Merge pull request #247900 from amjoseph-nixpkgs/pr/stdenv/libgcc-no-more-cycles
glibcCross: use a libgcc built separately from gcc
This commit is contained in:
commit
0dfed0d79b
9 changed files with 207 additions and 49 deletions
|
@ -3,7 +3,13 @@
|
|||
, enableMultilib
|
||||
}:
|
||||
|
||||
let
|
||||
forceLibgccToBuildCrtStuff =
|
||||
import ./libgcc-buildstuff.nix { inherit lib stdenv; };
|
||||
in
|
||||
|
||||
originalAttrs: (stdenv.mkDerivation (finalAttrs: originalAttrs // {
|
||||
passthru = (originalAttrs.passthru or {}) // { inherit forceLibgccToBuildCrtStuff; };
|
||||
preUnpack = ''
|
||||
oldOpts="$(shopt -po nounset)" || true
|
||||
set -euo pipefail
|
||||
|
|
37
pkgs/development/compilers/gcc/common/libgcc-buildstuff.nix
Normal file
37
pkgs/development/compilers/gcc/common/libgcc-buildstuff.nix
Normal file
|
@ -0,0 +1,37 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
}:
|
||||
|
||||
# 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
|
||||
let
|
||||
# crt{i,n}.o are the first and last (respectively) object file
|
||||
# linked when producing an executable. Traditionally these
|
||||
# files are delivered as part of the C library, but on GNU
|
||||
# systems they are in fact built by GCC. Since libgcc needs to
|
||||
# build before glibc, we can't wait for them to be copied by
|
||||
# glibc. At this early pre-glibc stage these files sometimes
|
||||
# have different names.
|
||||
crtstuff-ofiles =
|
||||
if stdenv.targetPlatform.isPower
|
||||
then "ecrti.o ecrtn.o ncrti.o ncrtn.o"
|
||||
else "crti.o crtn.o";
|
||||
|
||||
# Normally, `SHLIB_LC` is set to `-lc`, which means that
|
||||
# `libgcc_s.so` cannot be built until `libc.so` is available.
|
||||
# The assignment below clobbers this variable, removing the
|
||||
# `-lc`.
|
||||
#
|
||||
# On PowerPC we add `-mnewlib`, which means "libc has not been
|
||||
# built yet". This causes libgcc's Makefile to use the
|
||||
# gcc-built `{e,n}crt{n,i}.o` instead of failing to find the
|
||||
# versions which have been repackaged in libc as `crt{n,i}.o`
|
||||
#
|
||||
SHLIB_LC = lib.optionalString stdenv.targetPlatform.isPower "-mnewlib";
|
||||
|
||||
in ''
|
||||
echo 'libgcc.a: ${crtstuff-ofiles}' >> libgcc/Makefile.in
|
||||
echo 'SHLIB_LC=${SHLIB_LC}' >> libgcc/Makefile.in
|
||||
''
|
|
@ -44,14 +44,14 @@ lib.optional (lib.versionAtLeast version "11.0")
|
|||
!langJit &&
|
||||
!stdenv.hostPlatform.isDarwin &&
|
||||
enableShared
|
||||
;
|
||||
;
|
||||
|
||||
# For some reason libgcc_s.so has major-version "2" on m68k but
|
||||
# "1" everywhere else. Might be worth changing this to "*".
|
||||
libgcc_s-version-major =
|
||||
if targetPlatform.isM68k
|
||||
then "2"
|
||||
else "1";
|
||||
# For some reason libgcc_s.so has major-version "2" on m68k but
|
||||
# "1" everywhere else. Might be worth changing this to "*".
|
||||
libgcc_s-version-major =
|
||||
if targetPlatform.isM68k
|
||||
then "2"
|
||||
else "1";
|
||||
|
||||
in
|
||||
(pkg: pkg.overrideAttrs (previousAttrs: lib.optionalAttrs ((!langC) || langJit || enableLibGccOutput) {
|
||||
|
|
|
@ -112,39 +112,5 @@ 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)
|
||||
(let
|
||||
|
||||
# crt{i,n}.o are the first and last (respectively) object file
|
||||
# linked when producing an executable. Traditionally these
|
||||
# files are delivered as part of the C library, but on GNU
|
||||
# systems they are in fact built by GCC. Since libgcc needs to
|
||||
# build before glibc, we can't wait for them to be copied by
|
||||
# glibc. At this early pre-glibc stage these files sometimes
|
||||
# have different names.
|
||||
crtstuff-ofiles =
|
||||
if targetPlatform.isPower
|
||||
then "ecrti.o ecrtn.o ncrti.o ncrtn.o"
|
||||
else "crti.o crtn.o";
|
||||
|
||||
# Normally, `SHLIB_LC` is set to `-lc`, which means that
|
||||
# `libgcc_s.so` cannot be built until `libc.so` is available.
|
||||
# The assignment below clobbers this variable, removing the
|
||||
# `-lc`.
|
||||
#
|
||||
# On PowerPC we add `-mnewlib`, which means "libc has not been
|
||||
# built yet". This causes libgcc's Makefile to use the
|
||||
# gcc-built `{e,n}crt{n,i}.o` instead of failing to find the
|
||||
# versions which have been repackaged in libc as `crt{n,i}.o`
|
||||
#
|
||||
SHLIB_LC = lib.optionalString targetPlatform.isPower "-mnewlib";
|
||||
|
||||
in ''
|
||||
echo 'libgcc.a: ${crtstuff-ofiles}' >> libgcc/Makefile.in
|
||||
echo 'SHLIB_LC=${SHLIB_LC}' >> libgcc/Makefile.in
|
||||
'')
|
||||
|
||||
(import ./libgcc-buildstuff.nix { inherit lib stdenv; })
|
||||
|
|
140
pkgs/development/libraries/gcc/libgcc/default.nix
Normal file
140
pkgs/development/libraries/gcc/libgcc/default.nix
Normal file
|
@ -0,0 +1,140 @@
|
|||
{ lib, stdenvNoLibs, buildPackages
|
||||
, gcc, glibc
|
||||
, libiberty
|
||||
}:
|
||||
|
||||
let
|
||||
stdenv = stdenvNoLibs;
|
||||
gccConfigureFlags = gcc.cc.configureFlags ++ [
|
||||
"--disable-fixincludes"
|
||||
"--disable-intl"
|
||||
"--enable-threads=posix"
|
||||
"--with-glibc-version=${glibc.version}"
|
||||
|
||||
# these are required in order to prevent inhibit_libc=true,
|
||||
# which will cripple libgcc's unwinder; see:
|
||||
# https://github.com/NixOS/nixpkgs/issues/213453#issuecomment-1616346163
|
||||
"--with-headers=${lib.getDev glibc}/include"
|
||||
"--with-native-system-header-dir=${lib.getDev glibc}${glibc.incdir or "/include"}"
|
||||
"--with-build-sysroot=/"
|
||||
];
|
||||
|
||||
in stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "libgcc";
|
||||
inherit (gcc.cc) src version;
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
strictDeps = true;
|
||||
depsBuildBuild = [ buildPackages.stdenv.cc ];
|
||||
nativeBuildInputs = [ libiberty ];
|
||||
buildInputs = [ glibc ];
|
||||
|
||||
postUnpack = ''
|
||||
mkdir -p ./build
|
||||
buildRoot=$(readlink -e "./build")
|
||||
'';
|
||||
|
||||
postPatch =
|
||||
gcc.cc.passthru.forceLibgccToBuildCrtStuff
|
||||
+ ''
|
||||
sourceRoot=$(readlink -e "./libgcc")
|
||||
'';
|
||||
|
||||
hardeningDisable = [ "pie" ];
|
||||
|
||||
preConfigure =
|
||||
''
|
||||
# Drop in libiberty, as external builds are not expected
|
||||
cd "$buildRoot"
|
||||
(
|
||||
mkdir -p build-${stdenv.buildPlatform.config}/libiberty/
|
||||
cd build-${stdenv.buildPlatform.config}/libiberty/
|
||||
ln -s ${buildPackages.libiberty}/lib/libiberty.a ./
|
||||
)
|
||||
mkdir -p "$buildRoot/gcc"
|
||||
cd "$buildRoot/gcc"
|
||||
(
|
||||
# We "shift" the tools over to fake platforms perspective from the previous stage.
|
||||
export AS_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$AS_FOR_BUILD
|
||||
export CC_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CC_FOR_BUILD
|
||||
export CPP_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CPP_FOR_BUILD
|
||||
export CXX_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CXX_FOR_BUILD
|
||||
export LD_FOR_BUILD=${buildPackages.stdenv.cc.bintools}/bin/$LD_FOR_BUILD
|
||||
|
||||
export AS=$AS_FOR_BUILD
|
||||
export CC=$CC_FOR_BUILD
|
||||
export CPP=$CPP_FOR_BUILD
|
||||
export CXX=$CXX_FOR_BUILD
|
||||
export LD=$LD_FOR_BUILD
|
||||
|
||||
export AS_FOR_TARGET=${stdenv.cc}/bin/$AS
|
||||
export CC_FOR_TARGET=${stdenv.cc}/bin/$CC
|
||||
export CPP_FOR_TARGET=${stdenv.cc}/bin/$CPP
|
||||
export LD_FOR_TARGET=${stdenv.cc.bintools}/bin/$LD
|
||||
|
||||
# We define GENERATOR_FILE so nothing bothers looking for GNU GMP.
|
||||
export NIX_CFLAGS_COMPILE_FOR_BUILD+=' -DGENERATOR_FILE=1'
|
||||
|
||||
"$sourceRoot/../gcc/configure" ${lib.concatStringsSep " " gccConfigureFlags}
|
||||
|
||||
# We remove the `libgcc.mvar` deps so that the bootstrap xgcc isn't built.
|
||||
sed -e 's,libgcc.mvars:.*$,libgcc.mvars:,' -i Makefile
|
||||
|
||||
make \
|
||||
config.h \
|
||||
libgcc.mvars \
|
||||
tconfig.h \
|
||||
tm.h \
|
||||
options.h \
|
||||
insn-constants.h \
|
||||
'' + lib.optionalString stdenv.targetPlatform.isM68k ''
|
||||
sysroot-suffix.h \
|
||||
'' + lib.optionalString stdenv.targetPlatform.isArmv7 ''
|
||||
arm-isa.h \
|
||||
arm-cpu.h \
|
||||
'' + ''
|
||||
insn-modes.h
|
||||
)
|
||||
mkdir -p "$buildRoot/gcc/include"
|
||||
|
||||
# Preparing to configure + build libgcc itself
|
||||
mkdir -p "$buildRoot/gcc/${stdenv.hostPlatform.config}/libgcc"
|
||||
cd "$buildRoot/gcc/${stdenv.hostPlatform.config}/libgcc"
|
||||
configureScript=$sourceRoot/configure
|
||||
chmod +x "$configureScript"
|
||||
|
||||
export AS_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$AS_FOR_BUILD
|
||||
export CC_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CC_FOR_BUILD
|
||||
export CPP_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CPP_FOR_BUILD
|
||||
export CXX_FOR_BUILD=${buildPackages.stdenv.cc}/bin/$CXX_FOR_BUILD
|
||||
export LD_FOR_BUILD=${buildPackages.stdenv.cc.bintools}/bin/$LD_FOR_BUILD
|
||||
|
||||
export AS=${stdenv.cc}/bin/$AS
|
||||
export CC=${stdenv.cc}/bin/$CC
|
||||
export CPP=${stdenv.cc}/bin/$CPP
|
||||
export CXX=${stdenv.cc}/bin/$CXX
|
||||
export LD=${stdenv.cc.bintools}/bin/$LD
|
||||
|
||||
export AS_FOR_TARGET=${stdenv.cc}/bin/$AS_FOR_TARGET
|
||||
export CC_FOR_TARGET=${stdenv.cc}/bin/$CC_FOR_TARGET
|
||||
export CPP_FOR_TARGET=${stdenv.cc}/bin/$CPP_FOR_TARGET
|
||||
export LD_FOR_TARGET=${stdenv.cc.bintools}/bin/$LD_FOR_TARGET
|
||||
'';
|
||||
|
||||
configurePlatforms = [ "build" "host" ];
|
||||
configureFlags = [
|
||||
"cross_compiling=true"
|
||||
"--disable-gcov"
|
||||
"--with-glibc-version=${glibc.version}"
|
||||
];
|
||||
|
||||
makeFlags = [ "MULTIBUILDTOP:=../" ];
|
||||
|
||||
postInstall = ''
|
||||
moveToOutput "lib/gcc/${stdenv.hostPlatform.config}/${finalAttrs.version}/include" "$dev"
|
||||
mkdir -p "$out/lib" "$dev/include"
|
||||
ln -s "$out/lib/gcc/${stdenv.hostPlatform.config}/${finalAttrs.version}"/* "$out/lib"
|
||||
ln -s "$dev/lib/gcc/${stdenv.hostPlatform.config}/${finalAttrs.version}/include"/* "$dev/include/"
|
||||
'';
|
||||
})
|
|
@ -4,6 +4,7 @@
|
|||
, withGd ? false
|
||||
, withLibcrypt? false
|
||||
, buildPackages
|
||||
, libgcc
|
||||
}:
|
||||
|
||||
let
|
||||
|
@ -16,7 +17,7 @@ in
|
|||
|
||||
(callPackage ./common.nix { inherit stdenv; } {
|
||||
inherit withLinuxHeaders withGd profilingLibraries withLibcrypt;
|
||||
pname = "glibc" + lib.optionalString withGd "-gd";
|
||||
pname = "glibc" + lib.optionalString withGd "-gd" + lib.optionalString (stdenv.cc.isGNU && libgcc==null) "-nolibgcc";
|
||||
}).overrideAttrs(previousAttrs: {
|
||||
|
||||
# Note:
|
||||
|
@ -90,8 +91,8 @@ in
|
|||
#
|
||||
makeFlags =
|
||||
(previousAttrs.makeFlags or [])
|
||||
++ lib.optionals (stdenv.cc.cc?libgcc) [
|
||||
"user-defined-trusted-dirs=${stdenv.cc.cc.libgcc}/lib"
|
||||
++ lib.optionals (libgcc != null) [
|
||||
"user-defined-trusted-dirs=${libgcc}/lib"
|
||||
];
|
||||
|
||||
postInstall = previousAttrs.postInstall + (if stdenv.hostPlatform == stdenv.buildPlatform then ''
|
||||
|
@ -166,8 +167,8 @@ in
|
|||
|
||||
passthru =
|
||||
(previousAttrs.passthru or {})
|
||||
// lib.optionalAttrs (stdenv.cc.cc?libgcc) {
|
||||
inherit (stdenv.cc.cc) libgcc;
|
||||
// lib.optionalAttrs (libgcc != null) {
|
||||
inherit libgcc;
|
||||
};
|
||||
|
||||
meta = (previousAttrs.meta or {}) // { description = "The GNU C Library"; };
|
||||
|
|
|
@ -115,6 +115,7 @@ let
|
|||
in
|
||||
pkgs.runCommand "test-mbuffer" {} ''
|
||||
echo hello | ${emulator} ${mbuffer}/bin/mbuffer
|
||||
touch $out
|
||||
'';
|
||||
|
||||
# This is meant to be a carefully curated list of builds/packages
|
||||
|
@ -127,13 +128,14 @@ let
|
|||
# of things that often break. So, no buckshot `mapTestOnCross`
|
||||
# calls here.
|
||||
sanity = [
|
||||
#pkgs.mbuffer # https://github.com/NixOS/nixpkgs/issues/213453
|
||||
mbuffer
|
||||
#pkgs.pkgsCross.gnu64.bash # https://github.com/NixOS/nixpkgs/issues/243164
|
||||
pkgs.gcc_multi.cc
|
||||
pkgs.pkgsMusl.stdenv
|
||||
pkgs.pkgsLLVM.stdenv
|
||||
pkgs.pkgsStatic.bash
|
||||
pkgs.pkgsCross.arm-embedded.stdenv
|
||||
pkgs.pkgsCross.armv7l-hf-multiplatform.stdenv
|
||||
pkgs.pkgsCross.m68k.stdenv
|
||||
pkgs.pkgsCross.aarch64-multiplatform.pkgsBuildTarget.gcc
|
||||
pkgs.pkgsCross.powernv.pkgsBuildTarget.gcc
|
||||
|
|
|
@ -879,7 +879,6 @@ mapAliases ({
|
|||
liberation_ttf_v1_from_source = throw "'liberation_ttf_v1_from_source' has been renamed to/replaced by 'liberation_ttf_v1'"; # Converted to throw 2022-02-22
|
||||
liberation_ttf_v2_from_source = throw "'liberation_ttf_v2_from_source' has been renamed to/replaced by 'liberation_ttf_v2'"; # Converted to throw 2022-02-22
|
||||
liberationsansnarrow = throw "'liberationsansnarrow' has been renamed to/replaced by 'liberation-sans-narrow'"; # Converted to throw 2022-02-22
|
||||
libgcc = throw "libgcc was removed, use gcc.cc.libgcc if needed"; # added 2023-05-13
|
||||
libgksu = throw "libgksu has been removed"; # Added 2022-01-16
|
||||
libgme = game-music-emu; # Added 2022-07-20
|
||||
libgnome_keyring = throw "'libgnome_keyring' has been renamed to/replaced by 'libgnome-keyring'"; # Converted to throw 2022-02-22
|
||||
|
|
|
@ -18918,6 +18918,8 @@ with pkgs;
|
|||
|
||||
librarian-puppet-go = callPackage ../development/tools/librarian-puppet-go { };
|
||||
|
||||
libgcc = stdenv.cc.cc.libgcc or null;
|
||||
|
||||
# This is for e.g. LLVM libraries on linux.
|
||||
gccForLibs =
|
||||
if stdenv.targetPlatform == stdenv.hostPlatform && targetPackages.stdenv.cc.isGNU
|
||||
|
@ -21444,6 +21446,11 @@ with pkgs;
|
|||
# Being redundant to avoid cycles on boot. TODO: find a better way
|
||||
glibcCross = callPackage ../development/libraries/glibc {
|
||||
stdenv = gccCrossLibcStdenv; # doesn't compile without gcc
|
||||
libgcc = callPackage ../development/libraries/gcc/libgcc {
|
||||
gcc = gccCrossLibcStdenv.cc;
|
||||
glibc = glibcCross.override { libgcc = null; };
|
||||
stdenvNoLibs = gccCrossLibcStdenv;
|
||||
};
|
||||
};
|
||||
|
||||
muslCross = musl.override {
|
||||
|
|
Loading…
Reference in a new issue