11use std:: { collections:: BTreeMap , env, path:: PathBuf , sync:: atomic:: Ordering } ;
22
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_LITTLE_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_FEATURES" )
35+ . unwrap ( )
36+ . split ( "," )
37+ . map ( ToOwned :: to_owned)
38+ . collect ( ) ,
39+ }
40+ }
41+ }
42+
343fn main ( ) {
444 println ! ( "cargo:rerun-if-changed=build.rs" ) ;
545 configure_check_cfg ( ) ;
646
7- let target = env :: var ( "TARGET" ) . unwrap ( ) ;
47+ let target = Target :: from_env ( ) ;
848 let cwd = env:: current_dir ( ) . unwrap ( ) ;
949
1050 println ! ( "cargo:compiler-rt={}" , cwd. join( "compiler-rt" ) . display( ) ) ;
@@ -14,43 +54,43 @@ fn main() {
1454 println ! ( "cargo:rustc-cfg=feature=\" unstable\" " ) ;
1555
1656 // Emscripten's runtime includes all the builtins
17- if target. contains ( "emscripten" ) {
57+ if target. env == "emscripten" {
1858 return ;
1959 }
2060
2161 // OpenBSD provides compiler_rt by default, use it instead of rebuilding it from source
22- if target. contains ( "openbsd" ) {
62+ if target. os == "openbsd" {
2363 println ! ( "cargo:rustc-link-search=native=/usr/lib" ) ;
2464 println ! ( "cargo:rustc-link-lib=compiler_rt" ) ;
2565 return ;
2666 }
2767
2868 // Forcibly enable memory intrinsics on wasm & SGX as we don't have a libc to
2969 // 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" )
3676 {
3777 println ! ( "cargo:rustc-cfg=feature=\" mem\" " ) ;
3878 }
3979
4080 // These targets have hardware unaligned access support.
4181 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" )
4686 {
4787 println ! ( "cargo:rustc-cfg=feature=\" mem-unaligned\" " ) ;
4888 }
4989
5090 // NOTE we are going to assume that llvm-target, what determines our codegen option, matches the
5191 // target triple. This is usually correct for our built-in targets but can break in presence of
5292 // custom targets, which can have arbitrary names.
53- let llvm_target = target. split ( '-' ) . collect :: < Vec < _ > > ( ) ;
93+ let llvm_target = target. triple . split ( '-' ) . collect :: < Vec < _ > > ( ) ;
5494
5595 // Build missing intrinsics from compiler-rt C source code. If we're
5696 // mangling names though we assume that we're also in test mode so we don't
@@ -60,7 +100,7 @@ fn main() {
60100 // Don't use a C compiler for these targets:
61101 //
62102 // * nvptx - everything is bitcode, not compatible with mixed C/Rust
63- if !target. contains ( "nvptx" ) {
103+ if !target. arch . contains ( "nvptx" ) {
64104 #[ cfg( feature = "c" ) ]
65105 c:: compile ( & llvm_target, & target) ;
66106 }
@@ -86,7 +126,7 @@ fn main() {
86126 println ! ( "cargo::rustc-check-cfg=cfg(kernel_user_helpers)" ) ;
87127 if llvm_target[ 0 ] == "armv4t"
88128 || llvm_target[ 0 ] == "armv5te"
89- || target == "arm-linux-androideabi"
129+ || target. triple == "arm-linux-androideabi"
90130 {
91131 println ! ( "cargo:rustc-cfg=kernel_user_helpers" )
92132 }
@@ -227,6 +267,8 @@ mod c {
227267 use std:: io:: Write ;
228268 use std:: path:: { Path , PathBuf } ;
229269
270+ use super :: Target ;
271+
230272 struct Sources {
231273 // SYMBOL -> PATH TO SOURCE
232274 map : BTreeMap < & ' static str , & ' static str > ,
@@ -267,11 +309,7 @@ mod c {
267309 }
268310
269311 /// 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 ) {
275313 let mut consider_float_intrinsics = true ;
276314 let cfg = & mut cc:: Build :: new ( ) ;
277315
@@ -280,7 +318,7 @@ mod c {
280318 //
281319 // Therefore, evaluate if those flags are present and set a boolean that causes any
282320 // compiler-rt intrinsics that contain floating point source to be excluded for this target.
283- if target_arch == "aarch64" {
321+ if target . arch == "aarch64" {
284322 let cflags_key = String :: from ( "CFLAGS_" ) + & ( target. to_owned ( ) . replace ( "-" , "_" ) ) ;
285323 if let Ok ( cflags_value) = env:: var ( cflags_key) {
286324 if cflags_value. contains ( "+nofp" ) || cflags_value. contains ( "+nosimd" ) {
@@ -299,7 +337,7 @@ mod c {
299337
300338 cfg. warnings ( false ) ;
301339
302- if target_env == "msvc" {
340+ if target . env == "msvc" {
303341 // Don't pull in extra libraries on MSVC
304342 cfg. flag ( "/Zl" ) ;
305343
@@ -328,7 +366,7 @@ mod c {
328366 // at odds with compiling with `-ffreestanding`, as the header
329367 // may be incompatible or not present. Create a minimal stub
330368 // header to use instead.
331- if target_os == "uefi" {
369+ if target . os == "uefi" {
332370 let out_dir = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
333371 let include_dir = out_dir. join ( "include" ) ;
334372 if !include_dir. exists ( ) {
@@ -373,7 +411,7 @@ mod c {
373411
374412 // On iOS and 32-bit OSX these are all just empty intrinsics, no need to
375413 // include them.
376- if target_vendor != "apple" || target_arch != "x86" {
414+ if target . vendor != "apple" || target . arch != "x86" {
377415 sources. extend ( & [
378416 ( "__absvti2" , "absvti2.c" ) ,
379417 ( "__addvti3" , "addvti3.c" ) ,
@@ -392,7 +430,7 @@ mod c {
392430 }
393431 }
394432
395- if target_vendor == "apple" {
433+ if target . vendor == "apple" {
396434 sources. extend ( & [
397435 ( "atomic_flag_clear" , "atomic_flag_clear.c" ) ,
398436 ( "atomic_flag_clear_explicit" , "atomic_flag_clear_explicit.c" ) ,
@@ -406,8 +444,8 @@ mod c {
406444 ] ) ;
407445 }
408446
409- if target_env != "msvc" {
410- if target_arch == "x86" {
447+ if target . env != "msvc" {
448+ if target . arch == "x86" {
411449 sources. extend ( & [
412450 ( "__ashldi3" , "i386/ashldi3.S" ) ,
413451 ( "__ashrdi3" , "i386/ashrdi3.S" ) ,
@@ -421,7 +459,7 @@ mod c {
421459 }
422460 }
423461
424- if target_arch == "arm" && target_vendor != "apple" && target_env != "msvc" {
462+ if target . arch == "arm" && target . vendor != "apple" && target . env != "msvc" {
425463 sources. extend ( & [
426464 ( "__aeabi_div0" , "arm/aeabi_div0.c" ) ,
427465 ( "__aeabi_drsub" , "arm/aeabi_drsub.c" ) ,
@@ -441,7 +479,7 @@ mod c {
441479 ( "__umodsi3" , "arm/umodsi3.S" ) ,
442480 ] ) ;
443481
444- if target_os == "freebsd" {
482+ if target . os == "freebsd" {
445483 sources. extend ( & [ ( "__clear_cache" , "clear_cache.c" ) ] ) ;
446484 }
447485
@@ -513,7 +551,7 @@ mod c {
513551 ] ) ;
514552 }
515553
516- if ( target_arch == "aarch64" || target_arch == "arm64ec" ) && consider_float_intrinsics {
554+ if ( target . arch == "aarch64" || target . arch == "arm64ec" ) && consider_float_intrinsics {
517555 sources. extend ( & [
518556 ( "__comparetf2" , "comparetf2.c" ) ,
519557 ( "__floatditf" , "floatditf.c" ) ,
@@ -526,16 +564,16 @@ mod c {
526564 ( "__fe_raise_inexact" , "fp_mode.c" ) ,
527565 ] ) ;
528566
529- if target_os != "windows" {
567+ if target . os != "windows" {
530568 sources. extend ( & [ ( "__multc3" , "multc3.c" ) ] ) ;
531569 }
532570 }
533571
534- if target_arch == "mips" || target_arch == "riscv32" || target_arch == "riscv64" {
572+ if target . arch == "mips" || target . arch == "riscv32" || target . arch == "riscv64" {
535573 sources. extend ( & [ ( "__bswapsi2" , "bswapsi2.c" ) ] ) ;
536574 }
537575
538- if target_arch == "mips64" {
576+ if target . arch == "mips64" {
539577 sources. extend ( & [
540578 ( "__netf2" , "comparetf2.c" ) ,
541579 ( "__floatsitf" , "floatsitf.c" ) ,
@@ -544,7 +582,7 @@ mod c {
544582 ] ) ;
545583 }
546584
547- if target_arch == "loongarch64" {
585+ if target . arch == "loongarch64" {
548586 sources. extend ( & [
549587 ( "__netf2" , "comparetf2.c" ) ,
550588 ( "__floatsitf" , "floatsitf.c" ) ,
@@ -554,7 +592,7 @@ mod c {
554592 }
555593
556594 // 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"
558596 {
559597 let mut to_remove = Vec :: new ( ) ;
560598 for ( k, v) in sources. map . iter ( ) {
@@ -570,7 +608,7 @@ mod c {
570608 }
571609
572610 // Android uses emulated TLS so we need a runtime support function.
573- if target_os == "android" {
611+ if target . os == "android" {
574612 sources. extend ( & [ ( "__emutls_get_address" , "emutls.c" ) ] ) ;
575613
576614 // Work around a bug in the NDK headers (fixed in
@@ -580,7 +618,7 @@ mod c {
580618 }
581619
582620 // OpenHarmony also uses emulated TLS.
583- if target_env == "ohos" {
621+ if target . env == "ohos" {
584622 sources. extend ( & [ ( "__emutls_get_address" , "emutls.c" ) ] ) ;
585623 }
586624
@@ -607,7 +645,7 @@ mod c {
607645 // sets of flags to the same source file.
608646 // Note: Out-of-line aarch64 atomics are not supported by the msvc toolchain (#430).
609647 let src_dir = root. join ( "lib/builtins" ) ;
610- if target_arch == "aarch64" && target_env != "msvc" {
648+ if target . arch == "aarch64" && target . env != "msvc" {
611649 // See below for why we're building these as separate libraries.
612650 build_aarch64_out_of_line_atomics_libraries ( & src_dir, cfg) ;
613651
0 commit comments