Commit 82ff1f5db1 in #182807 removed two lines
from stage.nix which were responsible for making sure the `gcc` for `pkgsStatic`
on powerpc64 was built with the `--with-abi=elfv2` flag.
Unfortunately this causes build failures for `pkgsCross.ppc64.pkgsStatic`, as
reported here:
https://github.com/NixOS/nixpkgs/pull/182807#issuecomment-1247268226
This commit reverts the deletion.
Unfortunately ugly kludges like this are necessary because nixpkgs'
`lib/systems/` doesn't understand the difference between a libc and an abi. So
we have no clean way to tell nixpkgs "musl on big-endian powerpc64 always uses
the ELFv2 ABI" -- it thinks that musl is an ABI. Until that gets fixed there is
no better way to add the flag.
This simplifies usages and makes the default value consistent.
In a few cases, the default value was interpreted to be `false`,
but this is useless, because virtually nobody will explicitly
set `allowAliases = true;`.
MIPS has a large space of {architecture,abi,endianness}; this commit
adds all of them to lib/systems/platforms.nix so we can be done with
it.
Currently lib/systems/inspect.nix has a single "isMips" predicate,
which is a bit ambiguous now that we will have both mips32 and mips64
support, with the latter having two ABIs. Let's add four new
predicates (isMips32, isMips64, isMips64n32, and isMips64n64) and
treat the now-ambiguous isMips as deprecated in favor of the
more-specific predicates. These predicates are used mainly for
enabling/disabling target-specific workarounds, and it is extremely
rare that a platform-specific workaround is needed, and both mips32
and mips64 need exactly the same workaround.
The separate predicates (isMips64n32 and isMips64n64) for ABI
distinctions are, unfortunately, useful. Boost's user-scheduled
threading (used by nix) does does not currently supports mips64n32,
which is a very desirable ABI on routers since they rarely have
more than 2**32 bytes of DRAM.
The comment
a dirty hack that should be removed
has led me to believe that nixpkgsFun isn't the right solution,
but bypassing it is worse, because it creates a second, inner
overriding mechanism that doesn't pass its changes to the old,
outer overriding mechanism.
Before this change:
nix-repl> ((import <nixpkgs> {}).appendOverlays([(f: s: { foobarbaz = "ok"; })])).foobarbaz
"ok"
nix-repl> ((import <nixpkgs> {}).appendOverlays([(f: s: { foobarbaz = "ok"; })])).pkgsCross.aarch64-multiplatform.foobarbaz
error: attribute 'foobarbaz' missing
at «string»:1:1:
1| ((import <nixpkgs> {}).appendOverlays([(f: s: { foobarbaz = "ok"; })])).pkgsCross.aarch64-multiplatform.foobarbaz
| ^
2|
After this change:
nix-repl> ((import ./. {}).appendOverlays([(f: s: { foobarbaz = "ok"; })])).pkgsCross.aarch64-multiplatform.foobarbaz
"ok"
Thanks to samueldr for discovering this problem.
The old stdenv adapters were subtly wrong in two ways:
- `overrideAttrs` leaked the original, unoverridden `mkDerivation`.
- `stdenv.override` would throw away any manually-set `mkDerivation`
from a stdenv reverting to the original.
Now, `mkDerivation` is controlled (nearly directly) via an argument, and
always correctly closes over the final ("self") stdenv. This means the
adapters can work entirely via `.override` without any manual `stdenv //
...`, and both those issues are fixed.
Note hashes are changed, because stdenvs no previously overridden like
`stdenvNoCC` and `crossLibcStdenv` now are. I had to add some
`dontDisableStatic = true` accordingly. The flip side however is that
since the overrides compose, we no longer need to override anything but
the default `stdenv` from which all the others are created.
Fixes pkgsCross.muslpi.nix (depends on
pkgsCross.muslpi.busybox-sandbox-shell, which depends on
pkgsCross.muslpi.pkgsStatic.stdenv)
Currently, the ABI adapter in pkgsStatic does not
recognize musleabi/musleabihf and falls back to "musl".
```
> nix eval -f . pkgsCross.muslpi.stdenv.hostPlatform.config
"armv6l-unknown-linux-musleabihf"
> nix eval -f . pkgsCross.muslpi.pkgsStatic.stdenv.hostPlatform.config
"armv6l-unknown-linux-musl"
```
This results in an invalid config passed to GCC configuration, which
fails with `Configuration armv6l-unknown-linux-musl not supported`.
PR #122778 allowed the linker being chosen independently from useLLVM
which also affected pkgsLLVM where we were relying on this behavior.
For platform sets assembled from scratch useLLVM still implies
linker == "lld", however in the case of pkgsLLVM we update the current
platform via the set update operator which means that `linker` won't
be re-evaluated. Using ld.bfd with pkgsLLVM is okay to a certain extent,
but with C++ things begin to break.
We fix this by setting linker explicitly.
Provide a version of nixpkgs which is built using the LLVM toolchain.
This is achieved by reusing the useLLVM attribute usable in the cross
toolchain bootstrapping which is a) perfectly acceptable and b) the only
way to bootstrap a LLVM stdenv across platforms without unreasonable
amounts of work.
This is mostly working now since we fixed some issues with
llvmPackages_7.lldClang in #119717 and compile glibc with gcc at all
times as of #119786 (since clang can't compile our glibc at the moment).
There are seemingly some issues left to be ironed out, for example the
C++ library of ncurses fails to build with a linking issue. I have
attempted to alleviate that problem with #120790, but to no avail so
far.
Nonetheless, having a working pkgsLLVM.hello is a good start.
A currently present issue is that there is no way to change the libc
since there is some issue with lldClang actually picking up on the set
libc. This will need investigation and fixing.
The staging logic reconstructs the target platform, discarding
powerpc64's custom gcc.abi = elfv2 setup. Musl requires ELFv2 ABI so
this should be set unconditionally here.
Each invocation of pkgs.extends adds 130MB of allocation to the hydra
evaluator. We are already struggling with the amount of memory nixpkgs
requires.
`pkgs.extend` is a useful escape-hatch, but should be not be used inside
of nixpkgs directly.
Consider example:
$ nix-instantiate ./nixos -A system --arg configuration '
{
boot.isContainer = true;
nixpkgs.overlays = [ (self: super: {
nix = self.pkgsStatic.nix;
}) ];
}'
When resolving package through overlays, we figure out that
nix == self.pkgsStatic.nix
=>
nix == (import <nixpkgs> { inherit overlays; }).nix
=>
nix == (import <nixpkgs> { overlays = [(self: super: { nix = self.pkgsStatic.nix; })];}).nix
and we enter infinite recursion of nixpkgs evaluations.
The proper fix should terminate recursion by assigning self fixpoint
to inner custom package set. But I get infinite recursion somehow, so
I use `super`. It is less correct modulo deep custom overrides, but behaves
correctly for simple cases and doesn't OOM evaluator.
Fixes https://github.com/NixOS/nixpkgs/issues/57984
This is needed to avoid confusing and repeated boilerplate for
`fooForTarget`. The vast majority of use-cases can still use
`buildPackages or `targetPackages`, which are now defined in terms of
these.
Whenever we create scripts that are installed to $out, we must use runtimeShell
in order to get the shell that can be executed on the machine we create the
package for. This is relevant for cross-compiling. The only use case for
stdenv.shell are scripts that are executed as part of the build system.
Usages in checkPhase are borderline however to decrease the likelyhood
of people copying the wrong examples, I decided to use runtimeShell as well.
This enables inspection of the currently used overlays. Useful for
usecases where nixpkgs is imported multiple times.
eg. different channels
self: super:
let
latest = import <nixpkgs-trunk> {
inherit (super) config overlays;
};
in
{
hello-custom-latest = latest.hello-custom;
}
Adds the static overlay that can be used to build Nixpkgs statically.
Can be used like:
nix build pkgsStatic.hello
Not all packages build, as some rely on dynamic linking.
For historical reasons, self was ill-named. This removes its usages
from all-packages.nix and provides a deprecation message for those
who use a patched Nixpkgs.
Some packages seem to depend on the peculiarities of res, as can
be seen by making res into an alias of pkgs (normally "self").
The super variable doesn't have all that is needed.
Therefore the simple fix is not guaranteed to work and as such,
usages of res need to be changed to pkgs or super, case by case.
This is something that I have found useful in tests. In practice
I recommend that people call Nixpkgs once for performance and
simplicity. The inline documentation mentions this too.
2a6e4ae49a and
e51f736076 reverted a bit too much, and I
initially missed this when reviewing. The release notes already still
mention this change, too.
Intuitively, one cares mainly about the host platform: Platforms differ
in meaningful ways but compilation is morally a pure process and
probably doesn't care, or those difference are already abstracted away.
@Dezgeg also empirically confirmed that > 95% of checks are indeed of
the host platform.
Yet these attributes in the old cross infrastructure were defined to be
the build platform, for expediency. And this was never before changed.
(For native builds build and host coincide, so it isn't clear what the
intention was.)
Fixing this doesn't affect native builds, since again they coincide. It
also doesn't affect cross builds of anything in Nixpkgs, as these are no
longer used. It could affect external cross builds, but I deem that
unlikely as anyone thinking about cross would use more explicit
attributes for clarity, all the more so because the rarity of inspecting
the build platform.
I don't know when we can/should remove them, but this at least gets
people to stop using them. The preferred alternatives also date back to
17.09 so writing forward-compatable code without extra conditions is
easy.
Beginning with these as they are the least controversial.