12add0d91Sopenharmony_ciuse std::env; 22add0d91Sopenharmony_ciuse std::process::Command; 32add0d91Sopenharmony_ciuse std::str; 42add0d91Sopenharmony_ci 52add0d91Sopenharmony_cifn main() { 62add0d91Sopenharmony_ci // Avoid unnecessary re-building. 72add0d91Sopenharmony_ci println!("cargo:rerun-if-changed=build.rs"); 82add0d91Sopenharmony_ci 92add0d91Sopenharmony_ci let (rustc_minor_ver, is_nightly) = rustc_minor_nightly(); 102add0d91Sopenharmony_ci let rustc_dep_of_std = env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok(); 112add0d91Sopenharmony_ci let align_cargo_feature = env::var("CARGO_FEATURE_ALIGN").is_ok(); 122add0d91Sopenharmony_ci let const_extern_fn_cargo_feature = env::var("CARGO_FEATURE_CONST_EXTERN_FN").is_ok(); 132add0d91Sopenharmony_ci let libc_ci = env::var("LIBC_CI").is_ok(); 142add0d91Sopenharmony_ci 152add0d91Sopenharmony_ci if env::var("CARGO_FEATURE_USE_STD").is_ok() { 162add0d91Sopenharmony_ci println!( 172add0d91Sopenharmony_ci "cargo:warning=\"libc's use_std cargo feature is deprecated since libc 0.2.55; \ 182add0d91Sopenharmony_ci please consider using the `std` cargo feature instead\"" 192add0d91Sopenharmony_ci ); 202add0d91Sopenharmony_ci } 212add0d91Sopenharmony_ci 222add0d91Sopenharmony_ci // The ABI of libc used by libstd is backward compatible with FreeBSD 10. 232add0d91Sopenharmony_ci // The ABI of libc from crates.io is backward compatible with FreeBSD 11. 242add0d91Sopenharmony_ci // 252add0d91Sopenharmony_ci // On CI, we detect the actual FreeBSD version and match its ABI exactly, 262add0d91Sopenharmony_ci // running tests to ensure that the ABI is correct. 272add0d91Sopenharmony_ci match which_freebsd() { 282add0d91Sopenharmony_ci Some(10) if libc_ci || rustc_dep_of_std => { 292add0d91Sopenharmony_ci println!("cargo:rustc-cfg=freebsd10") 302add0d91Sopenharmony_ci } 312add0d91Sopenharmony_ci Some(11) if libc_ci => println!("cargo:rustc-cfg=freebsd11"), 322add0d91Sopenharmony_ci Some(12) if libc_ci => println!("cargo:rustc-cfg=freebsd12"), 332add0d91Sopenharmony_ci Some(13) if libc_ci => println!("cargo:rustc-cfg=freebsd13"), 342add0d91Sopenharmony_ci Some(14) if libc_ci => println!("cargo:rustc-cfg=freebsd14"), 352add0d91Sopenharmony_ci Some(_) | None => println!("cargo:rustc-cfg=freebsd11"), 362add0d91Sopenharmony_ci } 372add0d91Sopenharmony_ci 382add0d91Sopenharmony_ci // On CI: deny all warnings 392add0d91Sopenharmony_ci if libc_ci { 402add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_deny_warnings"); 412add0d91Sopenharmony_ci } 422add0d91Sopenharmony_ci 432add0d91Sopenharmony_ci // Rust >= 1.15 supports private module use: 442add0d91Sopenharmony_ci if rustc_minor_ver >= 15 || rustc_dep_of_std { 452add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_priv_mod_use"); 462add0d91Sopenharmony_ci } 472add0d91Sopenharmony_ci 482add0d91Sopenharmony_ci // Rust >= 1.19 supports unions: 492add0d91Sopenharmony_ci if rustc_minor_ver >= 19 || rustc_dep_of_std { 502add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_union"); 512add0d91Sopenharmony_ci } 522add0d91Sopenharmony_ci 532add0d91Sopenharmony_ci // Rust >= 1.24 supports const mem::size_of: 542add0d91Sopenharmony_ci if rustc_minor_ver >= 24 || rustc_dep_of_std { 552add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_const_size_of"); 562add0d91Sopenharmony_ci } 572add0d91Sopenharmony_ci 582add0d91Sopenharmony_ci // Rust >= 1.25 supports repr(align): 592add0d91Sopenharmony_ci if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature { 602add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_align"); 612add0d91Sopenharmony_ci } 622add0d91Sopenharmony_ci 632add0d91Sopenharmony_ci // Rust >= 1.26 supports i128 and u128: 642add0d91Sopenharmony_ci if rustc_minor_ver >= 26 || rustc_dep_of_std { 652add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_int128"); 662add0d91Sopenharmony_ci } 672add0d91Sopenharmony_ci 682add0d91Sopenharmony_ci // Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it. 692add0d91Sopenharmony_ci // Otherwise, it defines an incompatible type to retaining 702add0d91Sopenharmony_ci // backwards-compatibility. 712add0d91Sopenharmony_ci if rustc_minor_ver >= 30 || rustc_dep_of_std { 722add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_core_cvoid"); 732add0d91Sopenharmony_ci } 742add0d91Sopenharmony_ci 752add0d91Sopenharmony_ci // Rust >= 1.33 supports repr(packed(N)) and cfg(target_vendor). 762add0d91Sopenharmony_ci if rustc_minor_ver >= 33 || rustc_dep_of_std { 772add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_packedN"); 782add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_cfg_target_vendor"); 792add0d91Sopenharmony_ci } 802add0d91Sopenharmony_ci 812add0d91Sopenharmony_ci // Rust >= 1.40 supports #[non_exhaustive]. 822add0d91Sopenharmony_ci if rustc_minor_ver >= 40 || rustc_dep_of_std { 832add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_non_exhaustive"); 842add0d91Sopenharmony_ci } 852add0d91Sopenharmony_ci 862add0d91Sopenharmony_ci if rustc_minor_ver >= 51 || rustc_dep_of_std { 872add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_ptr_addr_of"); 882add0d91Sopenharmony_ci } 892add0d91Sopenharmony_ci 902add0d91Sopenharmony_ci // Rust >= 1.37.0 allows underscores as anonymous constant names. 912add0d91Sopenharmony_ci if rustc_minor_ver >= 37 || rustc_dep_of_std { 922add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_underscore_const_names"); 932add0d91Sopenharmony_ci } 942add0d91Sopenharmony_ci 952add0d91Sopenharmony_ci // #[thread_local] is currently unstable 962add0d91Sopenharmony_ci if rustc_dep_of_std { 972add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_thread_local"); 982add0d91Sopenharmony_ci } 992add0d91Sopenharmony_ci 1002add0d91Sopenharmony_ci // Rust >= 1.62.0 allows to use `const_extern_fn` for "Rust" and "C". 1012add0d91Sopenharmony_ci if rustc_minor_ver >= 62 { 1022add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_const_extern_fn"); 1032add0d91Sopenharmony_ci } else { 1042add0d91Sopenharmony_ci // Rust < 1.62.0 requires a crate feature and feature gate. 1052add0d91Sopenharmony_ci if const_extern_fn_cargo_feature { 1062add0d91Sopenharmony_ci if !is_nightly || rustc_minor_ver < 40 { 1072add0d91Sopenharmony_ci panic!("const-extern-fn requires a nightly compiler >= 1.40"); 1082add0d91Sopenharmony_ci } 1092add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_const_extern_fn_unstable"); 1102add0d91Sopenharmony_ci println!("cargo:rustc-cfg=libc_const_extern_fn"); 1112add0d91Sopenharmony_ci } 1122add0d91Sopenharmony_ci } 1132add0d91Sopenharmony_ci} 1142add0d91Sopenharmony_ci 1152add0d91Sopenharmony_cifn rustc_minor_nightly() -> (u32, bool) { 1162add0d91Sopenharmony_ci macro_rules! otry { 1172add0d91Sopenharmony_ci ($e:expr) => { 1182add0d91Sopenharmony_ci match $e { 1192add0d91Sopenharmony_ci Some(e) => e, 1202add0d91Sopenharmony_ci None => panic!("Failed to get rustc version"), 1212add0d91Sopenharmony_ci } 1222add0d91Sopenharmony_ci }; 1232add0d91Sopenharmony_ci } 1242add0d91Sopenharmony_ci 1252add0d91Sopenharmony_ci let rustc = otry!(env::var_os("RUSTC")); 1262add0d91Sopenharmony_ci let output = Command::new(rustc) 1272add0d91Sopenharmony_ci .arg("--version") 1282add0d91Sopenharmony_ci .output() 1292add0d91Sopenharmony_ci .ok() 1302add0d91Sopenharmony_ci .expect("Failed to get rustc version"); 1312add0d91Sopenharmony_ci let version = otry!(str::from_utf8(&output.stdout).ok()); 1322add0d91Sopenharmony_ci let mut pieces = version.split('.'); 1332add0d91Sopenharmony_ci 1342add0d91Sopenharmony_ci if pieces.next() != Some("rustc 1") { 1352add0d91Sopenharmony_ci panic!("Failed to get rustc version"); 1362add0d91Sopenharmony_ci } 1372add0d91Sopenharmony_ci 1382add0d91Sopenharmony_ci let minor = pieces.next(); 1392add0d91Sopenharmony_ci 1402add0d91Sopenharmony_ci // If `rustc` was built from a tarball, its version string 1412add0d91Sopenharmony_ci // will have neither a git hash nor a commit date 1422add0d91Sopenharmony_ci // (e.g. "rustc 1.39.0"). Treat this case as non-nightly, 1432add0d91Sopenharmony_ci // since a nightly build should either come from CI 1442add0d91Sopenharmony_ci // or a git checkout 1452add0d91Sopenharmony_ci let nightly_raw = otry!(pieces.next()).split('-').nth(1); 1462add0d91Sopenharmony_ci let nightly = nightly_raw 1472add0d91Sopenharmony_ci .map(|raw| raw.starts_with("dev") || raw.starts_with("nightly")) 1482add0d91Sopenharmony_ci .unwrap_or(false); 1492add0d91Sopenharmony_ci let minor = otry!(otry!(minor).parse().ok()); 1502add0d91Sopenharmony_ci 1512add0d91Sopenharmony_ci (minor, nightly) 1522add0d91Sopenharmony_ci} 1532add0d91Sopenharmony_ci 1542add0d91Sopenharmony_cifn which_freebsd() -> Option<i32> { 1552add0d91Sopenharmony_ci let output = std::process::Command::new("freebsd-version").output().ok(); 1562add0d91Sopenharmony_ci if output.is_none() { 1572add0d91Sopenharmony_ci return None; 1582add0d91Sopenharmony_ci } 1592add0d91Sopenharmony_ci let output = output.unwrap(); 1602add0d91Sopenharmony_ci if !output.status.success() { 1612add0d91Sopenharmony_ci return None; 1622add0d91Sopenharmony_ci } 1632add0d91Sopenharmony_ci 1642add0d91Sopenharmony_ci let stdout = String::from_utf8(output.stdout).ok(); 1652add0d91Sopenharmony_ci if stdout.is_none() { 1662add0d91Sopenharmony_ci return None; 1672add0d91Sopenharmony_ci } 1682add0d91Sopenharmony_ci let stdout = stdout.unwrap(); 1692add0d91Sopenharmony_ci 1702add0d91Sopenharmony_ci match &stdout { 1712add0d91Sopenharmony_ci s if s.starts_with("10") => Some(10), 1722add0d91Sopenharmony_ci s if s.starts_with("11") => Some(11), 1732add0d91Sopenharmony_ci s if s.starts_with("12") => Some(12), 1742add0d91Sopenharmony_ci s if s.starts_with("13") => Some(13), 1752add0d91Sopenharmony_ci s if s.starts_with("14") => Some(14), 1762add0d91Sopenharmony_ci _ => None, 1772add0d91Sopenharmony_ci } 1782add0d91Sopenharmony_ci} 179