11//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
22//! standalone executable.
33
4- use std:: io:: { self , Write } ;
4+ use std:: io:: Write ;
55use std:: path:: PathBuf ;
66use std:: process:: { Command , Stdio } ;
7+ use std:: sync:: Arc ;
78
89use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
910use rustc_hir:: ItemId ;
10- use rustc_session:: config:: OutputType ;
11+ use rustc_session:: config:: { OutputFilenames , OutputType } ;
1112
1213use crate :: prelude:: * ;
1314
@@ -31,52 +32,68 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
3132 }
3233}
3334
35+ #[ derive( Debug ) ]
36+ pub ( crate ) struct GlobalAsmConfig {
37+ asm_enabled : bool ,
38+ assembler : PathBuf ,
39+ linker : PathBuf ,
40+ output_filenames : Arc < OutputFilenames > ,
41+ }
42+
43+ impl GlobalAsmConfig {
44+ pub ( crate ) fn new ( tcx : TyCtxt < ' _ > ) -> Self {
45+ let asm_enabled = cfg ! ( feature = "inline_asm" )
46+ && !tcx. sess . target . is_like_osx
47+ && !tcx. sess . target . is_like_windows ;
48+
49+ GlobalAsmConfig {
50+ asm_enabled,
51+ assembler : crate :: toolchain:: get_toolchain_binary ( tcx. sess , "as" ) ,
52+ linker : crate :: toolchain:: get_toolchain_binary ( tcx. sess , "ld" ) ,
53+ output_filenames : tcx. output_filenames ( ( ) ) . clone ( ) ,
54+ }
55+ }
56+ }
57+
3458pub ( crate ) fn compile_global_asm (
35- tcx : TyCtxt < ' _ > ,
59+ config : & GlobalAsmConfig ,
3660 cgu_name : & str ,
3761 global_asm : & str ,
38- ) -> io :: Result < ( ) > {
62+ ) -> Result < ( ) , String > {
3963 if global_asm. is_empty ( ) {
4064 return Ok ( ( ) ) ;
4165 }
4266
43- if cfg ! ( not( feature = "inline_asm" ) )
44- || tcx. sess . target . is_like_osx
45- || tcx. sess . target . is_like_windows
46- {
67+ if !config. asm_enabled {
4768 if global_asm. contains ( "__rust_probestack" ) {
4869 return Ok ( ( ) ) ;
4970 }
5071
5172 // FIXME fix linker error on macOS
5273 if cfg ! ( not( feature = "inline_asm" ) ) {
53- return Err ( io :: Error :: new (
54- io :: ErrorKind :: Unsupported ,
55- "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift" ,
56- ) ) ;
74+ return Err (
75+ "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift"
76+ . to_owned ( ) ,
77+ ) ;
5778 } else {
58- return Err ( io:: Error :: new (
59- io:: ErrorKind :: Unsupported ,
60- "asm! and global_asm! are not yet supported on macOS and Windows" ,
61- ) ) ;
79+ return Err (
80+ "asm! and global_asm! are not yet supported on macOS and Windows" . to_owned ( )
81+ ) ;
6282 }
6383 }
6484
65- let assembler = crate :: toolchain:: get_toolchain_binary ( tcx. sess , "as" ) ;
66- let linker = crate :: toolchain:: get_toolchain_binary ( tcx. sess , "ld" ) ;
67-
6885 // Remove all LLVM style comments
6986 let global_asm = global_asm
7087 . lines ( )
7188 . map ( |line| if let Some ( index) = line. find ( "//" ) { & line[ 0 ..index] } else { line } )
7289 . collect :: < Vec < _ > > ( )
7390 . join ( "\n " ) ;
7491
75- let output_object_file = tcx . output_filenames ( ( ) ) . temp_path ( OutputType :: Object , Some ( cgu_name) ) ;
92+ let output_object_file = config . output_filenames . temp_path ( OutputType :: Object , Some ( cgu_name) ) ;
7693
7794 // Assemble `global_asm`
7895 let global_asm_object_file = add_file_stem_postfix ( output_object_file. clone ( ) , ".asm" ) ;
79- let mut child = Command :: new ( assembler)
96+ let mut child = Command :: new ( & config . assembler )
8097 . arg ( "-o" )
8198 . arg ( & global_asm_object_file)
8299 . stdin ( Stdio :: piped ( ) )
@@ -85,16 +102,13 @@ pub(crate) fn compile_global_asm(
85102 child. stdin . take ( ) . unwrap ( ) . write_all ( global_asm. as_bytes ( ) ) . unwrap ( ) ;
86103 let status = child. wait ( ) . expect ( "Failed to wait for `as`." ) ;
87104 if !status. success ( ) {
88- return Err ( io:: Error :: new (
89- io:: ErrorKind :: Other ,
90- format ! ( "Failed to assemble `{}`" , global_asm) ,
91- ) ) ;
105+ return Err ( format ! ( "Failed to assemble `{}`" , global_asm) ) ;
92106 }
93107
94108 // Link the global asm and main object file together
95109 let main_object_file = add_file_stem_postfix ( output_object_file. clone ( ) , ".main" ) ;
96110 std:: fs:: rename ( & output_object_file, & main_object_file) . unwrap ( ) ;
97- let status = Command :: new ( linker)
111+ let status = Command :: new ( & config . linker )
98112 . arg ( "-r" ) // Create a new object file
99113 . arg ( "-o" )
100114 . arg ( output_object_file)
@@ -103,13 +117,10 @@ pub(crate) fn compile_global_asm(
103117 . status ( )
104118 . unwrap ( ) ;
105119 if !status. success ( ) {
106- return Err ( io:: Error :: new (
107- io:: ErrorKind :: Other ,
108- format ! (
109- "Failed to link `{}` and `{}` together" ,
110- main_object_file. display( ) ,
111- global_asm_object_file. display( ) ,
112- ) ,
120+ return Err ( format ! (
121+ "Failed to link `{}` and `{}` together" ,
122+ main_object_file. display( ) ,
123+ global_asm_object_file. display( ) ,
113124 ) ) ;
114125 }
115126
0 commit comments