`examples.nix` had settings that only repeated what the `config` already
implied. They read as if the platform were special, when it ought to be
the default. Now the default logic in `default.nix` ought to handle the
setting in question in a rule-based way so it is.
Change:
- `useLLVM` now covers
- UEFI
- MSVC CRT and C++ ABI
- Windows on AArch64 as well as FreeBSD and OpenBSD
- `libc` gains a UEFI case
hat retires seven `useLLVM` settings, eighteen `libc = "newlib"`, one
`libc = "bionic"`, and the `libc`/`linker` pair on the UEFI examples.
The remaining `libc`s in examples now means"this differs from what the
triple implies", which is true of the seven left: `newlib-nano`, the
mingw `msvcrt`/`ucrt` pairs those entries exist to distinguish, and
`mmix`, whose OS is `mmixware` rather than `none` so the bare-metal
default does not reach it. That one gains a comment.
No functional change. Elaborating all 87 platforms in
`lib.systems.examples` before and after gives byte-identical `config`,
`system`, `useLLVM`, `useGccNG`, `libc`, `linker` and
`rust.rustcTarget`. `mmix` surfaced that way, having regressed to
`native/impure`.
Assisted-by: Claude Code (Claude Opus 5)
Nothing could select the split GCC package set, so none of the fixes
below this commit were reachable from a normal build.
Add `useGccNG` alongside the existing `useLLVM`/`useZig`/`useArocc`
choices, and honour it where a compiler is picked: the cross stdenv takes
`gccNGPackages.gcc`, and `stdenvNoLibs`/`stdenvNoLibc` map to
`gccNoLibgcc` and `gccWithLibgcc`. That last pair is the point of the
split. Both currently fall back to `gccCrossLibcStdenv`, because the
monolithic compiler cannot distinguish them; `lib/systems/default.nix`
says as much next to `linker`, noting that we would like to choose the C
compiler and runtime library orthogonally but "due to the monolithic GCC
build we cannot actually make those choices independently". This is what
lifts that, the way the LLVM set already splits `clangNoCompilerRt` from
`clangNoLibc`.
`gccNGPackages` tracks `default-gcc-version` rather than naming a
release, so the split set and the monolithic `gcc` stay on the same one.
`useGccNG` defaults to `false` and no platform derives it, so no existing
build changes. Setting it on a platform spec is enough to exercise the
whole stack:
nix-build . -A stdenv.cc --arg crossSystem \
'{ config = "aarch64-unknown-linux-musl"; useGccNG = true; }'
The intent is to switch obscure low-tier platforms over to it soon --
NetBSD first -- so `ng` gets dogfooded somewhere the blast radius is
small. Those switches come separately.
Assisted-by: Claude Code (Claude Opus 5)
Wasi P2 is different enough to Wasi P1 to warrant being treated entirely
separately, rather than as two minor variants of the same thing. P3 will
likewise want to be a different target.
I've left aliases in place; maybe eventually, those can be deprecated
and removed. I've tested this, but it's possible there might be breakage
somewhere (e.g., the canonical doubles for P1 have changed, though I
can't imagine why anyone would rely on that).
Fixes https://github.com/NixOS/nixpkgs/issues/435954
A platform elaborated by another supported revision of Nixpkgs would
trip the assertion when it is re-elaborated.
Avoid this, by checking `oldestSupportedReleaseIsAtLeast 2511`, as 25.11
is the version that stopped adding `linux-kernel` to elaborated systems.
rustc allows code to perform compile-time tests against target_env [0],
which is a function of the target triple. There isn't provision in
Nixpkgs for learning target_env, however. That doesn't affect rustc's
evaluation of cfg guards in Rust code - rustc knows perfectly well what
target_env is - but it _does_ affect the env vars passed to a build
script set by buildRustCrate, which is presently hard-coded to gnu, and
also affects any Nix code looking to branch on target_env.
Being able to access target_env is very relevant to, for example, WASI
as (using Rust terminology) wasm32-wasip1 and wasm32-wasip2 differ only
by target_env, with identical target_arch and target_os values. Properly
reflecting target_env may also fix some random musl issues if you're a
bit lucky.
This commit adds a new attr, rust.platform.env, which reflects the
target_env that rustc will set for the target, and wires it up in
buildRustCrate. In isolation, this change mostly only affects build
scripts checking target_env, but crate2nix will greatly benefit from
being able to accurately resolve the dep graph (which can also vary
depending on target_env).
The target triple -> target_env function resists Kolmogorov compression:
it's irregular and, though there are some patterns, there are lots of
special cases. So, I have done the stupidest possible thing and scraped
out all of the targets with non-empty target_env values and dumped that
into an attrset. This attrset will progressively get out of date as
rustc adds new platforms, but updating it should be simple enough - I've
included the generation script as a comment.
There are some other configuration options not being reflected in Nix. I
have left those alone, but, in the future, maybe this can be extended to
just dumping all of them into an attrset and then reflecting them in
rust.platform. It might even make sense to convert the existing code
producing rust.platform to just looking up from an attrset and to 'do
what rustc does'.
I would have liked to have added a test targetting a platform with a
non-empty non-GNU target_env, but all of the yaks were quite hairy.
Fixes https://github.com/NixOS/nixpkgs/issues/436832
[0]: https://doc.rust-lang.org/reference/conditional-compilation.html#r-cfg.target_env
Currently, you need to override `stdenv.hostPlatform` to request a
compressed kernel on AArch64, and the kernel configuration is split
between the central structured configuration and string snippets in
platform definitions. This has consequently made the latter bitrot
terribly. Since the platform‐specific logic is now very limited after
cleaning up the detritus, we can move it into the kernel derivation
and expose the relevant configuration there for anyone who wants to
customize it further or needs to read it out.
Co-authored-by: zowoq <59103226+zowoq@users.noreply.github.com>
Add sh4 CPU type (32-bit, little-endian, family "sh"), isSh4 predicate,
"sh4-linux" system double, cross-compilation example (sh4-unknown-linux-gnu),
linuxArch mapping to "sh", and test entry.
Use lib.filter and lib.attrNames instead of builtins.* directly,
consistent with the rest of the file's style.
Follow-up to #506588, incorporating review feedback from #507232.
`qemuArch` returned "aarch64" for both LE and BE, causing binfmt to
register `qemu-aarch64` for `aarch64_be` binaries. QEMU ships separate
`qemu-aarch64` and `qemu-aarch64_be` binaries, so the wrong interpreter
was used, failing with "Invalid ELF image for this architecture".
Since QEMU distinguishes endianness in the binary name, this adds the
"_be" suffix via `isBigEndian`, which is similar to the approach MIPS
uses a few lines below.
Make rustcTargetSpec the primary entrypoint for setting a custom target,
and wire up all the other stuff so they are hopefully as working and as
broken as before.
In particular, to specify a custom target, the user now just specifies
rust.rustcTargetSpec. rust.platform and rust.cargoShortTarget are
populated from rust.rustcTargetSpec now. In addition, rust.rustcTarget
defaults to rust.cargoShortTarget. (rust.rustcTarget and
rust.cargoShortTarget really should always be the same, but I think we
can deal with that later).
This allows the user to more easily control the basename of
rust.rustcTargetSpec by passing e.g.
"${./rust}/mips64el_mips3-unknown-linux-gnuabi64.json", which allows
cc-rs and in turn std to work.
Rust does not know how to parse "gnuabielfv{1,2}", so simplify those down to just "gnu".
This obsoletes the manual rustcTarget fix in the ppc64-elfv1 example.
The old cygwin support used -pc-windows-cygnus as the config. This is
supported by LLVM, but not by GNU. This will change it to -pc-cygwin,
which is more generally supported.
Because the kernel is now 'cygwin' rather than 'windows', isWindows will
return false. There are lots of different reasons isWindows is used in
nixpkgs, but in my experience they often have to do with posix
compatibility and don't apply to cygwin.
Co-authored-by: Brian McKenna <brian@brianmckenna.org>
this architecture mapping is used broadly in the node ecosystem.
an assortment of tools and hooks, like buildNpmPackage or
pnpm.configHook, will benefit from reusing these values. placing them in
stdenv makes sense because (1) several of these tools don't currently
depend on nodejs, and may even be available where nodejs is not and (2)
`stdenv.{build,host,target}Platform` seems to be less error-prone than
`pkgs*.nodejs.{os,arch}` -- especially for setup hooks where the offsets
are shifted.
qemu architecture names are fixed — we're using uname here just
because it's more likely to be correct than CPU name (see e.g. POWER).
This means that aarch64 is always called aarch64, even on Darwin where
uname reports arm64.
Fixes: 61582c7043 ("lib/systems: use Darwin architecture names for `config` and `uname`")