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:
36ad0b17a7/scripts/build/cc/gcc.sh (L638-L640)
This commit is contained in:
parent
e41f217257
commit
2affd455a4
@ -66,7 +66,6 @@ let
|
||||
"--disable-threads"
|
||||
"--disable-libgomp"
|
||||
"--disable-libquadmath"
|
||||
"--disable-shared"
|
||||
"--disable-libatomic" # requires libc
|
||||
"--disable-decimal-float" # requires libc
|
||||
"--disable-libmpx" # requires libc
|
||||
|
@ -1,10 +1,13 @@
|
||||
{ lib, version, buildPlatform, hostPlatform, targetPlatform
|
||||
{ lib
|
||||
, stdenv
|
||||
, version, buildPlatform, hostPlatform, targetPlatform
|
||||
, gnat-bootstrap ? null
|
||||
, langAda ? false
|
||||
, langJava ? false
|
||||
, langJit ? false
|
||||
, langGo
|
||||
, crossStageStatic
|
||||
, withoutTargetLibc
|
||||
, enableShared
|
||||
, enableMultilib
|
||||
}:
|
||||
|
||||
@ -109,6 +112,17 @@ in lib.optionalString (hostPlatform.isSunOS && hostPlatform.is64bit) ''
|
||||
export inhibit_libc=true
|
||||
''
|
||||
|
||||
# Trick to build a gcc that is capable of emitting shared libraries *without* having the
|
||||
# targetPlatform libc available beforehand. Taken from:
|
||||
# https://web.archive.org/web/20170222224855/http://frank.harvard.edu/~coldwell/toolchain/
|
||||
# https://web.archive.org/web/20170224235700/http://frank.harvard.edu/~coldwell/toolchain/t-linux.diff
|
||||
+ lib.optionalString (targetPlatform != hostPlatform && withoutTargetLibc && enableShared)
|
||||
(lib.optionalString (!stdenv.targetPlatform.isPower) ''
|
||||
echo 'libgcc.a: crti.o crtn.o' >> libgcc/Makefile.in
|
||||
'' + ''
|
||||
echo 'SHLIB_LC=' >> libgcc/Makefile.in
|
||||
'')
|
||||
|
||||
+ lib.optionalString (!enableMultilib && hostPlatform.is64bit && !hostPlatform.isMips64n32) ''
|
||||
export linkLib64toLib=1
|
||||
''
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -14346,7 +14346,7 @@ with pkgs;
|
||||
xbursttools = callPackage ../tools/misc/xburst-tools {
|
||||
# It needs a cross compiler for mipsel to build the firmware it will
|
||||
# load into the Ben Nanonote
|
||||
gccCross = pkgsCross.ben-nanonote.buildPackages.gccCrossStageStatic;
|
||||
gccCross = pkgsCross.ben-nanonote.buildPackages.gccWithoutTargetLibc;
|
||||
autoconf = buildPackages.autoconf269;
|
||||
};
|
||||
|
||||
@ -15266,7 +15266,7 @@ with pkgs;
|
||||
dontStrip = true;
|
||||
})));
|
||||
|
||||
gccCrossLibcStdenv = overrideCC stdenv buildPackages.gccCrossStageStatic;
|
||||
gccCrossLibcStdenv = overrideCC stdenv buildPackages.gccWithoutTargetLibc;
|
||||
|
||||
crossLibcStdenv =
|
||||
if stdenv.hostPlatform.useLLVM or false || stdenv.hostPlatform.isDarwin
|
||||
@ -15275,7 +15275,7 @@ with pkgs;
|
||||
|
||||
# The GCC used to build libc for the target platform. Normal gccs will be
|
||||
# built with, and use, that cross-compiled libc.
|
||||
gccCrossStageStatic = assert stdenv.targetPlatform != stdenv.hostPlatform; let
|
||||
gccWithoutTargetLibc = assert stdenv.targetPlatform != stdenv.hostPlatform; let
|
||||
libcCross1 = binutilsNoLibc.libc;
|
||||
in wrapCCWith {
|
||||
cc = gccFun {
|
||||
@ -15292,7 +15292,6 @@ with pkgs;
|
||||
langCC = false;
|
||||
libcCross = libcCross1;
|
||||
targetPackages.stdenv.cc.bintools = binutilsNoLibc;
|
||||
enableShared = false;
|
||||
};
|
||||
bintools = binutilsNoLibc;
|
||||
libc = libcCross1;
|
||||
|
Loading…
Reference in New Issue
Block a user