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()8fn 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>110fn 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