@@ -14,7 +14,7 @@ struct Target {
1414
1515impl Target {
1616 fn from_env ( ) -> Self {
17- let little_endian = match env:: var ( "CARGO_CFG_TARGET_LITTLE_ENDIAN " ) . unwrap ( ) . as_str ( ) {
17+ let little_endian = match env:: var ( "CARGO_CFG_TARGET_ENDIAN " ) . unwrap ( ) . as_str ( ) {
1818 "little" => true ,
1919 "big" => false ,
2020 x => panic ! ( "unknown endian {x}" ) ,
@@ -31,7 +31,7 @@ impl Target {
3131 . parse ( )
3232 . unwrap ( ) ,
3333 little_endian,
34- features : env:: var ( "CARGO_CFG_TARGET_FEATURES " )
34+ features : env:: var ( "CARGO_CFG_TARGET_FEATURE " )
3535 . unwrap ( )
3636 . split ( "," )
3737 . map ( ToOwned :: to_owned)
@@ -42,11 +42,12 @@ impl Target {
4242
4343fn main ( ) {
4444 println ! ( "cargo:rerun-if-changed=build.rs" ) ;
45- configure_check_cfg ( ) ;
46-
4745 let target = Target :: from_env ( ) ;
4846 let cwd = env:: current_dir ( ) . unwrap ( ) ;
4947
48+ configure_check_cfg ( ) ;
49+ configure_f16_f128 ( & target) ;
50+
5051 println ! ( "cargo:compiler-rt={}" , cwd. join( "compiler-rt" ) . display( ) ) ;
5152
5253 // Activate libm's unstable features to make full use of Nightly.
@@ -259,6 +260,49 @@ fn configure_check_cfg() {
259260 println ! ( "cargo::rustc-check-cfg=cfg(assert_no_panic)" ) ;
260261}
261262
263+ /// Configure whether or not `f16` and `f128` support should be enabled.
264+ fn configure_f16_f128 ( target : & Target ) {
265+ // Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
266+ // that the backend will not crash when using these types. This does not mean that the
267+ // backend does the right thing, or that the platform doesn't have ABI bugs.
268+ //
269+ // We do this so symbols are provided when `long double` is `f128` which prevents linking
270+ // errors on musl (musl makes use of `long double`).
271+ //
272+ // HACK: this logic should be in `rust-lang/rust` so changes only need to be done in one
273+ // place. However, there is no straightforward way to do this, so we do it here.
274+ let ( f16_ok, f128_ok) = match target. arch . as_str ( ) {
275+ // No selection failures
276+ "aarch64" | "x86" | "x86_64" | "riscv32" | "riscv64" | "mips" | "mips64" => ( true , true ) ,
277+ // `f16` selection failure https://github.com/llvm/llvm-project/issues/93894
278+ "loongarch" | "loongarch64" => ( false , true ) ,
279+ // conversion selection failure. `f128` is needed because of `long double`, `f16` is more
280+ // optional. <https://github.com/llvm/llvm-project/issues/92866>.
281+ "powerpc" | "powerpc64" => ( false , true ) ,
282+ // No `f16` support <https://github.com/llvm/llvm-project/issues/50374>
283+ "s390x" => ( false , true ) ,
284+ _ => ( false , false ) ,
285+ } ;
286+
287+ // If the feature is set, disable these types.
288+ let disable_both = env:: var_os ( "CARGO_FEATURE_NO_F16_F128" ) . is_some ( ) ;
289+
290+ println ! ( "cargo:warning=f16 {f16_ok} f128 {f128_ok} disable both {disable_both}" ) ;
291+
292+ println ! ( "cargo::rustc-check-cfg=cfg(f16_enabled)" ) ;
293+ println ! ( "cargo::rustc-check-cfg=cfg(f128_enabled)" ) ;
294+
295+ if f16_ok && !disable_both {
296+ println ! ( "cargo::rustc-cfg=f16_enabled" ) ;
297+ println ! ( "cargo:warning=f16 enabled" ) ;
298+ }
299+
300+ if f128_ok && !disable_both {
301+ println ! ( "cargo::rustc-cfg=f128_enabled" ) ;
302+ println ! ( "cargo:warning=f128 enabled" ) ;
303+ }
304+ }
305+
262306#[ cfg( feature = "c" ) ]
263307mod c {
264308 use std:: collections:: { BTreeMap , HashSet } ;
0 commit comments