lib.systems: rust: Make rustcTargetSpec the primary entrypoint (#446668)

This commit is contained in:
Alyssa Ross 2026-03-07 08:22:44 +00:00 committed by GitHub
commit bd0c7ad05a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 98 additions and 89 deletions

View file

@ -254,7 +254,7 @@ By default, it takes the `stdenv.hostPlatform.config` and replaces components
where they are known to differ. But there are ways to customize the argument:
- To choose a different target by name, define
`stdenv.hostPlatform.rust.rustcTarget` as that name (a string), and that
`stdenv.hostPlatform.rust.rustcTargetSpec` as that name (a string), and that
name will be used instead.
For example:
@ -262,7 +262,7 @@ where they are known to differ. But there are ways to customize the argument:
```nix
import <nixpkgs> {
crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
rust.rustcTarget = "thumbv7em-none-eabi";
rust.rustcTargetSpec = "thumbv7em-none-eabi";
};
}
```
@ -274,22 +274,24 @@ where they are known to differ. But there are ways to customize the argument:
```
- To pass a completely custom target, define
`stdenv.hostPlatform.rust.rustcTarget` with its name, and
`stdenv.hostPlatform.rust.platform` with the value. The value will be
serialized to JSON in a file called
`${stdenv.hostPlatform.rust.rustcTarget}.json`, and the path of that file
will be used instead.
`stdenv.hostPlatform.rust.rustcTargetSpec` with the path to the custom
target specification JSON file.
Note that some tools like Cargo and some crates like `cc` make use of the
file name of the target JSON. Therefore, do not use
`./path/to/target-spec.json` directly, because it will be renamed by Nix.
Instead, place it a directory and use `"${./path/to/dir}/target-spec.json"`.
The directory should contain only this one file, to avoid unrelated changes
causing unnecessary rebuilds.
For example:
```nix
import <nixpkgs> {
crossSystem = (import <nixpkgs/lib>).systems.examples.armhf-embedded // {
rust.rustcTarget = "thumb-crazy";
rust.platform = {
foo = "";
bar = "";
};
crossSystem = {
config = "mips64el-unknown-linux-gnuabi64";
# gcc = ...; # Config for C compiler omitted
rust.rustcTargetSpec = "${./rust}/mips64el_mips3-unknown-linux-gnuabi64.json";
};
}
```
@ -297,12 +299,9 @@ where they are known to differ. But there are ways to customize the argument:
will result in:
```shell
--target /nix/store/asdfasdfsadf-thumb-crazy.json # contains {"foo":"","bar":""}
--target /nix/store/...-rust/mips64el_mips3-unknown-linux-gnuabi64.json
```
Note that currently custom targets aren't compiled with `std`, so `cargo test`
will fail. This can be ignored by adding `doCheck = false;` to your derivation.
### Running package tests {#running-package-tests}
When using `buildRustPackage`, the `checkPhase` is enabled by default and runs

View file

@ -417,12 +417,20 @@ let
// args
// {
rust = rust // {
platform =
rust.platform or (
if lib.hasSuffix ".json" (rust.rustcTargetSpec or "") then
lib.importJSON rust.rustcTargetSpec
else
{ }
)
# Once args.rustc.platform.target-family is deprecated and
# removed, there will no longer be any need to modify any
# values from args.rust.platform, so we can drop all the
# "args ? rust" etc. checks, and merge args.rust.platform in
# /after/.
platform = rust.platform or { } // {
// {
# https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch
arch =
if rust ? platform then
@ -474,9 +482,10 @@ let
.${vendor.name} or vendor.name;
};
# The name of the rust target, even if it is custom. Adjustments are
# because rust has slightly different naming conventions than we do.
rustcTarget =
# The name of the rust target if it is standard, or the json file
# containing the custom target spec. Adjustments are because rust has
# slightly different naming conventions than we do.
rustcTargetSpec =
let
inherit (final.parsed) cpu kernel abi;
cpu_ =
@ -497,28 +506,29 @@ let
"gnu"
else
abi.name;
in
# TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL.
args.rust.rustcTarget or args.rustc.config or (
inferred =
if final.isWasi then
# Rust uses `wasm32-wasip?` rather than `wasm32-unknown-wasi`.
# We cannot know which subversion does the user want, and
# currently use WASI 0.1 as default for compatibility. Custom
# users can set `rust.rustcTarget` to override it.
if final.isWasi then
# users can set `rust.rustcTargetSpec` to override it.
"${cpu_}-wasip1"
else
"${cpu_}-${vendor_}-${kernel.name}${optionalString (abi.name != "unknown") "-${abi_}"}"
"${cpu_}-${vendor_}-${kernel.name}${optionalString (abi.name != "unknown") "-${abi_}"}";
in
# TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL.
args.rust.rustcTargetSpec or args.rustc.config or (
if rust ? platform then
# TODO: This breaks cc-rs and thus std support, so maybe remove support?
builtins.toFile (rust.rustcTarget or inferred + ".json") (toJSON rust.platform)
else
args.rust.rustcTarget or inferred
);
# The name of the rust target if it is standard, or the json file
# containing the custom target spec.
rustcTargetSpec =
rust.rustcTargetSpec or (
if rust ? platform then
builtins.toFile (final.rust.rustcTarget + ".json") (toJSON rust.platform)
else
final.rust.rustcTarget
);
# Do not use rustcTarget. Use rustcTargetSpec or cargoShortTarget.
# TODO: Remove all in-tree usages, and deprecate
rustcTarget = rust.rustcTarget or final.rust.cargoShortTarget;
# The name of the rust target if it is standard, or the
# basename of the file containing the custom target spec,