@@ -252,7 +252,6 @@ pub struct ModuleConfig {
252
252
emit_ir : bool ,
253
253
emit_asm : bool ,
254
254
emit_obj : bool ,
255
-
256
255
// Miscellaneous flags. These are mostly copied from command-line
257
256
// options.
258
257
no_verify : bool ,
@@ -262,7 +261,11 @@ pub struct ModuleConfig {
262
261
vectorize_loop : bool ,
263
262
vectorize_slp : bool ,
264
263
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 ,
266
269
}
267
270
268
271
unsafe impl Send for ModuleConfig { }
@@ -280,6 +283,7 @@ impl ModuleConfig {
280
283
emit_ir : false ,
281
284
emit_asm : false ,
282
285
emit_obj : false ,
286
+ obj_is_bitcode : false ,
283
287
284
288
no_verify : false ,
285
289
no_prepopulate_passes : false ,
@@ -298,6 +302,7 @@ impl ModuleConfig {
298
302
self . no_builtins = trans. no_builtins ;
299
303
self . time_passes = sess. time_passes ( ) ;
300
304
self . inline_threshold = sess. opts . cg . inline_threshold ;
305
+ self . obj_is_bitcode = sess. target . target . options . obj_is_bitcode ;
301
306
302
307
// Copy what clang does by turning on loop vectorization at O2 and
303
308
// slp vectorization at O3. Otherwise configure other optimization aspects
@@ -524,11 +529,21 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
524
529
f ( cpm) ;
525
530
}
526
531
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 ( ) ) ;
532
547
}
533
548
534
549
time ( config. time_passes , & format ! ( "codegen passes [{}]" , cgcx. worker) , || {
@@ -562,14 +577,27 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
562
577
}
563
578
}
564
579
565
- if config. emit_obj {
566
- let path = output_names. with_extension ( & format ! ( "{}.o" , name_extra) ) ;
580
+ if write_obj {
567
581
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 ) ;
569
583
} ) ;
570
584
}
571
585
} ) ;
572
586
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
+
573
601
llvm:: LLVMDisposeModule ( llmod) ;
574
602
llvm:: LLVMContextDispose ( llcx) ;
575
603
llvm:: LLVMRustDisposeTargetMachine ( tm) ;
0 commit comments