Files
lms0806 9436ba5067 time: use C altzone when available (#8357)
* time: use C altzone when available

* Modified to also check TARGET_CC/CC_target.
2026-07-25 20:03:52 +09:00

73 lines
2.2 KiB
Rust

//! Like CPython's `HAVE_ALTZONE`, it detects the presence of `altzone` in `time.h` at build time.
#![allow(
clippy::disallowed_methods,
reason = "build scripts cannot use rustpython-host_env"
)]
use std::{env, fs, path::PathBuf};
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rustc-check-cfg=cfg(has_altzone)");
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default();
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
if target_env == "msvc" || target_arch == "wasm32" {
return;
}
let host = env::var("HOST").unwrap_or_default();
let target = env::var("TARGET").unwrap_or_default();
// cc::Build resolves CC_<target>, CC_<target_with_underscores>, TARGET_CC, then CC.
if host != target && !has_target_c_compiler(&target) {
return;
}
if probe_altzone() {
println!("cargo:rustc-cfg=has_altzone");
}
}
/// Whether any compiler env var that `cc::Build` would consult for the target is set.
fn has_target_c_compiler(target: &str) -> bool {
let underscored = target.replace(['-', '.'], "_");
env::var_os(format!("CC_{target}")).is_some()
|| env::var_os(format!("CC_{underscored}")).is_some()
|| env::var_os("TARGET_CC").is_some()
|| env::var_os("CC").is_some()
}
/// Check corresponding to `AC_TRY_COMPILE(... altzone ...)` in CPython's `configure`.
fn probe_altzone() -> bool {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR"));
let src = out_dir.join("probe_altzone.c");
let obj = out_dir.join("probe_altzone.o");
if fs::write(
&src,
"#include <time.h>\nint main(void) { return (int)altzone; }\n",
)
.is_err()
{
return false;
}
let Ok(compiler) = cc::Build::new().try_get_compiler() else {
return false;
};
let mut cmd = compiler.to_command();
if compiler.is_like_msvc() {
cmd.arg("/c").arg(&src).arg(format!("/Fo{}", obj.display()));
} else {
cmd.arg("-c").arg(&src).arg("-o").arg(&obj);
}
match cmd.output() {
Ok(output) => output.status.success(),
Err(_) => false,
}
}