17e2e9c0cSopenharmony_ciuse std::env; 27e2e9c0cSopenharmony_ciuse std::process::Command; 37e2e9c0cSopenharmony_ciuse std::str::{self, FromStr}; 47e2e9c0cSopenharmony_ci 57e2e9c0cSopenharmony_ci// The rustc-cfg strings below are *not* public API. Please let us know by 67e2e9c0cSopenharmony_ci// opening a GitHub issue if your build environment requires some way to enable 77e2e9c0cSopenharmony_ci// these cfgs other than by executing our build script. 87e2e9c0cSopenharmony_cifn main() { 97e2e9c0cSopenharmony_ci println!("cargo:rerun-if-changed=build.rs"); 107e2e9c0cSopenharmony_ci 117e2e9c0cSopenharmony_ci let minor = match rustc_minor_version() { 127e2e9c0cSopenharmony_ci Some(minor) => minor, 137e2e9c0cSopenharmony_ci None => return, 147e2e9c0cSopenharmony_ci }; 157e2e9c0cSopenharmony_ci 167e2e9c0cSopenharmony_ci let target = env::var("TARGET").unwrap(); 177e2e9c0cSopenharmony_ci let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten"; 187e2e9c0cSopenharmony_ci 197e2e9c0cSopenharmony_ci // TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add 207e2e9c0cSopenharmony_ci // stabilized in Rust 1.34: 217e2e9c0cSopenharmony_ci // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto 227e2e9c0cSopenharmony_ci // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations 237e2e9c0cSopenharmony_ci if minor < 34 { 247e2e9c0cSopenharmony_ci println!("cargo:rustc-cfg=no_core_try_from"); 257e2e9c0cSopenharmony_ci println!("cargo:rustc-cfg=no_num_nonzero_signed"); 267e2e9c0cSopenharmony_ci println!("cargo:rustc-cfg=no_systemtime_checked_add"); 277e2e9c0cSopenharmony_ci println!("cargo:rustc-cfg=no_relaxed_trait_bounds"); 287e2e9c0cSopenharmony_ci } 297e2e9c0cSopenharmony_ci 307e2e9c0cSopenharmony_ci // f32::copysign and f64::copysign stabilized in Rust 1.35. 317e2e9c0cSopenharmony_ci // https://blog.rust-lang.org/2019/05/23/Rust-1.35.0.html#copy-the-sign-of-a-floating-point-number-onto-another 327e2e9c0cSopenharmony_ci if minor < 35 { 337e2e9c0cSopenharmony_ci println!("cargo:rustc-cfg=no_float_copysign"); 347e2e9c0cSopenharmony_ci } 357e2e9c0cSopenharmony_ci 367e2e9c0cSopenharmony_ci // Current minimum supported version of serde_derive crate is Rust 1.56. 377e2e9c0cSopenharmony_ci if minor < 56 { 387e2e9c0cSopenharmony_ci println!("cargo:rustc-cfg=no_serde_derive"); 397e2e9c0cSopenharmony_ci } 407e2e9c0cSopenharmony_ci 417e2e9c0cSopenharmony_ci // Support for #[cfg(target_has_atomic = "...")] stabilized in Rust 1.60. 427e2e9c0cSopenharmony_ci if minor < 60 { 437e2e9c0cSopenharmony_ci println!("cargo:rustc-cfg=no_target_has_atomic"); 447e2e9c0cSopenharmony_ci // Allowlist of archs that support std::sync::atomic module. This is 457e2e9c0cSopenharmony_ci // based on rustc's compiler/rustc_target/src/spec/*.rs. 467e2e9c0cSopenharmony_ci let has_atomic64 = target.starts_with("x86_64") 477e2e9c0cSopenharmony_ci || target.starts_with("i686") 487e2e9c0cSopenharmony_ci || target.starts_with("aarch64") 497e2e9c0cSopenharmony_ci || target.starts_with("powerpc64") 507e2e9c0cSopenharmony_ci || target.starts_with("sparc64") 517e2e9c0cSopenharmony_ci || target.starts_with("mips64el") 527e2e9c0cSopenharmony_ci || target.starts_with("riscv64"); 537e2e9c0cSopenharmony_ci let has_atomic32 = has_atomic64 || emscripten; 547e2e9c0cSopenharmony_ci if minor < 34 || !has_atomic64 { 557e2e9c0cSopenharmony_ci println!("cargo:rustc-cfg=no_std_atomic64"); 567e2e9c0cSopenharmony_ci } 577e2e9c0cSopenharmony_ci if minor < 34 || !has_atomic32 { 587e2e9c0cSopenharmony_ci println!("cargo:rustc-cfg=no_std_atomic"); 597e2e9c0cSopenharmony_ci } 607e2e9c0cSopenharmony_ci } 617e2e9c0cSopenharmony_ci 627e2e9c0cSopenharmony_ci // Support for core::ffi::CStr and alloc::ffi::CString stabilized in Rust 1.64. 637e2e9c0cSopenharmony_ci // https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html#c-compatible-ffi-types-in-core-and-alloc 647e2e9c0cSopenharmony_ci if minor < 64 { 657e2e9c0cSopenharmony_ci println!("cargo:rustc-cfg=no_core_cstr"); 667e2e9c0cSopenharmony_ci } 677e2e9c0cSopenharmony_ci} 687e2e9c0cSopenharmony_ci 697e2e9c0cSopenharmony_cifn rustc_minor_version() -> Option<u32> { 707e2e9c0cSopenharmony_ci let rustc = match env::var_os("RUSTC") { 717e2e9c0cSopenharmony_ci Some(rustc) => rustc, 727e2e9c0cSopenharmony_ci None => return None, 737e2e9c0cSopenharmony_ci }; 747e2e9c0cSopenharmony_ci 757e2e9c0cSopenharmony_ci let output = match Command::new(rustc).arg("--version").output() { 767e2e9c0cSopenharmony_ci Ok(output) => output, 777e2e9c0cSopenharmony_ci Err(_) => return None, 787e2e9c0cSopenharmony_ci }; 797e2e9c0cSopenharmony_ci 807e2e9c0cSopenharmony_ci let version = match str::from_utf8(&output.stdout) { 817e2e9c0cSopenharmony_ci Ok(version) => version, 827e2e9c0cSopenharmony_ci Err(_) => return None, 837e2e9c0cSopenharmony_ci }; 847e2e9c0cSopenharmony_ci 857e2e9c0cSopenharmony_ci let mut pieces = version.split('.'); 867e2e9c0cSopenharmony_ci if pieces.next() != Some("rustc 1") { 877e2e9c0cSopenharmony_ci return None; 887e2e9c0cSopenharmony_ci } 897e2e9c0cSopenharmony_ci 907e2e9c0cSopenharmony_ci let next = match pieces.next() { 917e2e9c0cSopenharmony_ci Some(next) => next, 927e2e9c0cSopenharmony_ci None => return None, 937e2e9c0cSopenharmony_ci }; 947e2e9c0cSopenharmony_ci 957e2e9c0cSopenharmony_ci u32::from_str(next).ok() 967e2e9c0cSopenharmony_ci} 97