@@ -244,7 +244,6 @@ pub struct ModuleConfig {
244
244
emit_ir : bool ,
245
245
emit_asm : bool ,
246
246
emit_obj : bool ,
247
-
248
247
// Miscellaneous flags. These are mostly copied from command-line
249
248
// options.
250
249
no_verify : bool ,
@@ -254,7 +253,11 @@ pub struct ModuleConfig {
254
253
vectorize_loop : bool ,
255
254
vectorize_slp : bool ,
256
255
merge_functions : bool ,
257
- inline_threshold : Option < usize >
256
+ inline_threshold : Option < usize > ,
257
+ // Instead of creating an object file by doing LLVM codegen, just
258
+ // make the object file bitcode. Provides easy compatibility with
259
+ // emscripten's ecc compiler, when used as the linker.
260
+ obj_is_bitcode : bool ,
258
261
}
259
262
260
263
unsafe impl Send for ModuleConfig { }
@@ -272,6 +275,7 @@ impl ModuleConfig {
272
275
emit_ir : false ,
273
276
emit_asm : false ,
274
277
emit_obj : false ,
278
+ obj_is_bitcode : false ,
275
279
276
280
no_verify : false ,
277
281
no_prepopulate_passes : false ,
@@ -290,6 +294,7 @@ impl ModuleConfig {
290
294
self . no_builtins = trans. no_builtins ;
291
295
self . time_passes = sess. time_passes ( ) ;
292
296
self . inline_threshold = sess. opts . cg . inline_threshold ;
297
+ self . obj_is_bitcode = sess. target . target . options . obj_is_bitcode ;
293
298
294
299
// Copy what clang does by turning on loop vectorization at O2 and
295
300
// slp vectorization at O3. Otherwise configure other optimization aspects
@@ -530,11 +535,21 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
530
535
f ( cpm) ;
531
536
}
532
537
533
- if config. emit_bc {
534
- let ext = format ! ( "{}.bc" , name_extra) ;
535
- let out = output_names. with_extension ( & ext) ;
536
- let out = path2cstr ( & out) ;
537
- llvm:: LLVMWriteBitcodeToFile ( llmod, out. as_ptr ( ) ) ;
538
+ // Change what we write and cleanup based on whether obj files are
539
+ // just llvm bitcode. In that case write bitcode, and possibly
540
+ // delete the bitcode if it wasn't requested. Don't generate the
541
+ // machine code, instead copy the .o file from the .bc
542
+ let write_bc = config. emit_bc || config. obj_is_bitcode ;
543
+ let rm_bc = !config. emit_bc && config. obj_is_bitcode ;
544
+ let write_obj = config. emit_obj && !config. obj_is_bitcode ;
545
+ let copy_bc_to_obj = config. emit_obj && config. obj_is_bitcode ;
546
+
547
+ let bc_out = output_names. with_extension ( & format ! ( "{}.bc" , name_extra) ) ;
548
+ let obj_out = output_names. with_extension ( & format ! ( "{}.o" , name_extra) ) ;
549
+
550
+ if write_bc {
551
+ let bc_out_c = path2cstr ( & bc_out) ;
552
+ llvm:: LLVMWriteBitcodeToFile ( llmod, bc_out_c. as_ptr ( ) ) ;
538
553
}
539
554
540
555
time ( config. time_passes , & format ! ( "codegen passes [{}]" , cgcx. worker) , || {
@@ -568,14 +583,27 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
568
583
}
569
584
}
570
585
571
- if config. emit_obj {
572
- let path = output_names. with_extension ( & format ! ( "{}.o" , name_extra) ) ;
586
+ if write_obj {
573
587
with_codegen ( tm, llmod, config. no_builtins , |cpm| {
574
- write_output_file ( cgcx. handler , tm, cpm, llmod, & path , llvm:: ObjectFileType ) ;
588
+ write_output_file ( cgcx. handler , tm, cpm, llmod, & obj_out , llvm:: ObjectFileType ) ;
575
589
} ) ;
576
590
}
577
591
} ) ;
578
592
593
+ if copy_bc_to_obj {
594
+ debug ! ( "copying bitcode {:?} to obj {:?}" , bc_out, obj_out) ;
595
+ if let Err ( e) = fs:: copy ( & bc_out, & obj_out) {
596
+ cgcx. handler . err ( & format ! ( "failed to copy bitcode to object file: {}" , e) ) ;
597
+ }
598
+ }
599
+
600
+ if rm_bc {
601
+ debug ! ( "removing_bitcode {:?}" , bc_out) ;
602
+ if let Err ( e) = fs:: remove_file ( & bc_out) {
603
+ cgcx. handler . err ( & format ! ( "failed to remove bitcode: {}" , e) ) ;
604
+ }
605
+ }
606
+
579
607
llvm:: LLVMDisposeModule ( llmod) ;
580
608
llvm:: LLVMContextDispose ( llcx) ;
581
609
llvm:: LLVMRustDisposeTargetMachine ( tm) ;
0 commit comments