summary refs log tree commit diff
path: root/pkgs/os-specific/windows/default.nix
diff options
context:
space:
mode:
authorAdam Joseph <adam@westernsemico.com>2023-06-16 14:15:36 -0700
committerAdam Joseph <adam@westernsemico.com>2023-07-01 13:12:40 -0700
commit2affd455a40a28825f356307ce5bd8fa2f202217 (patch)
tree0413358466c30cebcb81c930dce9fb175008fac6 /pkgs/os-specific/windows/default.nix
parente41f217257cf34d1328cad141cfb01c6f8093b37 (diff)
downloadnixpkgs-2affd455a40a28825f356307ce5bd8fa2f202217.tar
nixpkgs-2affd455a40a28825f356307ce5bd8fa2f202217.tar.gz
nixpkgs-2affd455a40a28825f356307ce5bd8fa2f202217.tar.bz2
nixpkgs-2affd455a40a28825f356307ce5bd8fa2f202217.tar.lz
nixpkgs-2affd455a40a28825f356307ce5bd8fa2f202217.tar.xz
nixpkgs-2affd455a40a28825f356307ce5bd8fa2f202217.tar.zst
nixpkgs-2affd455a40a28825f356307ce5bd8fa2f202217.zip
gccCrossStageStatic: enable dynamic libraries, rename to gccWithoutTargetLibc
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:

  https://github.com/crosstool-ng/crosstool-ng/blob/36ad0b17a732aaffe4701d5d8d410d6e3e3abba9/scripts/build/cc/gcc.sh#L638-L640
Diffstat (limited to 'pkgs/os-specific/windows/default.nix')
-rw-r--r--pkgs/os-specific/windows/default.nix2
1 files changed, 1 insertions, 1 deletions
diff --git a/pkgs/os-specific/windows/default.nix b/pkgs/os-specific/windows/default.nix
index 8d6dd50548e..12859de8a20 100644
--- a/pkgs/os-specific/windows/default.nix
+++ b/pkgs/os-specific/windows/default.nix
@@ -20,7 +20,7 @@ lib.makeScope newScope (self: with self; {
   crossThreadsStdenv = overrideCC crossLibcStdenv
     (if stdenv.hostPlatform.useLLVM or false
      then buildPackages.llvmPackages_8.clangNoLibcxx
-     else buildPackages.gccCrossStageStatic.override (old: {
+     else buildPackages.gccWithoutTargetLibc.override (old: {
        bintools = old.bintools.override {
          libc = libcCross;
        };