diff --git a/build.rs b/build.rs index 2d5c6ace..5898cad5 100644 --- a/build.rs +++ b/build.rs @@ -14,7 +14,7 @@ struct Target { impl Target { fn from_env() -> Self { - let little_endian = match env::var("CARGO_CFG_TARGET_LITTLE_ENDIAN").unwrap().as_str() { + let little_endian = match env::var("CARGO_CFG_TARGET_ENDIAN").unwrap().as_str() { "little" => true, "big" => false, x => panic!("unknown endian {x}"), @@ -31,7 +31,7 @@ impl Target { .parse() .unwrap(), little_endian, - features: env::var("CARGO_CFG_TARGET_FEATURES") + features: env::var("CARGO_CFG_TARGET_FEATURE") .unwrap() .split(",") .map(ToOwned::to_owned) @@ -42,11 +42,12 @@ impl Target { fn main() { println!("cargo:rerun-if-changed=build.rs"); - configure_check_cfg(); - let target = Target::from_env(); let cwd = env::current_dir().unwrap(); + configure_check_cfg(); + configure_f16_f128(&target); + println!("cargo:compiler-rt={}", cwd.join("compiler-rt").display()); // Activate libm's unstable features to make full use of Nightly. @@ -259,6 +260,45 @@ fn configure_check_cfg() { println!("cargo::rustc-check-cfg=cfg(assert_no_panic)"); } +/// Configure whether or not `f16` and `f128` support should be enabled. +fn configure_f16_f128(target: &Target) { + // 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. This does not mean that the + // backend does the right thing, or that the platform doesn't have ABI bugs. + // + // We do this so symbols are provided when `long double` is `f128` which prevents linking + // errors on musl (musl makes use of `long double`). + // + // HACK: this logic should be in `rust-lang/rust` so changes only need to be done in one + // place. However, there is no straightforward way to do this, so we do it here. + let (f16_ok, f128_ok) = match target.arch.as_str() { + // No selection failures + "aarch64" | "x86" | "x86_64" | "riscv32" | "riscv64" | "mips" | "mips64" => (true, true), + // `f16` selection failure https://github.com/llvm/llvm-project/issues/93894 + "loongarch" | "loongarch64" => (false, true), + // conversion selection failure. `f128` is needed because of `long double`, `f16` is more + // optional. . + "powerpc" | "powerpc64" => (false, true), + // No `f16` support + "s390x" => (false, true), + _ => (false, false), + }; + + // 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_ok && !disable_both { + println!("cargo:rustc-cfg=f16_enabled") + } + + if f128_ok && !disable_both { + println!("cargo:rustc-cfg=f128_enabled") + } +} + #[cfg(feature = "c")] mod c { use std::collections::{BTreeMap, HashSet};