1
1
use std:: { collections:: BTreeMap , env, path:: PathBuf , sync:: atomic:: Ordering } ;
2
2
3
+ #[ allow( dead_code) ]
4
+ struct Target {
5
+ triple : String ,
6
+ os : String ,
7
+ arch : String ,
8
+ vendor : String ,
9
+ env : String ,
10
+ pointer_width : u8 ,
11
+ little_endian : bool ,
12
+ features : Vec < String > ,
13
+ }
14
+
15
+ impl Target {
16
+ fn from_env ( ) -> Self {
17
+ let little_endian = match env:: var ( "CARGO_CFG_TARGET_ENDIAN" ) . unwrap ( ) . as_str ( ) {
18
+ "little" => true ,
19
+ "big" => false ,
20
+ x => panic ! ( "unknown endian {x}" ) ,
21
+ } ;
22
+
23
+ Self {
24
+ triple : env:: var ( "TARGET" ) . unwrap ( ) ,
25
+ os : env:: var ( "CARGO_CFG_TARGET_OS" ) . unwrap ( ) ,
26
+ arch : env:: var ( "CARGO_CFG_TARGET_ARCH" ) . unwrap ( ) ,
27
+ vendor : env:: var ( "CARGO_CFG_TARGET_VENDOR" ) . unwrap ( ) ,
28
+ env : env:: var ( "CARGO_CFG_TARGET_ENV" ) . unwrap ( ) ,
29
+ pointer_width : env:: var ( "CARGO_CFG_TARGET_POINTER_WIDTH" )
30
+ . unwrap ( )
31
+ . parse ( )
32
+ . unwrap ( ) ,
33
+ little_endian,
34
+ features : env:: var ( "CARGO_CFG_TARGET_FEATURE" )
35
+ . unwrap_or_default ( )
36
+ . split ( "," )
37
+ . map ( ToOwned :: to_owned)
38
+ . collect ( ) ,
39
+ }
40
+ }
41
+ }
42
+
3
43
fn main ( ) {
4
44
println ! ( "cargo:rerun-if-changed=build.rs" ) ;
5
45
configure_check_cfg ( ) ;
6
46
7
- let target = env :: var ( "TARGET" ) . unwrap ( ) ;
47
+ let target = Target :: from_env ( ) ;
8
48
let cwd = env:: current_dir ( ) . unwrap ( ) ;
9
49
10
50
println ! ( "cargo:compiler-rt={}" , cwd. join( "compiler-rt" ) . display( ) ) ;
@@ -14,43 +54,43 @@ fn main() {
14
54
println ! ( "cargo:rustc-cfg=feature=\" unstable\" " ) ;
15
55
16
56
// Emscripten's runtime includes all the builtins
17
- if target. contains ( "emscripten" ) {
57
+ if target. env == "emscripten" {
18
58
return ;
19
59
}
20
60
21
61
// OpenBSD provides compiler_rt by default, use it instead of rebuilding it from source
22
- if target. contains ( "openbsd" ) {
62
+ if target. os == "openbsd" {
23
63
println ! ( "cargo:rustc-link-search=native=/usr/lib" ) ;
24
64
println ! ( "cargo:rustc-link-lib=compiler_rt" ) ;
25
65
return ;
26
66
}
27
67
28
68
// Forcibly enable memory intrinsics on wasm & SGX as we don't have a libc to
29
69
// provide them.
30
- if ( target. contains ( "wasm" ) && !target. contains ( "wasi" ) )
31
- || ( target. contains ( "sgx" ) && target. contains ( "fortanix" ) )
32
- || target. contains ( "-none" )
33
- || target. contains ( "nvptx" )
34
- || target. contains ( "uefi" )
35
- || target. contains ( "xous" )
70
+ if ( target. triple . contains ( "wasm" ) && !target. triple . contains ( "wasi" ) )
71
+ || ( target. triple . contains ( "sgx" ) && target. triple . contains ( "fortanix" ) )
72
+ || target. triple . contains ( "-none" )
73
+ || target. triple . contains ( "nvptx" )
74
+ || target. triple . contains ( "uefi" )
75
+ || target. triple . contains ( "xous" )
36
76
{
37
77
println ! ( "cargo:rustc-cfg=feature=\" mem\" " ) ;
38
78
}
39
79
40
80
// These targets have hardware unaligned access support.
41
81
println ! ( "cargo::rustc-check-cfg=cfg(feature, values(\" mem-unaligned\" ))" ) ;
42
- if target. contains ( "x86_64" )
43
- || target. contains ( "i686" )
44
- || target. contains ( "aarch64" )
45
- || target. contains ( "bpf" )
82
+ if target. arch . contains ( "x86_64" )
83
+ || target. arch . contains ( "i686" )
84
+ || target. arch . contains ( "aarch64" )
85
+ || target. arch . contains ( "bpf" )
46
86
{
47
87
println ! ( "cargo:rustc-cfg=feature=\" mem-unaligned\" " ) ;
48
88
}
49
89
50
90
// NOTE we are going to assume that llvm-target, what determines our codegen option, matches the
51
91
// target triple. This is usually correct for our built-in targets but can break in presence of
52
92
// custom targets, which can have arbitrary names.
53
- let llvm_target = target. split ( '-' ) . collect :: < Vec < _ > > ( ) ;
93
+ let llvm_target = target. triple . split ( '-' ) . collect :: < Vec < _ > > ( ) ;
54
94
55
95
// Build missing intrinsics from compiler-rt C source code. If we're
56
96
// mangling names though we assume that we're also in test mode so we don't
@@ -60,7 +100,7 @@ fn main() {
60
100
// Don't use a C compiler for these targets:
61
101
//
62
102
// * nvptx - everything is bitcode, not compatible with mixed C/Rust
63
- if !target. contains ( "nvptx" ) {
103
+ if !target. arch . contains ( "nvptx" ) {
64
104
#[ cfg( feature = "c" ) ]
65
105
c:: compile ( & llvm_target, & target) ;
66
106
}
@@ -86,7 +126,7 @@ fn main() {
86
126
println ! ( "cargo::rustc-check-cfg=cfg(kernel_user_helpers)" ) ;
87
127
if llvm_target[ 0 ] == "armv4t"
88
128
|| llvm_target[ 0 ] == "armv5te"
89
- || target == "arm-linux-androideabi"
129
+ || target. triple == "arm-linux-androideabi"
90
130
{
91
131
println ! ( "cargo:rustc-cfg=kernel_user_helpers" )
92
132
}
@@ -227,6 +267,8 @@ mod c {
227
267
use std:: io:: Write ;
228
268
use std:: path:: { Path , PathBuf } ;
229
269
270
+ use super :: Target ;
271
+
230
272
struct Sources {
231
273
// SYMBOL -> PATH TO SOURCE
232
274
map : BTreeMap < & ' static str , & ' static str > ,
@@ -267,11 +309,7 @@ mod c {
267
309
}
268
310
269
311
/// Compile intrinsics from the compiler-rt C source code
270
- pub fn compile ( llvm_target : & [ & str ] , target : & String ) {
271
- let target_arch = env:: var ( "CARGO_CFG_TARGET_ARCH" ) . unwrap ( ) ;
272
- let target_env = env:: var ( "CARGO_CFG_TARGET_ENV" ) . unwrap ( ) ;
273
- let target_os = env:: var ( "CARGO_CFG_TARGET_OS" ) . unwrap ( ) ;
274
- let target_vendor = env:: var ( "CARGO_CFG_TARGET_VENDOR" ) . unwrap ( ) ;
312
+ pub fn compile ( llvm_target : & [ & str ] , target : & Target ) {
275
313
let mut consider_float_intrinsics = true ;
276
314
let cfg = & mut cc:: Build :: new ( ) ;
277
315
@@ -280,8 +318,8 @@ mod c {
280
318
//
281
319
// Therefore, evaluate if those flags are present and set a boolean that causes any
282
320
// compiler-rt intrinsics that contain floating point source to be excluded for this target.
283
- if target_arch == "aarch64" {
284
- let cflags_key = String :: from ( "CFLAGS_" ) + & ( target. to_owned ( ) . replace ( "-" , "_" ) ) ;
321
+ if target . arch == "aarch64" {
322
+ let cflags_key = String :: from ( "CFLAGS_" ) + & ( target. triple . replace ( "-" , "_" ) ) ;
285
323
if let Ok ( cflags_value) = env:: var ( cflags_key) {
286
324
if cflags_value. contains ( "+nofp" ) || cflags_value. contains ( "+nosimd" ) {
287
325
consider_float_intrinsics = false ;
@@ -299,7 +337,7 @@ mod c {
299
337
300
338
cfg. warnings ( false ) ;
301
339
302
- if target_env == "msvc" {
340
+ if target . env == "msvc" {
303
341
// Don't pull in extra libraries on MSVC
304
342
cfg. flag ( "/Zl" ) ;
305
343
@@ -328,7 +366,7 @@ mod c {
328
366
// at odds with compiling with `-ffreestanding`, as the header
329
367
// may be incompatible or not present. Create a minimal stub
330
368
// header to use instead.
331
- if target_os == "uefi" {
369
+ if target . os == "uefi" {
332
370
let out_dir = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
333
371
let include_dir = out_dir. join ( "include" ) ;
334
372
if !include_dir. exists ( ) {
@@ -373,7 +411,7 @@ mod c {
373
411
374
412
// On iOS and 32-bit OSX these are all just empty intrinsics, no need to
375
413
// include them.
376
- if target_vendor != "apple" || target_arch != "x86" {
414
+ if target . vendor != "apple" || target . arch != "x86" {
377
415
sources. extend ( & [
378
416
( "__absvti2" , "absvti2.c" ) ,
379
417
( "__addvti3" , "addvti3.c" ) ,
@@ -392,7 +430,7 @@ mod c {
392
430
}
393
431
}
394
432
395
- if target_vendor == "apple" {
433
+ if target . vendor == "apple" {
396
434
sources. extend ( & [
397
435
( "atomic_flag_clear" , "atomic_flag_clear.c" ) ,
398
436
( "atomic_flag_clear_explicit" , "atomic_flag_clear_explicit.c" ) ,
@@ -406,8 +444,8 @@ mod c {
406
444
] ) ;
407
445
}
408
446
409
- if target_env != "msvc" {
410
- if target_arch == "x86" {
447
+ if target . env != "msvc" {
448
+ if target . arch == "x86" {
411
449
sources. extend ( & [
412
450
( "__ashldi3" , "i386/ashldi3.S" ) ,
413
451
( "__ashrdi3" , "i386/ashrdi3.S" ) ,
@@ -421,7 +459,7 @@ mod c {
421
459
}
422
460
}
423
461
424
- if target_arch == "arm" && target_vendor != "apple" && target_env != "msvc" {
462
+ if target . arch == "arm" && target . vendor != "apple" && target . env != "msvc" {
425
463
sources. extend ( & [
426
464
( "__aeabi_div0" , "arm/aeabi_div0.c" ) ,
427
465
( "__aeabi_drsub" , "arm/aeabi_drsub.c" ) ,
@@ -441,7 +479,7 @@ mod c {
441
479
( "__umodsi3" , "arm/umodsi3.S" ) ,
442
480
] ) ;
443
481
444
- if target_os == "freebsd" {
482
+ if target . os == "freebsd" {
445
483
sources. extend ( & [ ( "__clear_cache" , "clear_cache.c" ) ] ) ;
446
484
}
447
485
@@ -513,7 +551,7 @@ mod c {
513
551
] ) ;
514
552
}
515
553
516
- if ( target_arch == "aarch64" || target_arch == "arm64ec" ) && consider_float_intrinsics {
554
+ if ( target . arch == "aarch64" || target . arch == "arm64ec" ) && consider_float_intrinsics {
517
555
sources. extend ( & [
518
556
( "__comparetf2" , "comparetf2.c" ) ,
519
557
( "__floatditf" , "floatditf.c" ) ,
@@ -526,16 +564,16 @@ mod c {
526
564
( "__fe_raise_inexact" , "fp_mode.c" ) ,
527
565
] ) ;
528
566
529
- if target_os != "windows" {
567
+ if target . os != "windows" {
530
568
sources. extend ( & [ ( "__multc3" , "multc3.c" ) ] ) ;
531
569
}
532
570
}
533
571
534
- if target_arch == "mips" || target_arch == "riscv32" || target_arch == "riscv64" {
572
+ if target . arch == "mips" || target . arch == "riscv32" || target . arch == "riscv64" {
535
573
sources. extend ( & [ ( "__bswapsi2" , "bswapsi2.c" ) ] ) ;
536
574
}
537
575
538
- if target_arch == "mips64" {
576
+ if target . arch == "mips64" {
539
577
sources. extend ( & [
540
578
( "__netf2" , "comparetf2.c" ) ,
541
579
( "__floatsitf" , "floatsitf.c" ) ,
@@ -544,7 +582,7 @@ mod c {
544
582
] ) ;
545
583
}
546
584
547
- if target_arch == "loongarch64" {
585
+ if target . arch == "loongarch64" {
548
586
sources. extend ( & [
549
587
( "__netf2" , "comparetf2.c" ) ,
550
588
( "__floatsitf" , "floatsitf.c" ) ,
@@ -554,7 +592,7 @@ mod c {
554
592
}
555
593
556
594
// Remove the assembly implementations that won't compile for the target
557
- if llvm_target[ 0 ] == "thumbv6m" || llvm_target[ 0 ] == "thumbv8m.base" || target_os == "uefi"
595
+ if llvm_target[ 0 ] == "thumbv6m" || llvm_target[ 0 ] == "thumbv8m.base" || target . os == "uefi"
558
596
{
559
597
let mut to_remove = Vec :: new ( ) ;
560
598
for ( k, v) in sources. map . iter ( ) {
@@ -570,7 +608,7 @@ mod c {
570
608
}
571
609
572
610
// Android uses emulated TLS so we need a runtime support function.
573
- if target_os == "android" {
611
+ if target . os == "android" {
574
612
sources. extend ( & [ ( "__emutls_get_address" , "emutls.c" ) ] ) ;
575
613
576
614
// Work around a bug in the NDK headers (fixed in
@@ -580,7 +618,7 @@ mod c {
580
618
}
581
619
582
620
// OpenHarmony also uses emulated TLS.
583
- if target_env == "ohos" {
621
+ if target . env == "ohos" {
584
622
sources. extend ( & [ ( "__emutls_get_address" , "emutls.c" ) ] ) ;
585
623
}
586
624
@@ -607,7 +645,7 @@ mod c {
607
645
// sets of flags to the same source file.
608
646
// Note: Out-of-line aarch64 atomics are not supported by the msvc toolchain (#430).
609
647
let src_dir = root. join ( "lib/builtins" ) ;
610
- if target_arch == "aarch64" && target_env != "msvc" {
648
+ if target . arch == "aarch64" && target . env != "msvc" {
611
649
// See below for why we're building these as separate libraries.
612
650
build_aarch64_out_of_line_atomics_libraries ( & src_dir, cfg) ;
613
651
0 commit comments