gcc: pass result of lib.systems.equals around rather than recomputing (#516034)

This commit is contained in:
Emily
2026-05-12 01:38:50 +00:00
committed by GitHub
10 changed files with 81 additions and 109 deletions
+10 -18
View File
@@ -9,10 +9,13 @@
isl_0_20,
noSysDirs,
wrapCC,
}@args:
}:
let
versions = import ./versions.nix;
buildIsHost = lib.systems.equals stdenv.buildPlatform stdenv.hostPlatform;
buildIsTarget = lib.systems.equals stdenv.buildPlatform stdenv.targetPlatform;
hostIsTarget = lib.systems.equals stdenv.hostPlatform stdenv.targetPlatform;
gccForMajorMinorVersion =
majorMinorVersion:
let
@@ -24,18 +27,13 @@ let
callPackage ./default.nix {
inherit noSysDirs;
inherit majorMinorVersion;
_systemInfo = {
inherit buildIsHost hostIsTarget;
};
reproducibleBuild = true;
profiledCompiler = false;
libcCross =
if !lib.systems.equals stdenv.targetPlatform stdenv.buildPlatform then
targetPackages.libc or pkgs.libc
else
null;
threadsCross =
if !lib.systems.equals stdenv.targetPlatform stdenv.buildPlatform then
targetPackages.threads or pkgs.threads
else
{ };
libcCross = if !buildIsTarget then targetPackages.libc or pkgs.libc else null;
threadsCross = if !buildIsTarget then targetPackages.threads or pkgs.threads else { };
isl = if stdenv.hostPlatform.isDarwin then null else isl_0_20;
# do not allow version skew when cross-building gcc
#
@@ -56,13 +54,7 @@ let
# Let's fix both problems by requiring the same compiler version for
# cross-case.
stdenv =
if
(
(!lib.systems.equals stdenv.targetPlatform stdenv.buildPlatform)
|| (!lib.systems.equals stdenv.hostPlatform stdenv.targetPlatform)
)
&& stdenv.cc.isGNU
then
if (!buildIsTarget || !hostIsTarget) && stdenv.cc.isGNU then
overrideCC stdenv buildPackages."gcc${majorVersion}"
else
stdenv;
@@ -3,11 +3,12 @@
stdenv,
enableMultilib,
targetConfig,
hostIsTarget,
}:
let
forceLibgccToBuildCrtStuff = import ./libgcc-buildstuff.nix { inherit lib stdenv; };
isCross = !lib.systems.equals stdenv.targetPlatform stdenv.hostPlatform;
isCross = !hostIsTarget;
in
# We don't support multilib and cross at the same time
@@ -5,17 +5,12 @@
langC,
langCC,
runtimeShell,
buildIsHost,
hostIsTarget,
}:
let
enableChecksum =
(
with stdenv;
lib.systems.equals buildPlatform hostPlatform && lib.systems.equals hostPlatform targetPlatform
)
&& langC
&& langCC
&& !stdenv.hostPlatform.isDarwin;
enableChecksum = buildIsHost && hostIsTarget && langC && langCC && !stdenv.hostPlatform.isDarwin;
in
(
pkg:
@@ -32,7 +32,8 @@
langObjCpp,
langJit,
langRust ? false,
disableBootstrap ? (!lib.systems.equals stdenv.targetPlatform stdenv.hostPlatform),
hostIsTarget,
disableBootstrap ? (!hostIsTarget),
}:
assert !enablePlugin -> disableGdbPlugin;
@@ -48,7 +49,6 @@ assert !enablePlugin -> disableGdbPlugin;
let
inherit (stdenv)
buildPlatform
hostPlatform
targetPlatform
;
@@ -56,9 +56,8 @@ let
# See https://github.com/NixOS/nixpkgs/pull/209870#issuecomment-1500550903
disableBootstrap' = disableBootstrap && !langFortran && !langGo;
crossMingw = (!lib.systems.equals targetPlatform hostPlatform) && targetPlatform.isMinGW;
crossDarwin =
(!lib.systems.equals targetPlatform hostPlatform) && targetPlatform.libc == "libSystem";
crossMingw = !hostIsTarget && targetPlatform.isMinGW;
crossDarwin = !hostIsTarget && targetPlatform.libc == "libSystem";
crossConfigureFlags =
# Ensure that -print-prog-name is able to find the correct programs.
@@ -247,20 +246,18 @@ let
++ lib.optional (isl != null) "--with-isl=${isl}"
# Ada options, gcc can't build the runtime library for a cross compiler
++ lib.optional langAda (
if lib.systems.equals hostPlatform targetPlatform then "--enable-libada" else "--disable-libada"
)
++ lib.optional langAda (if hostIsTarget then "--enable-libada" else "--disable-libada")
++ import ../common/platform-flags.nix {
inherit (stdenv) targetPlatform;
inherit lib;
}
++ lib.optionals (!lib.systems.equals targetPlatform hostPlatform) crossConfigureFlags
++ lib.optionals (!hostIsTarget) crossConfigureFlags
++ lib.optional disableBootstrap' "--disable-bootstrap"
# Platform-specific flags
++ lib.optional (
lib.systems.equals targetPlatform hostPlatform && targetPlatform.isx86_32
hostIsTarget && targetPlatform.isx86_32
) "--with-arch=${stdenv.hostPlatform.parsed.cpu.name}"
++ lib.optional (targetPlatform.isNetBSD || targetPlatform.isCygwin) "--disable-libssp" # Provided by libc.
++ lib.optionals hostPlatform.isSunOS [
@@ -277,7 +274,7 @@ let
lib.optional (targetPlatform.libc == "musl")
# musl at least, disable: https://git.buildroot.net/buildroot/commit/?id=873d4019f7fb00f6a80592224236b3ba7d657865
"--disable-libmpx"
++ lib.optionals (lib.systems.equals targetPlatform hostPlatform && targetPlatform.libc == "musl") [
++ lib.optionals (hostIsTarget && targetPlatform.libc == "musl") [
"--disable-libsanitizer"
"--disable-symvers"
"libat_cv_have_ifunc=no"
@@ -27,11 +27,13 @@
cargo,
withoutTargetLibc ? null,
threadsCross ? null,
buildIsHost,
hostIsTarget,
}:
let
inherit (lib) optionals;
inherit (stdenv) buildPlatform hostPlatform targetPlatform;
inherit (stdenv) buildPlatform targetPlatform;
in
{
@@ -56,12 +58,12 @@ in
# same for all gcc's
depsBuildTarget =
(
if lib.systems.equals hostPlatform buildPlatform then
if buildIsHost then
[
targetPackages.stdenv.cc.bintools # newly-built gcc will be used
]
else
assert lib.systems.equals targetPlatform hostPlatform;
assert hostIsTarget;
[
# build != host == target
stdenv.cc
@@ -4,12 +4,9 @@
withoutTargetLibc,
libcCross,
threadsCross,
hostIsTarget,
}:
let
inherit (stdenv) hostPlatform targetPlatform;
in
{
# For non-cross builds these flags are currently assigned in builder.sh.
# It would be good to consolidate the generation of makeFlags
@@ -18,7 +15,7 @@ in
let
mkFlags =
dep:
lib.optionals ((!lib.systems.equals targetPlatform hostPlatform) && dep != null) (
lib.optionals (!hostIsTarget && dep != null) (
[
"-O2 -idirafter ${lib.getDev dep}${dep.incdir or "/include"}"
]
@@ -35,7 +32,7 @@ in
let
mkFlags =
dep:
lib.optionals ((!lib.systems.equals targetPlatform hostPlatform) && dep != null) (
lib.optionals (!hostIsTarget && dep != null) (
[
"-Wl,-L${lib.getLib dep}${dep.libdir or "/lib"}"
]
@@ -10,6 +10,7 @@
hostPlatform,
withoutTargetLibc,
libcCross,
hostIsTarget,
}:
assert !stdenv.targetPlatform.hasSharedLibraries -> !enableShared;
@@ -24,27 +25,20 @@ lib.pipe drv
pkg:
pkg.overrideAttrs (
previousAttrs:
lib.optionalAttrs
(
(!lib.systems.equals targetPlatform hostPlatform)
&& (enableShared || targetPlatform.isMinGW)
&& withoutTargetLibc
)
{
makeFlags = [
"all-gcc"
"all-target-libgcc"
];
installTargets = "install-gcc install-target-libgcc";
}
lib.optionalAttrs (!hostIsTarget && (enableShared || targetPlatform.isMinGW) && withoutTargetLibc) {
makeFlags = [
"all-gcc"
"all-target-libgcc"
];
installTargets = "install-gcc install-target-libgcc";
}
)
)
]
++ (
let
targetPlatformSlash =
if lib.systems.equals hostPlatform targetPlatform then "" else "${targetPlatform.config}/";
targetPlatformSlash = if hostIsTarget 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
@@ -14,6 +14,8 @@
enableShared,
enableMultilib,
pkgsBuildTarget,
buildIsHost,
hostIsTarget,
}:
assert langAda -> gnat-bootstrap != null;
@@ -39,7 +41,7 @@ lib.optionalString (hostPlatform.isSunOS && hostPlatform.is64bit) ''
langFortran
&& (
(!lib.systems.equals buildPlatform hostPlatform) && (lib.systems.equals hostPlatform targetPlatform)
!buildIsHost && hostIsTarget
)
)
''
@@ -57,12 +59,9 @@ lib.optionalString (hostPlatform.isSunOS && hostPlatform.is64bit) ''
# HACK: if host and target config are the same, but the platforms are
# actually different we need to convince the configure script that it
# is in fact building a cross compiler although it doesn't believe it.
+
lib.optionalString
(targetPlatform.config == hostPlatform.config && (!lib.systems.equals targetPlatform hostPlatform))
''
substituteInPlace configure --replace is_cross_compiler=no is_cross_compiler=yes
''
+ lib.optionalString (targetPlatform.config == hostPlatform.config && !hostIsTarget) ''
substituteInPlace configure --replace is_cross_compiler=no is_cross_compiler=yes
''
# Normally (for host != target case) --without-headers automatically
# enables 'inhibit_libc=true' in gcc's gcc/configure.ac. But case of
@@ -71,11 +70,7 @@ lib.optionalString (hostPlatform.isSunOS && hostPlatform.is64bit) ''
# We explicitly inhibit libc headers use in this case as well.
+
lib.optionalString
(
(!lib.systems.equals targetPlatform hostPlatform)
&& withoutTargetLibc
&& targetPlatform.config == hostPlatform.config
)
(!hostIsTarget && withoutTargetLibc && targetPlatform.config == hostPlatform.config)
''
export inhibit_libc=true
''
@@ -93,6 +88,6 @@ lib.optionalString (hostPlatform.isSunOS && hostPlatform.is64bit) ''
done
''
+ lib.optionalString (
(!lib.systems.equals targetPlatform hostPlatform) && withoutTargetLibc && enableShared
) (import ./libgcc-buildstuff.nix { inherit lib stdenv; })
+ lib.optionalString (!hostIsTarget && withoutTargetLibc && enableShared) (
import ./libgcc-buildstuff.nix { inherit lib stdenv; }
)
+28 -28
View File
@@ -35,8 +35,14 @@
zlib ? null,
libucontext ? null,
gnat-bootstrap ? null,
# Allows only computing system equality once across every file responsible for
# building gcc. Not part of the public API
_systemInfo ? {
buildIsHost = lib.systems.equals stdenv.buildPlatform stdenv.hostPlatform;
hostIsTarget = lib.systems.equals stdenv.hostPlatform stdenv.targetPlatform;
},
enableMultilib ? false,
enablePlugin ? (lib.systems.equals stdenv.hostPlatform stdenv.buildPlatform), # Whether to support user-supplied plug-ins
enablePlugin ? _systemInfo.buildIsHost, # Whether to support user-supplied plug-ins
name ? "gcc",
libcCross ? null,
threadsCross ? { }, # for MinGW
@@ -59,9 +65,6 @@
let
inherit (lib)
callPackageWith
filter
getBin
maintainers
makeLibraryPath
makeSearchPathOutput
mapAttrs
@@ -70,17 +73,15 @@ let
optionals
optionalString
pipe
platforms
versionAtLeast
versions
;
inherit (_systemInfo) buildIsHost hostIsTarget;
gccVersions = import ./versions.nix;
version = gccVersions.fromMajorMinor majorMinorVersion;
majorVersion = versions.major version;
atLeast14 = versionAtLeast version "14";
is14 = majorVersion == "14";
is13 = majorVersion == "13";
# releases have a form: MAJOR.MINOR.MICRO, like 14.2.1
@@ -98,21 +99,16 @@ let
disableBootstrap = !stdenv.hostPlatform.isDarwin && !profiledCompiler;
inherit (stdenv) buildPlatform hostPlatform targetPlatform;
targetConfig =
if (!lib.systems.equals targetPlatform hostPlatform) then targetPlatform.config else null;
targetConfig = if (!hostIsTarget) then targetPlatform.config else null;
patches = callFile ./patches { };
# Cross-gcc settings (build == host != target)
crossMingw = (!lib.systems.equals targetPlatform hostPlatform) && targetPlatform.isMinGW;
crossMingw = (!hostIsTarget) && targetPlatform.isMinGW;
stageNameAddon = optionalString withoutTargetLibc "-nolibc";
crossNameAddon = optionalString (
!lib.systems.equals targetPlatform hostPlatform
) "${targetPlatform.config}${stageNameAddon}-";
crossNameAddon = optionalString (!hostIsTarget) "${targetPlatform.config}${stageNameAddon}-";
targetPrefix = lib.optionalString (
!lib.systems.equals stdenv.targetPlatform stdenv.hostPlatform
) "${stdenv.targetPlatform.config}-";
targetPrefix = lib.optionalString (!hostIsTarget) "${stdenv.targetPlatform.config}-";
callFile = callPackageWith {
# lets
@@ -184,6 +180,8 @@ let
which
zlib
;
inherit buildIsHost hostIsTarget;
};
in
@@ -267,7 +265,7 @@ pipe
substituteInPlace libgfortran/configure \
--replace "-install_name \\\$rpath/\\\$soname" "-install_name ''${!outputLib}/lib/\\\$soname"
''
+ (optionalString ((!lib.systems.equals targetPlatform hostPlatform) || stdenv.cc.libc != null)
+ (optionalString ((!hostIsTarget) || stdenv.cc.libc != null)
# On NixOS, use the right path to the dynamic linker instead of
# `/lib/ld*.so'.
(
@@ -337,11 +335,7 @@ pipe
let
target =
optionalString profiledCompiler "profiled"
+ optionalString (
(lib.systems.equals targetPlatform hostPlatform)
&& (lib.systems.equals hostPlatform buildPlatform)
&& !disableBootstrap
) "bootstrap";
+ optionalString (hostIsTarget && buildIsHost && !disableBootstrap) "bootstrap";
in
optional (target != "") target;
@@ -371,13 +365,11 @@ pipe
# compiler (after the specs for the cross-gcc are created). Having
# LIBRARY_PATH= makes gcc read the specs from ., and the build breaks.
CPATH = optionals (lib.systems.equals targetPlatform hostPlatform) (
CPATH = optionals hostIsTarget (
makeSearchPathOutput "dev" "include" ([ ] ++ optional (zlib != null) zlib)
);
LIBRARY_PATH = optionals (lib.systems.equals targetPlatform hostPlatform) (
makeLibraryPath (optional (zlib != null) zlib)
);
LIBRARY_PATH = optionals hostIsTarget (makeLibraryPath (optional (zlib != null) zlib));
NIX_LDFLAGS = optionalString hostPlatform.isSunOS "-lm";
@@ -439,10 +431,18 @@ pipe
langJit
targetPlatform
hostPlatform
hostIsTarget
withoutTargetLibc
enableShared
libcCross
;
})
(callPackage ./common/checksum.nix { inherit langC langCC; })
(callPackage ./common/checksum.nix {
inherit
langC
langCC
buildIsHost
hostIsTarget
;
})
]
@@ -23,6 +23,8 @@
fetchurl,
withoutTargetLibc,
threadsCross,
buildIsHost,
hostIsTarget,
}:
let
@@ -36,10 +38,7 @@ let
# aarch64-darwin, as it breaks building a foreign one:
# https://github.com/iains/gcc-12-branch/issues/18
canApplyIainsDarwinPatches =
stdenv.hostPlatform.isDarwin
&& stdenv.hostPlatform.isAarch64
&& (lib.systems.equals buildPlatform hostPlatform)
&& (lib.systems.equals hostPlatform targetPlatform);
stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64 && buildIsHost && hostIsTarget;
inherit (lib) optionals optional;
in