• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::env;
2 use std::process::Command;
3 use std::str;
4 
5 // The rustc-cfg strings below are *not* public API. Please let us know by
6 // opening a GitHub issue if your build environment requires some way to enable
7 // these cfgs other than by executing our build script.
main()8 fn main() {
9     println!("cargo:rerun-if-changed=build.rs");
10 
11     let minor = match rustc_minor_version() {
12         Some(minor) => minor,
13         None => return,
14     };
15 
16     if minor >= 77 {
17         println!("cargo:rustc-check-cfg=cfg(no_core_cstr)");
18         println!("cargo:rustc-check-cfg=cfg(no_core_error)");
19         println!("cargo:rustc-check-cfg=cfg(no_core_net)");
20         println!("cargo:rustc-check-cfg=cfg(no_core_num_saturating)");
21         println!("cargo:rustc-check-cfg=cfg(no_core_try_from)");
22         println!("cargo:rustc-check-cfg=cfg(no_diagnostic_namespace)");
23         println!("cargo:rustc-check-cfg=cfg(no_float_copysign)");
24         println!("cargo:rustc-check-cfg=cfg(no_num_nonzero_signed)");
25         println!("cargo:rustc-check-cfg=cfg(no_relaxed_trait_bounds)");
26         println!("cargo:rustc-check-cfg=cfg(no_serde_derive)");
27         println!("cargo:rustc-check-cfg=cfg(no_std_atomic)");
28         println!("cargo:rustc-check-cfg=cfg(no_std_atomic64)");
29         println!("cargo:rustc-check-cfg=cfg(no_systemtime_checked_add)");
30         println!("cargo:rustc-check-cfg=cfg(no_target_has_atomic)");
31     }
32 
33     let target = env::var("TARGET").unwrap();
34     let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
35 
36     // TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add
37     // stabilized in Rust 1.34:
38     // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto
39     // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations
40     if minor < 34 {
41         println!("cargo:rustc-cfg=no_core_try_from");
42         println!("cargo:rustc-cfg=no_num_nonzero_signed");
43         println!("cargo:rustc-cfg=no_systemtime_checked_add");
44         println!("cargo:rustc-cfg=no_relaxed_trait_bounds");
45     }
46 
47     // f32::copysign and f64::copysign stabilized in Rust 1.35.
48     // https://blog.rust-lang.org/2019/05/23/Rust-1.35.0.html#copy-the-sign-of-a-floating-point-number-onto-another
49     if minor < 35 {
50         println!("cargo:rustc-cfg=no_float_copysign");
51     }
52 
53     // Support for #[cfg(target_has_atomic = "...")] stabilized in Rust 1.60.
54     if minor < 60 {
55         println!("cargo:rustc-cfg=no_target_has_atomic");
56         // Allowlist of archs that support std::sync::atomic module. This is
57         // based on rustc's compiler/rustc_target/src/spec/*.rs.
58         let has_atomic64 = target.starts_with("x86_64")
59             || target.starts_with("i686")
60             || target.starts_with("aarch64")
61             || target.starts_with("powerpc64")
62             || target.starts_with("sparc64")
63             || target.starts_with("mips64el")
64             || target.starts_with("riscv64");
65         let has_atomic32 = has_atomic64 || emscripten;
66         if minor < 34 || !has_atomic64 {
67             println!("cargo:rustc-cfg=no_std_atomic64");
68         }
69         if minor < 34 || !has_atomic32 {
70             println!("cargo:rustc-cfg=no_std_atomic");
71         }
72     }
73 
74     // Current minimum supported version of serde_derive crate is Rust 1.61.
75     if minor < 61 {
76         println!("cargo:rustc-cfg=no_serde_derive");
77     }
78 
79     // Support for core::ffi::CStr and alloc::ffi::CString stabilized in Rust 1.64.
80     // https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html#c-compatible-ffi-types-in-core-and-alloc
81     if minor < 64 {
82         println!("cargo:rustc-cfg=no_core_cstr");
83     }
84 
85     // Support for core::num::Saturating and std::num::Saturating stabilized in Rust 1.74
86     // https://blog.rust-lang.org/2023/11/16/Rust-1.74.0.html#stabilized-apis
87     if minor < 74 {
88         println!("cargo:rustc-cfg=no_core_num_saturating");
89     }
90 
91     // Support for core::net stabilized in Rust 1.77.
92     // https://blog.rust-lang.org/2024/03/21/Rust-1.77.0.html
93     if minor < 77 {
94         println!("cargo:rustc-cfg=no_core_net");
95     }
96 
97     // Support for the `#[diagnostic]` tool attribute namespace
98     // https://blog.rust-lang.org/2024/05/02/Rust-1.78.0.html#diagnostic-attributes
99     if minor < 78 {
100         println!("cargo:rustc-cfg=no_diagnostic_namespace");
101     }
102 
103     // The Error trait became available in core in 1.81.
104     // https://blog.rust-lang.org/2024/09/05/Rust-1.81.0.html#coreerrorerror
105     if minor < 81 {
106         println!("cargo:rustc-cfg=no_core_error");
107     }
108 }
109 
rustc_minor_version() -> Option<u32>110 fn rustc_minor_version() -> Option<u32> {
111     let rustc = env::var_os("RUSTC")?;
112     let output = Command::new(rustc).arg("--version").output().ok()?;
113     let version = str::from_utf8(&output.stdout).ok()?;
114     let mut pieces = version.split('.');
115     if pieces.next() != Some("rustc 1") {
116         return None;
117     }
118     pieces.next()?.parse().ok()
119 }
120