@@ -14,7 +14,7 @@ struct Target {
14
14
15
15
impl Target {
16
16
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 ( ) {
18
18
"little" => true ,
19
19
"big" => false ,
20
20
x => panic ! ( "unknown endian {x}" ) ,
@@ -31,7 +31,7 @@ impl Target {
31
31
. parse ( )
32
32
. unwrap ( ) ,
33
33
little_endian,
34
- features : env:: var ( "CARGO_CFG_TARGET_FEATURES " )
34
+ features : env:: var ( "CARGO_CFG_TARGET_FEATURE " )
35
35
. unwrap ( )
36
36
. split ( "," )
37
37
. map ( ToOwned :: to_owned)
@@ -42,11 +42,12 @@ impl Target {
42
42
43
43
fn main ( ) {
44
44
println ! ( "cargo:rerun-if-changed=build.rs" ) ;
45
- configure_check_cfg ( ) ;
46
-
47
45
let target = Target :: from_env ( ) ;
48
46
let cwd = env:: current_dir ( ) . unwrap ( ) ;
49
47
48
+ configure_check_cfg ( ) ;
49
+ configure_f16_f128 ( & target) ;
50
+
50
51
println ! ( "cargo:compiler-rt={}" , cwd. join( "compiler-rt" ) . display( ) ) ;
51
52
52
53
// Activate libm's unstable features to make full use of Nightly.
@@ -259,6 +260,49 @@ fn configure_check_cfg() {
259
260
println ! ( "cargo::rustc-check-cfg=cfg(assert_no_panic)" ) ;
260
261
}
261
262
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
+
262
306
#[ cfg( feature = "c" ) ]
263
307
mod c {
264
308
use std:: collections:: { BTreeMap , HashSet } ;
0 commit comments