gcc: for cross compilers, don't build libgcc twice
Cross-compiled binaries currently end up with two different libgcc outpaths in their closure. This is harmless, but confusing. The two libgccs are: - One of them is the "first" targetPlatform libgcc, which is built by the "first" cross-compiler. This "first libgcc" and "first compiler" are used to build the targetPlatform glibc. - Once glibc is built, we *rebuild* the cross-compiler, since gcc can't enable most of its features unless you give it an already-compiled targetPlatform glibc. When this "second" compiler is built, it also builds an extra copy of libgcc. This commit discards the second, extra libgcc, and instead puts a reference to the first (correct) libgcc into the "second compiler" `.passthru.libgcc`, so that anybody expecting `stdenv.cc.cc.libgcc` to exist will still find it there. Closes #249680
This commit is contained in:
parent
e6aa338820
commit
aafab3b5b6
|
@ -8,6 +8,7 @@
|
|||
, targetPlatform
|
||||
, hostPlatform
|
||||
, withoutTargetLibc
|
||||
, libcCross
|
||||
}:
|
||||
|
||||
assert !stdenv.targetPlatform.hasSharedLibraries -> !enableShared;
|
||||
|
@ -31,7 +32,7 @@ drv: lib.pipe drv
|
|||
# nixpkgs did not add the "libgcc" output until gcc11. In theory
|
||||
# the following condition can be changed to `true`, but that has not
|
||||
# been tested.
|
||||
lib.optional (lib.versionAtLeast version "11.0")
|
||||
lib.optionals (lib.versionAtLeast version "11.0")
|
||||
|
||||
(let
|
||||
targetPlatformSlash =
|
||||
|
@ -39,11 +40,20 @@ lib.optional (lib.versionAtLeast version "11.0")
|
|||
then ""
|
||||
else "${targetPlatform.config}/";
|
||||
|
||||
# If we are building a cross-compiler and the target libc provided
|
||||
# to us at build time has a libgcc, use that instead of building a
|
||||
# new one. This avoids having two separate (but identical) libgcc
|
||||
# outpaths in the closure of most packages, which can be confusing.
|
||||
useLibgccFromTargetLibc =
|
||||
libcCross != null &&
|
||||
libcCross?passthru.libgcc;
|
||||
|
||||
enableLibGccOutput =
|
||||
(!stdenv.targetPlatform.isWindows || (with stdenv; targetPlatform == hostPlatform)) &&
|
||||
!langJit &&
|
||||
!stdenv.hostPlatform.isDarwin &&
|
||||
enableShared
|
||||
enableShared &&
|
||||
!useLibgccFromTargetLibc
|
||||
;
|
||||
|
||||
# For some reason libgcc_s.so has major-version "2" on m68k but
|
||||
|
@ -54,6 +64,14 @@ lib.optional (lib.versionAtLeast version "11.0")
|
|||
else "1";
|
||||
|
||||
in
|
||||
[
|
||||
|
||||
(pkg: pkg.overrideAttrs (previousAttrs: lib.optionalAttrs useLibgccFromTargetLibc {
|
||||
passthru = (previousAttrs.passthru or {}) // {
|
||||
inherit (libcCross) libgcc;
|
||||
};
|
||||
}))
|
||||
|
||||
(pkg: pkg.overrideAttrs (previousAttrs: lib.optionalAttrs ((!langC) || langJit || enableLibGccOutput) {
|
||||
outputs = previousAttrs.outputs ++ lib.optionals enableLibGccOutput [ "libgcc" ];
|
||||
# This is a separate phase because gcc assembles its phase scripts
|
||||
|
@ -143,5 +161,4 @@ in
|
|||
+ ''
|
||||
patchelf --set-rpath "" $libgcc/lib/libgcc_s.so.${libgcc_s-version-major}
|
||||
'');
|
||||
}))))
|
||||
|
||||
}))]))
|
||||
|
|
|
@ -450,7 +450,7 @@ ${""} done
|
|||
}
|
||||
))
|
||||
([
|
||||
(callPackage ./common/libgcc.nix { inherit version langC langCC langJit targetPlatform hostPlatform withoutTargetLibc enableShared; })
|
||||
(callPackage ./common/libgcc.nix { inherit version langC langCC langJit targetPlatform hostPlatform withoutTargetLibc enableShared libcCross; })
|
||||
] ++ optionals atLeast11 [
|
||||
(callPackage ./common/checksum.nix { inherit langC langCC; })
|
||||
])
|
||||
|
|
Loading…
Reference in a new issue