@@ -94,7 +94,7 @@ impl Step for Std {
94
94
copy_third_party_objects ( builder, & compiler, target) ;
95
95
96
96
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) ;
98
98
99
99
builder. info ( & format ! ( "Building stage{} std artifacts ({} -> {})" , compiler. stage,
100
100
& compiler. host, target) ) ;
@@ -155,7 +155,6 @@ fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target:
155
155
/// Configure cargo to compile the standard library, adding appropriate env vars
156
156
/// and such.
157
157
pub fn std_cargo ( builder : & Builder < ' _ > ,
158
- compiler : & Compiler ,
159
158
target : Interned < String > ,
160
159
cargo : & mut Cargo ) {
161
160
if let Some ( target) = env:: var_os ( "MACOSX_STD_DEPLOYMENT_TARGET" ) {
@@ -200,22 +199,6 @@ pub fn std_cargo(builder: &Builder<'_>,
200
199
let mut features = builder. std_features ( ) ;
201
200
features. push_str ( & compiler_builtins_c_feature) ;
202
201
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
-
219
202
cargo. arg ( "--features" ) . arg ( features)
220
203
. arg ( "--manifest-path" )
221
204
. arg ( builder. src . join ( "src/libtest/Cargo.toml" ) ) ;
@@ -274,30 +257,95 @@ impl Step for StdLink {
274
257
let hostdir = builder. sysroot_libdir ( target_compiler, compiler. host ) ;
275
258
add_to_sysroot ( builder, & libdir, & hostdir, & libstd_stamp ( builder, compiler, target) ) ;
276
259
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) ;
282
264
}
283
265
}
284
266
}
285
267
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
+ _ => { }
300
347
}
348
+ result
301
349
}
302
350
303
351
#[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
0 commit comments