@@ -94,7 +94,7 @@ impl Step for Std {
9494 copy_third_party_objects ( builder, & compiler, target) ;
9595
9696 let mut cargo = builder. cargo ( compiler, Mode :: Std , target, "build" ) ;
97- std_cargo ( builder, & compiler , target, & mut cargo) ;
97+ std_cargo ( builder, target, & mut cargo) ;
9898
9999 builder. info ( & format ! ( "Building stage{} std artifacts ({} -> {})" , compiler. stage,
100100 & compiler. host, target) ) ;
@@ -155,7 +155,6 @@ fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target:
155155/// Configure cargo to compile the standard library, adding appropriate env vars
156156/// and such.
157157pub fn std_cargo ( builder : & Builder < ' _ > ,
158- compiler : & Compiler ,
159158 target : Interned < String > ,
160159 cargo : & mut Cargo ) {
161160 if let Some ( target) = env:: var_os ( "MACOSX_STD_DEPLOYMENT_TARGET" ) {
@@ -200,22 +199,6 @@ pub fn std_cargo(builder: &Builder<'_>,
200199 let mut features = builder. std_features ( ) ;
201200 features. push_str ( & compiler_builtins_c_feature) ;
202201
203- if compiler. stage != 0 && builder. config . sanitizers {
204- // This variable is used by the sanitizer runtime crates, e.g.
205- // rustc_lsan, to build the sanitizer runtime from C code
206- // When this variable is missing, those crates won't compile the C code,
207- // so we don't set this variable during stage0 where llvm-config is
208- // missing
209- // We also only build the runtimes when --enable-sanitizers (or its
210- // config.toml equivalent) is used
211- let llvm_config = builder. ensure ( native:: Llvm {
212- target : builder. config . build ,
213- emscripten : false ,
214- } ) ;
215- cargo. env ( "LLVM_CONFIG" , llvm_config) ;
216- cargo. env ( "RUSTC_BUILD_SANITIZERS" , "1" ) ;
217- }
218-
219202 cargo. arg ( "--features" ) . arg ( features)
220203 . arg ( "--manifest-path" )
221204 . arg ( builder. src . join ( "src/libtest/Cargo.toml" ) ) ;
@@ -274,30 +257,95 @@ impl Step for StdLink {
274257 let hostdir = builder. sysroot_libdir ( target_compiler, compiler. host ) ;
275258 add_to_sysroot ( builder, & libdir, & hostdir, & libstd_stamp ( builder, compiler, target) ) ;
276259
277- if builder. config . sanitizers && compiler. stage != 0 && target == "x86_64-apple-darwin" {
278- // The sanitizers are only built in stage1 or above, so the dylibs will
279- // be missing in stage0 and causes panic. See the `std()` function above
280- // for reason why the sanitizers are not built in stage0.
281- copy_apple_sanitizer_dylibs ( builder, & builder. native_dir ( target) , "osx" , & libdir) ;
260+ if builder. config . sanitizers && target_compiler. stage != 0 {
261+ // The sanitizers are only copied in stage1 or above,
262+ // to avoid creating dependency on LLVM.
263+ copy_sanitizers ( builder, & target_compiler, target) ;
282264 }
283265 }
284266}
285267
286- fn copy_apple_sanitizer_dylibs (
287- builder : & Builder < ' _ > ,
288- native_dir : & Path ,
289- platform : & str ,
290- into : & Path ,
291- ) {
292- for & sanitizer in & [ "asan" , "tsan" ] {
293- let filename = format ! ( "lib__rustc__clang_rt.{}_{}_dynamic.dylib" , sanitizer, platform) ;
294- let mut src_path = native_dir. join ( sanitizer) ;
295- src_path. push ( "build" ) ;
296- src_path. push ( "lib" ) ;
297- src_path. push ( "darwin" ) ;
298- src_path. push ( & filename) ;
299- builder. copy ( & src_path, & into. join ( filename) ) ;
268+ /// Copies sanitizer runtime libraries into target libdir.
269+ fn copy_sanitizers ( builder : & Builder < ' _ > , compiler : & Compiler , target : Interned < String > ) {
270+ let llvm_config = builder. ensure ( native:: Llvm {
271+ target,
272+ emscripten : false ,
273+ } ) ;
274+
275+ let llvm_version = output ( Command :: new ( & llvm_config) . arg ( "--version" ) ) ;
276+ let llvm_version = llvm_version. trim ( ) ;
277+
278+ // The compiler-rt uses CLANG_VERSION as a part of COMPILER_RT_INSTALL_PATH.
279+ // The CLANG_VERSION is based on LLVM_VERSION but it does not not include
280+ // LLVM_VERSION_SUFFIX. On the other hand value returned from llvm-config
281+ // --version does include it, so lets strip it to obtain CLANG_VERSION.
282+ let mut non_digits = 0 ;
283+ let mut third_non_digit = llvm_version. len ( ) ;
284+ for ( i, c) in llvm_version. char_indices ( ) {
285+ if !c. is_digit ( 10 ) {
286+ non_digits += 1 ;
287+ if non_digits == 3 {
288+ third_non_digit = i;
289+ break ;
290+ }
291+ }
292+ }
293+ let llvm_version = & llvm_version[ ..third_non_digit] ;
294+
295+ let llvm_libdir = output ( Command :: new ( & llvm_config) . arg ( "--libdir" ) ) ;
296+ let llvm_libdir = PathBuf :: from ( llvm_libdir. trim ( ) ) ;
297+
298+ let clang_resourcedir = llvm_libdir. join ( "clang" ) . join ( & llvm_version) ;
299+ let sanitizers = supported_sanitizers ( & clang_resourcedir, target) ;
300+ let libdir = builder. sysroot_libdir ( * compiler, target) ;
301+
302+ for ( src, name) in & sanitizers {
303+ let dst = libdir. join ( name) ;
304+ if !src. exists ( ) {
305+ println ! ( "Ignoring missing runtime: {}" , src. display( ) ) ;
306+ continue ;
307+ }
308+ builder. copy ( & src, & dst) ;
309+
310+ if target == "x86_64-apple-darwin" {
311+ // Update the library install name reflect the fact it has been renamed.
312+ let status = Command :: new ( "install_name_tool" )
313+ . arg ( "-id" )
314+ . arg ( format ! ( "@rpath/{}" , name) )
315+ . arg ( & dst)
316+ . status ( )
317+ . expect ( "failed to execute `install_name_tool`" ) ;
318+ assert ! ( status. success( ) ) ;
319+ }
320+ }
321+ }
322+
323+ /// Returns a list of paths to sanitizer libraries supported on given target,
324+ /// and corresponding names we plan to give them when placed in target libdir.
325+ fn supported_sanitizers ( resourcedir : & Path , target : Interned < String > ) -> Vec < ( PathBuf , String ) > {
326+ let sanitizers = & [ "asan" , "lsan" , "msan" , "tsan" ] ;
327+ let mut result = Vec :: new ( ) ;
328+ match & * target {
329+ "x86_64-apple-darwin" => {
330+ let srcdir = resourcedir. join ( "lib/darwin" ) ;
331+ for s in sanitizers {
332+ let src = format ! ( "libclang_rt.{}_osx_dynamic.dylib" , s) ;
333+ let dst = format ! ( "librustc_rt.{}.dylib" , s) ;
334+ result. push ( ( srcdir. join ( src) , dst) ) ;
335+ }
336+
337+ }
338+ "x86_64-unknown-linux-gnu" => {
339+ let srcdir = resourcedir. join ( "lib/linux" ) ;
340+ for s in sanitizers {
341+ let src = format ! ( "libclang_rt.{}-x86_64.a" , s) ;
342+ let dst = format ! ( "librustc_rt.{}.a" , s) ;
343+ result. push ( ( srcdir. join ( src) , dst) ) ;
344+ }
345+ }
346+ _ => { }
300347 }
348+ result
301349}
302350
303351#[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
0 commit comments