For a long time, we've had `crossLibcStdenv`, `*Cross` libc attributes,
and `*bsdCross` pre-libc package sets. This was always bad because
having "cross" things is "not declarative": the naming doesn't reflect
what packages *need* but rather how we *provide* something. This is
ugly, and creates needless friction between cross and native building.
Now, almost all of these `*Cross` attributes are gone: just these are
kept:
- Glibc's and Musl's are kept, because those packages are widely used
and I didn't want to risk changing the native builds of those at this
time.
- generic `libcCross`, `theadsCross`, and friends, because these relate
to the convolulted GCC bootstrap which still needs to be redone.
The BSD and obscure Linux or freestnanding libcs have conversely all
been made to use a new `stdenvNoLibc`, which is like the old
`crossLibcStdenv` except:
1. It usable for native and cross alike
2. It named according to what it *is* ("a standard environment without
libc but with a C compiler"), rather than some non-compositional
jargon ("the stdenv used for building libc when cross compiling",
yuck).
I should have done this change long ago, but I was stymied because of
"infinite recursions". The problem was that in too many cases we are
overriding `stdenv` to *remove* things we don't need, and this risks
cyles since those more minimal stdenvs are used to build things in the
more maximal stdenvs.
The solution is to pass `stage.nix` `stdenvNoCC`, so we can override to
*build up* rather than *tear down*. For now, the full `stdenv` is also
passed, so I don't need to change the native bootstraps, but I can see
this changing as we make things more uniform and clean those up.
(adapted from commit 51f1ecaa59)
(adapted from commit 1743662e55)
This is the most upstream one, and so to avoid infinite recursion we
should get the things from it. This isn't needed per-se now, but will be
after the next commit.
(cherry picked from commit 4bd76beac0)
For a long time, we've had `crossLibcStdenv`, `*Cross` libc attributes,
and `*bsdCross` pre-libc package sets. This was always bad because
having "cross" things is "not declarative": the naming doesn't reflect
what packages *need* but rather how we *provide* something. This is
ugly, and creates needless friction between cross and native building.
Now, almost all of these `*Cross` attributes are gone: just these are
kept:
- Glibc's and Musl's are kept, because those packages are widely used
and I didn't want to risk changing the native builds of those at this
time.
- generic `libcCross`, `theadsCross`, and friends, because these relate
to the convolulted GCC bootstrap which still needs to be redone.
The BSD and obscure Linux or freestnanding libcs have conversely all
been made to use a new `stdenvNoLibc`, which is like the old
`crossLibcStdenv` except:
1. It usable for native and cross alike
2. It named according to what it *is* ("a standard environment without
libc but with a C compiler"), rather than some non-compositional
jargon ("the stdenv used for building libc when cross compiling",
yuck).
I should have done this change long ago, but I was stymied because of
"infinite recursions". The problem was that in too many cases we are
overriding `stdenv` to *remove* things we don't need, and this risks
cyles since those more minimal stdenvs are used to build things in the
more maximal stdenvs.
The solution is to pass `stage.nix` `stdenvNoCC`, so we can override to
*build up* rather than *tear down*. For now, the full `stdenv` is also
passed, so I don't need to change the native bootstraps, but I can see
this changing as we make things more uniform and clean those up.
Finally, the BSDs also had to be cleaned up, since they have a few
pre-libc dependencies, demanding a systematic approach. I realized what
rhelmot did in 61202561d9 (specify what
packages just need `stdenvNoLibc`) is definitely the right approach for
this, and adjusted NetBSD and OpenBSD to likewise use it.
This is the most upstream one, and so to avoid infinite recursion we
should get the things from it. This isn't needed per-se now, but will be
after the next commit.
The Minimalist Gnu for Windows distribution comes with support for
the traditional msvcrt libc, as well as ucrt64 libc. The latter
being the newer universal compiler runtime. We follow the msys2
environment naming convention[1]:
| name | toolchain | arch | libc | libc++ |
|------------|-----------|---------|--------|-----------|
| mingw32 | gcc | i686 | msvcrt | libstdc++ |
| mingw64 | gcc | x86_64 | msvcrt | libstdc++ |
| ucrt64 | gcc | x86_64 | ucrt | libstdc++ |
| clang32 | llvm | i686 | ucrt | libc++ |
| clang64 | llvm | x86_64 | ucrt | libc++ |
| clangarm64 | llvm | aarch64 | ucrt | libc++ |
For now nixpkgs only supports the first three with this commit.
--
[1]: https://www.msys2.org/docs/environments/
This commit allows `gccCrossStageStatic` to build dynamically-linked
libraries. Since is no longer restricted to building static
libraries its name is no longer appropriate, and this commit also
renames it to the more-accurate `gccWithoutTargetLibc`.
By default, you can't build a gcc that knows how to create dynamic
libraries unless you have already built the targetPlatform libc.
Because of this, our gcc cross-compiler is built in two stages:
1. Build a cross-compiler (gccCrossStageStatic) that can build
only static libraries.
2. Use gccCrossStageStatic to compile the targetPlatform libc.
3. Use the targetPlatform libc to build a fully-capable cross
compiler.
You might notice that this pattern looks very similar to what we do
with `xgcc` in the stdenv bootstrap. Indeed it is! I would like to
work towards getting the existing stdenv bootstrap to handle cross
compilers as well. However we don't want to cripple `stdenv.xgcc`
by taking away its ability to build dynamic libraries.
It turns out that the only thing gcc needs the targetPlatform libc
for is to emit a DT_NEEDED for `-lc` into `libgcc.so`. That's it!
And since we don't use `gccCrossStageStatic` to build anything other
than libc, it's safe to omit the `DT_NEEDED` because that `libgcc`
will never be loaded by anything other than `libc`. So `libc` will
already be in the process's address space.
Other people have noticed this; crosstool-ng has been using this
approach for a very long time:
36ad0b17a7/scripts/build/cc/gcc.sh (L638-L640)
Upstream `gcc-13` merged `mcfgthreads` support with a caveat: it's
headers interface is not compatible with the patch `nixpkgs` was
carrying in `gcc-12` and before.
To keep both new (`gcc13`) and old (`_pre_gcc13`) version I held back
previous `windows.mcfgthreads` attribute as
`windows.mcfgthreads_pre_gcc_13`. It is used for `gcc` before 13.
The change fixes the build of `pkgsCross.mingwW64.stdenv` itself and
example program:
$ nix build --impure --expr 'with import ./. {}; pkgsCross.mingwW64.re2c.override { stdenv = pkgsCross.mingwW64.gcc11Stdenv; }'
Without the change build frequently fails on `gnumake-4.4` as:
x86_64-w64-mingw32-dlltool: cannot delete libmsvcr120d_defs02133.o: No such file or directory
x86_64-w64-mingw32-dlltool: cannot delete libmsvcr120d_defs02134.o: No such file or directory
Pull upstream patches that fix temporary file collisions and add
missing dll dependencies.
With 0507725 "setup-hooks/strip.sh: run RANLIB on static
archives after stripping" it should now be safe to run strip
on wider range of .a files.
mingw-w64 is a good example where a reference was preserved
to gcc from intermediate stage. Enabling stripping by default
decreases `pkgsCross.mingw32` closure for 20%:
Before:
$ nix path-info -rsSh $(nix-build -A pkgsCross.mingw32.stdenv)
...
/nix/store/qzhkidff0wxhqf2gi97ng6qismzvpnbp-stdenv-linux 43.6K 1.0G
After:
$ nix path-info -rsSh $(nix-build -A pkgsCross.mingw32.stdenv)
...
/nix/store/fj4dv1n3sa3jgcb1j3nwn6njsf943n48-stdenv-linux 43.6K 792.4M
This will begin the process of breaking up the `useLLVM` monolith. That
is good in general, but I hope will be good for NetBSD and Darwin in
particular.
Co-authored-by: sterni <sternenseemann@systemli.org>
PR #115603 / 8ad96b7786 introduced a
syntax error by introducing an '' inside an indented string and thus a
syntax error. Was merged despite the failing ofborg check.