mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-08 13:18:32 +00:00
190 lines
6.8 KiB
Rust
190 lines
6.8 KiB
Rust
// Configuration shared with both libm and libm-test
|
|
|
|
use std::env;
|
|
use std::path::PathBuf;
|
|
|
|
#[allow(dead_code)]
|
|
pub struct Config {
|
|
pub manifest_dir: PathBuf,
|
|
pub out_dir: PathBuf,
|
|
pub opt_level: String,
|
|
pub cargo_features: Vec<String>,
|
|
pub target_arch: String,
|
|
pub target_env: String,
|
|
pub target_family: Option<String>,
|
|
pub target_os: String,
|
|
pub target_string: String,
|
|
pub target_vendor: String,
|
|
pub target_features: Vec<String>,
|
|
}
|
|
|
|
impl Config {
|
|
pub fn from_env() -> Self {
|
|
let target_features = env::var("CARGO_CFG_TARGET_FEATURE")
|
|
.map(|feats| feats.split(',').map(ToOwned::to_owned).collect())
|
|
.unwrap_or_default();
|
|
let cargo_features = env::vars()
|
|
.filter_map(|(name, _value)| name.strip_prefix("CARGO_FEATURE_").map(ToOwned::to_owned))
|
|
.map(|s| s.to_lowercase().replace("_", "-"))
|
|
.collect();
|
|
|
|
Self {
|
|
manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
|
|
out_dir: PathBuf::from(env::var("OUT_DIR").unwrap()),
|
|
opt_level: env::var("OPT_LEVEL").unwrap(),
|
|
cargo_features,
|
|
target_arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
|
|
target_env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
|
|
target_family: env::var("CARGO_CFG_TARGET_FAMILY").ok(),
|
|
target_os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
|
|
target_string: env::var("TARGET").unwrap(),
|
|
target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
|
|
target_features,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Libm gets most config options made available.
|
|
#[allow(dead_code)]
|
|
pub fn emit_libm_config(cfg: &Config) {
|
|
emit_intrinsics_cfg();
|
|
emit_arch_cfg();
|
|
emit_optimization_cfg(cfg);
|
|
emit_cfg_shorthands(cfg);
|
|
emit_cfg_env(cfg);
|
|
emit_f16_f128_cfg(cfg);
|
|
}
|
|
|
|
/// Tests don't need most feature-related config.
|
|
#[allow(dead_code)]
|
|
pub fn emit_test_config(cfg: &Config) {
|
|
emit_optimization_cfg(cfg);
|
|
emit_cfg_shorthands(cfg);
|
|
emit_cfg_env(cfg);
|
|
emit_f16_f128_cfg(cfg);
|
|
}
|
|
|
|
/// Simplify the feature logic for enabling intrinsics so code only needs to use
|
|
/// `cfg(intrinsics_enabled)`.
|
|
fn emit_intrinsics_cfg() {
|
|
println!("cargo:rustc-check-cfg=cfg(intrinsics_enabled)");
|
|
|
|
// Disabled by default; `unstable-intrinsics` enables again; `force-soft-floats` overrides
|
|
// to disable.
|
|
if cfg!(feature = "unstable-intrinsics") && !cfg!(feature = "force-soft-floats") {
|
|
println!("cargo:rustc-cfg=intrinsics_enabled");
|
|
}
|
|
}
|
|
|
|
/// Simplify the feature logic for enabling arch-specific features so code only needs to use
|
|
/// `cfg(arch_enabled)`.
|
|
fn emit_arch_cfg() {
|
|
println!("cargo:rustc-check-cfg=cfg(arch_enabled)");
|
|
|
|
// Enabled by default via the "arch" feature, `force-soft-floats` overrides to disable.
|
|
if cfg!(feature = "arch") && !cfg!(feature = "force-soft-floats") {
|
|
println!("cargo:rustc-cfg=arch_enabled");
|
|
}
|
|
}
|
|
|
|
/// Some tests are extremely slow. Emit a config option based on optimization level.
|
|
fn emit_optimization_cfg(cfg: &Config) {
|
|
println!("cargo:rustc-check-cfg=cfg(optimizations_enabled)");
|
|
|
|
if !matches!(cfg.opt_level.as_str(), "0" | "1") {
|
|
println!("cargo:rustc-cfg=optimizations_enabled");
|
|
}
|
|
}
|
|
|
|
/// Provide an alias for common longer config combinations.
|
|
fn emit_cfg_shorthands(cfg: &Config) {
|
|
println!("cargo:rustc-check-cfg=cfg(x86_no_sse)");
|
|
if cfg.target_arch == "x86" && !cfg.target_features.iter().any(|f| f == "sse") {
|
|
// Shorthand to detect i586 targets
|
|
println!("cargo:rustc-cfg=x86_no_sse");
|
|
}
|
|
}
|
|
|
|
/// Reemit config that we make use of for test logging.
|
|
fn emit_cfg_env(cfg: &Config) {
|
|
println!(
|
|
"cargo:rustc-env=CFG_CARGO_FEATURES={:?}",
|
|
cfg.cargo_features
|
|
);
|
|
println!("cargo:rustc-env=CFG_OPT_LEVEL={}", cfg.opt_level);
|
|
println!(
|
|
"cargo:rustc-env=CFG_TARGET_FEATURES={:?}",
|
|
cfg.target_features
|
|
);
|
|
}
|
|
|
|
/// Configure whether or not `f16` and `f128` support should be enabled.
|
|
fn emit_f16_f128_cfg(cfg: &Config) {
|
|
println!("cargo:rustc-check-cfg=cfg(f16_enabled)");
|
|
println!("cargo:rustc-check-cfg=cfg(f128_enabled)");
|
|
|
|
// `unstable-float` enables these features.
|
|
if !cfg!(feature = "unstable-float") {
|
|
return;
|
|
}
|
|
|
|
// Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
|
|
// that the backend will not crash when using these types and generates code that can be called
|
|
// without crashing (no infinite recursion). This does not mean that the platform doesn't have
|
|
// ABI or other bugs.
|
|
//
|
|
// We do this here rather than in `rust-lang/rust` because configuring via cargo features is
|
|
// not straightforward.
|
|
//
|
|
// Original source of this list:
|
|
// <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
|
|
let f16_enabled = match cfg.target_arch.as_str() {
|
|
// Unsupported <https://github.com/llvm/llvm-project/issues/94434>
|
|
"arm64ec" => false,
|
|
// Selection failure <https://github.com/llvm/llvm-project/issues/50374>
|
|
"s390x" => false,
|
|
// Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
|
|
// FIXME(llvm): loongarch fixed by <https://github.com/llvm/llvm-project/pull/107791>
|
|
"csky" => false,
|
|
"hexagon" => false,
|
|
"loongarch64" => false,
|
|
"mips" | "mips64" | "mips32r6" | "mips64r6" => false,
|
|
"powerpc" | "powerpc64" => false,
|
|
"sparc" | "sparc64" => false,
|
|
"wasm32" | "wasm64" => false,
|
|
// Most everything else works as of LLVM 19
|
|
_ => true,
|
|
};
|
|
|
|
let f128_enabled = match cfg.target_arch.as_str() {
|
|
// Unsupported (libcall is not supported) <https://github.com/llvm/llvm-project/issues/121122>
|
|
"amdgpu" => false,
|
|
// Unsupported <https://github.com/llvm/llvm-project/issues/94434>
|
|
"arm64ec" => false,
|
|
// Selection failure <https://github.com/llvm/llvm-project/issues/96432>
|
|
"mips64" | "mips64r6" => false,
|
|
// Selection failure <https://github.com/llvm/llvm-project/issues/95471>
|
|
"nvptx64" => false,
|
|
// Selection failure <https://github.com/llvm/llvm-project/issues/101545>
|
|
"powerpc64" if &cfg.target_os == "aix" => false,
|
|
// Selection failure <https://github.com/llvm/llvm-project/issues/41838>
|
|
"sparc" => false,
|
|
// Most everything else works as of LLVM 19
|
|
_ => true,
|
|
};
|
|
|
|
// If the feature is set, disable these types.
|
|
let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some();
|
|
|
|
println!("cargo:rustc-check-cfg=cfg(f16_enabled)");
|
|
println!("cargo:rustc-check-cfg=cfg(f128_enabled)");
|
|
|
|
if f16_enabled && !disable_both {
|
|
println!("cargo:rustc-cfg=f16_enabled");
|
|
}
|
|
|
|
if f128_enabled && !disable_both {
|
|
println!("cargo:rustc-cfg=f128_enabled");
|
|
}
|
|
}
|