summaryrefslogtreecommitdiff
path: root/library/std/build.rs
blob: c5d0af469a8e9df6a5bff1b8f123002fd640b8c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
use std::env;

fn main() {
    println!("cargo:rerun-if-changed=build.rs");
    let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH was not set");
    let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set");
    let target_vendor =
        env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
    let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
    let target_pointer_width: u32 = env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
        .expect("CARGO_CFG_TARGET_POINTER_WIDTH was not set")
        .parse()
        .unwrap();
    let is_miri = env::var_os("CARGO_CFG_MIRI").is_some();

    println!("cargo:rustc-check-cfg=cfg(netbsd10)");
    if target_os == "netbsd" && env::var("RUSTC_STD_NETBSD10").is_ok() {
        println!("cargo:rustc-cfg=netbsd10");
    }

    println!("cargo:rustc-check-cfg=cfg(restricted_std)");
    if target_os == "linux"
        || target_os == "android"
        || target_os == "netbsd"
        || target_os == "dragonfly"
        || target_os == "openbsd"
        || target_os == "freebsd"
        || target_os == "solaris"
        || target_os == "illumos"
        || target_os == "macos"
        || target_os == "ios"
        || target_os == "tvos"
        || target_os == "watchos"
        || target_os == "visionos"
        || target_os == "windows"
        || target_os == "fuchsia"
        || (target_vendor == "fortanix" && target_env == "sgx")
        || target_os == "hermit"
        || target_os == "l4re"
        || target_os == "redox"
        || target_os == "haiku"
        || target_os == "vxworks"
        || target_arch == "wasm32"
        || target_arch == "wasm64"
        || target_os == "espidf"
        || target_os.starts_with("solid")
        || (target_vendor == "nintendo" && target_env == "newlib")
        || target_os == "vita"
        || target_os == "aix"
        || target_os == "nto"
        || target_os == "xous"
        || target_os == "hurd"
        || target_os == "uefi"
        || target_os == "teeos"
        || target_os == "zkvm"
        || target_os == "rtems"
        || target_os == "nuttx"

        // See src/bootstrap/src/core/build_steps/synthetic_targets.rs
        || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
    {
        // These platforms don't have any special requirements.
    } else {
        // This is for Cargo's build-std support, to mark std as unstable for
        // typically no_std platforms.
        // This covers:
        // - os=none ("bare metal" targets)
        // - mipsel-sony-psp
        // - nvptx64-nvidia-cuda
        // - arch=avr
        // - JSON targets
        // - Any new targets that have not been explicitly added above.
        println!("cargo:rustc-cfg=restricted_std");
    }

    println!("cargo:rustc-check-cfg=cfg(backtrace_in_libstd)");
    println!("cargo:rustc-cfg=backtrace_in_libstd");

    println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap());

    // Emit these on platforms that have no known ABI bugs, LLVM selection bugs, lowering bugs,
    // missing symbols, or other problems, to determine when tests get run.
    // If more broken platforms are found, please update the tracking issue at
    // <https://github.com/rust-lang/rust/issues/116909>
    //
    // Some of these match arms are redundant; the goal is to separate reasons that the type is
    // unreliable, even when multiple reasons might fail the same platform.
    println!("cargo:rustc-check-cfg=cfg(reliable_f16)");
    println!("cargo:rustc-check-cfg=cfg(reliable_f128)");

    // This is a step beyond only having the types and basic functions available. Math functions
    // aren't consistently available or correct.
    println!("cargo:rustc-check-cfg=cfg(reliable_f16_math)");
    println!("cargo:rustc-check-cfg=cfg(reliable_f128_math)");

    let has_reliable_f16 = match (target_arch.as_str(), target_os.as_str()) {
        // We can always enable these in Miri as that is not affected by codegen bugs.
        _ if is_miri => true,
        // Selection failure <https://github.com/llvm/llvm-project/issues/50374>
        ("s390x", _) => false,
        // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
        ("arm64ec", _) => false,
        // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
        ("x86_64", "windows") => false,
        // Apple has a special ABI for `f16` that we do not yet support
        // FIXME(builtins): fixed by <https://github.com/rust-lang/compiler-builtins/pull/675>
        ("x86" | "x86_64", _) if target_vendor == "apple" => false,
        // Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
        ("csky", _) => false,
        ("hexagon", _) => false,
        ("loongarch64", _) => false,
        ("mips" | "mips64" | "mips32r6" | "mips64r6", _) => false,
        ("powerpc" | "powerpc64", _) => false,
        ("sparc" | "sparc64", _) => false,
        ("wasm32" | "wasm64", _) => false,
        // `f16` support only requires that symbols converting to and from `f32` are available. We
        // provide these in `compiler-builtins`, so `f16` should be available on all platforms that
        // do not have other ABI issues or LLVM crashes.
        _ => true,
    };

    let has_reliable_f128 = match (target_arch.as_str(), target_os.as_str()) {
        // We can always enable these in Miri as that is not affected by codegen bugs.
        _ if is_miri => true,
        // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
        ("arm64ec", _) => false,
        // ABI and precision bugs <https://github.com/rust-lang/rust/issues/125109>
        // <https://github.com/rust-lang/rust/issues/125102>
        ("powerpc" | "powerpc64", _) => false,
        // Selection bug <https://github.com/llvm/llvm-project/issues/95471>
        ("nvptx64", _) => false,
        // ABI unsupported  <https://github.com/llvm/llvm-project/issues/41838>
        ("sparc", _) => false,
        // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
        ("x86_64", "windows") => false,
        // 64-bit Linux is about the only platform to have f128 symbols by default
        (_, "linux") if target_pointer_width == 64 => true,
        // Same as for f16, except MacOS is also missing f128 symbols.
        _ => false,
    };

    // Configure platforms that have reliable basics but may have unreliable math.

    // LLVM is currently adding missing routines, <https://github.com/llvm/llvm-project/issues/93566>
    let has_reliable_f16_math = has_reliable_f16
        && match (target_arch.as_str(), target_os.as_str()) {
            // FIXME: Disabled on Miri as the intrinsics are not implemented yet.
            _ if is_miri => false,
            // x86 has a crash for `powi`: <https://github.com/llvm/llvm-project/issues/105747>
            ("x86" | "x86_64", _) => false,
            // Assume that working `f16` means working `f16` math for most platforms, since
            // operations just go through `f32`.
            _ => true,
        };

    let has_reliable_f128_math = has_reliable_f128
        && match (target_arch.as_str(), target_os.as_str()) {
            // FIXME: Disabled on Miri as the intrinsics are not implemented yet.
            _ if is_miri => false,
            // LLVM lowers `fp128` math to `long double` symbols even on platforms where
            // `long double` is not IEEE binary128. See
            // <https://github.com/llvm/llvm-project/issues/44744>.
            //
            // This rules out anything that doesn't have `long double` = `binary128`; <= 32 bits
            // (ld is `f64`), anything other than Linux (Windows and MacOS use `f64`), and `x86`
            // (ld is 80-bit extended precision).
            ("x86_64", _) => false,
            (_, "linux") if target_pointer_width == 64 => true,
            _ => false,
        };

    if has_reliable_f16 {
        println!("cargo:rustc-cfg=reliable_f16");
    }
    if has_reliable_f128 {
        println!("cargo:rustc-cfg=reliable_f128");
    }
    if has_reliable_f16_math {
        println!("cargo:rustc-cfg=reliable_f16_math");
    }
    if has_reliable_f128_math {
        println!("cargo:rustc-cfg=reliable_f128_math");
    }
}