@@ -252,7 +252,6 @@ pub struct ModuleConfig {
252252 emit_ir : bool ,
253253 emit_asm : bool ,
254254 emit_obj : bool ,
255-
256255 // Miscellaneous flags. These are mostly copied from command-line
257256 // options.
258257 no_verify : bool ,
@@ -262,7 +261,11 @@ pub struct ModuleConfig {
262261 vectorize_loop : bool ,
263262 vectorize_slp : bool ,
264263 merge_functions : bool ,
265- inline_threshold : Option < usize >
264+ inline_threshold : Option < usize > ,
265+ // Instead of creating an object file by doing LLVM codegen, just
266+ // make the object file bitcode. Provides easy compatibility with
267+ // emscripten's ecc compiler, when used as the linker.
268+ obj_is_bitcode : bool ,
266269}
267270
268271unsafe impl Send for ModuleConfig { }
@@ -280,6 +283,7 @@ impl ModuleConfig {
280283 emit_ir : false ,
281284 emit_asm : false ,
282285 emit_obj : false ,
286+ obj_is_bitcode : false ,
283287
284288 no_verify : false ,
285289 no_prepopulate_passes : false ,
@@ -298,6 +302,7 @@ impl ModuleConfig {
298302 self . no_builtins = trans. no_builtins ;
299303 self . time_passes = sess. time_passes ( ) ;
300304 self . inline_threshold = sess. opts . cg . inline_threshold ;
305+ self . obj_is_bitcode = sess. target . target . options . obj_is_bitcode ;
301306
302307 // Copy what clang does by turning on loop vectorization at O2 and
303308 // slp vectorization at O3. Otherwise configure other optimization aspects
@@ -524,11 +529,21 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
524529 f ( cpm) ;
525530 }
526531
527- if config. emit_bc {
528- let ext = format ! ( "{}.bc" , name_extra) ;
529- let out = output_names. with_extension ( & ext) ;
530- let out = path2cstr ( & out) ;
531- llvm:: LLVMWriteBitcodeToFile ( llmod, out. as_ptr ( ) ) ;
532+ // Change what we write and cleanup based on whether obj files are
533+ // just llvm bitcode. In that case write bitcode, and possibly
534+ // delete the bitcode if it wasn't requisted. Don't generate the
535+ // machine code, instead copy the .o file from the .bc
536+ let write_bc = config. emit_bc || config. obj_is_bitcode ;
537+ let rm_bc = !config. emit_bc && config. obj_is_bitcode ;
538+ let write_obj = config. emit_obj && !config. obj_is_bitcode ;
539+ let copy_bc_to_obj = config. emit_obj && config. obj_is_bitcode ;
540+
541+ let bc_out = output_names. with_extension ( & format ! ( "{}.bc" , name_extra) ) ;
542+ let obj_out = output_names. with_extension ( & format ! ( "{}.o" , name_extra) ) ;
543+
544+ if write_bc {
545+ let bc_out_c = path2cstr ( & bc_out) ;
546+ llvm:: LLVMWriteBitcodeToFile ( llmod, bc_out_c. as_ptr ( ) ) ;
532547 }
533548
534549 time ( config. time_passes , & format ! ( "codegen passes [{}]" , cgcx. worker) , || {
@@ -562,14 +577,27 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
562577 }
563578 }
564579
565- if config. emit_obj {
566- let path = output_names. with_extension ( & format ! ( "{}.o" , name_extra) ) ;
580+ if write_obj {
567581 with_codegen ( tm, llmod, config. no_builtins , |cpm| {
568- write_output_file ( cgcx. handler , tm, cpm, llmod, & path , llvm:: ObjectFileType ) ;
582+ write_output_file ( cgcx. handler , tm, cpm, llmod, & obj_out , llvm:: ObjectFileType ) ;
569583 } ) ;
570584 }
571585 } ) ;
572586
587+ if copy_bc_to_obj {
588+ debug ! ( "copying bitcode {:?} to obj {:?}" , bc_out, obj_out) ;
589+ if let Err ( e) = fs:: copy ( & bc_out, & obj_out) {
590+ cgcx. handler . err ( & format ! ( "failed to copy bitcode to object file: {}" , e) ) ;
591+ }
592+ }
593+
594+ if rm_bc {
595+ debug ! ( "removing_bitcode {:?}" , bc_out) ;
596+ if let Err ( e) = fs:: remove_file ( & bc_out) {
597+ cgcx. handler . err ( & format ! ( "failed to remove bitcode: {}" , e) ) ;
598+ }
599+ }
600+
573601 llvm:: LLVMDisposeModule ( llmod) ;
574602 llvm:: LLVMContextDispose ( llcx) ;
575603 llvm:: LLVMRustDisposeTargetMachine ( tm) ;
0 commit comments