Test building custom targets and resolve an issue probing rustc

The `rustc` probe done in our build scripts needs to pass `--target` to
get the correct configuration, which usually comes from the `TARGET`
environment variable. However, for targets specified via a `target.json`
file, `TARGET` gets set to the file name without an extension or path.
`rustc` will check a search path to attempt to locate the file, but this
is likely to fail since the directory where Cargo invokes build scripts
(and hence where those scripts invoke `rustc`) might not have any
relation to the JSON spec file.

Resolve this for now by leaving `f16` and `f128` disabled if the `rustc`
command fails. Result of the discussion at CARGO-14208 may eventually
provide a better solution.

A CI test is also added since custom JSON files are an edge case that
could fail in other ways. I verified this fails without the fix here.
The JSON file is the output for `thumbv7em-none-eabi`, just renamed so
`rustc` doesn't identify it.
This commit is contained in:
Trevor Gross 2025-07-04 19:42:18 -05:00
parent 19ab6461fb
commit 016bc61312
No known key found for this signature in database
GPG key ID: 7FE436A2537D184B
4 changed files with 63 additions and 6 deletions

View file

@ -195,6 +195,25 @@ jobs:
run: ./ci/update-musl.sh
- run: cargo clippy --workspace --all-targets
build-custom:
name: Build custom target
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Install Rust
run: |
rustup update nightly --no-self-update
rustup default nightly
rustup component add rust-src
- uses: Swatinem/rust-cache@v2
- run: |
# Ensure we can build with custom target.json files (these can interact
# poorly with build scripts)
cargo build -p compiler_builtins -p libm \
--target etc/thumbv7em-none-eabi-renamed.json \
-Zbuild-std=core
benchmarks:
name: Benchmarks
timeout-minutes: 20
@ -331,6 +350,7 @@ jobs:
success:
needs:
- benchmarks
- build-custom
- clippy
- extensive
- miri

View file

@ -45,9 +45,16 @@ impl Target {
let out = cmd
.output()
.unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
assert!(out.status.success(), "failed to run `{cmd:?}`");
let rustc_cfg = str::from_utf8(&out.stdout).unwrap();
// If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
// choice and leave `f16` and `f128` disabled.
let rustc_output_ok = out.status.success();
let reliable_f128 =
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
let reliable_f16 =
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");
Self {
triple,
triple_split,
@ -67,8 +74,8 @@ impl Target {
.split(",")
.map(ToOwned::to_owned)
.collect(),
reliable_f128: rustc_cfg.lines().any(|l| l == "target_has_reliable_f128"),
reliable_f16: rustc_cfg.lines().any(|l| l == "target_has_reliable_f16"),
reliable_f128,
reliable_f16,
}
}

View file

@ -0,0 +1,23 @@
{
"abi": "eabi",
"arch": "arm",
"c-enum-min-bits": 8,
"crt-objects-fallback": "false",
"data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
"emit-debug-gdb-scripts": false,
"frame-pointer": "always",
"linker": "rust-lld",
"linker-flavor": "gnu-lld",
"llvm-floatabi": "soft",
"llvm-target": "thumbv7em-none-eabi",
"max-atomic-width": 32,
"metadata": {
"description": "Bare ARMv7E-M",
"host_tools": false,
"std": false,
"tier": 2
},
"panic-strategy": "abort",
"relocation-model": "static",
"target-pointer-width": "32"
}

View file

@ -43,9 +43,16 @@ impl Config {
let out = cmd
.output()
.unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
assert!(out.status.success(), "failed to run `{cmd:?}`");
let rustc_cfg = str::from_utf8(&out.stdout).unwrap();
// If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
// choice and leave `f16` and `f128` disabled.
let rustc_output_ok = out.status.success();
let reliable_f128 =
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
let reliable_f16 =
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");
Self {
target_triple,
manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
@ -59,8 +66,8 @@ impl Config {
target_string: env::var("TARGET").unwrap(),
target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
target_features,
reliable_f128: rustc_cfg.lines().any(|l| l == "target_has_reliable_f128"),
reliable_f16: rustc_cfg.lines().any(|l| l == "target_has_reliable_f16"),
reliable_f128,
reliable_f16,
}
}
}