Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gcc: builder overhaul #238069

Closed
wants to merge 9 commits into from
128 changes: 62 additions & 66 deletions pkgs/development/compilers/gcc/common/builder.nix
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
{ lib
, stdenv
, enableMultilib
, staticCompiler
}:

originalAttrs: (stdenv.mkDerivation (finalAttrs: originalAttrs // {
originalAttrs: (stdenv.mkDerivation (finalAttrs: originalAttrs //
(let
inherit (finalAttrs) targetConfig;
ifNullThen = val: default: if val==null then default else val;
targetConfigSlash = if targetConfig==null then "" else "${targetConfig}/";
in {
preUnpack = ''
oldOpts="$(shopt -po nounset)" || true
set -euo pipefail

export NIX_FIXINC_DUMMY="$NIX_BUILD_TOP/dummy"
mkdir "$NIX_FIXINC_DUMMY"

if test "$staticCompiler" = "1"; then
EXTRA_LDFLAGS="-static"
else
EXTRA_LDFLAGS="-Wl,-rpath,''${!outputLib}/lib"
fi
EXTRA_LDFLAGS="${if staticCompiler then "-static" else "-Wl,-rpath,${builtins.placeholder "lib"}/lib"}"

# GCC interprets empty paths as ".", which we don't want.
if test -z "''${CPATH-}"; then unset CPATH; fi
Expand Down Expand Up @@ -96,7 +98,7 @@ originalAttrs: (stdenv.mkDerivation (finalAttrs: originalAttrs // {
declare -g EXTRA_FLAGS''${post}="''${extraFlags[*]}"
done

if test -z "''${targetConfig-}"; then
if test -z "${ifNullThen targetConfig ""}"; then
# host = target, so the flags are the same
EXTRA_FLAGS_FOR_TARGET="$EXTRA_FLAGS"
EXTRA_LDFLAGS_FOR_TARGET="$EXTRA_LDFLAGS"
Expand Down Expand Up @@ -128,37 +130,31 @@ originalAttrs: (stdenv.mkDerivation (finalAttrs: originalAttrs // {
"FLAGS_FOR_TARGET=$EXTRA_FLAGS_FOR_TARGET $EXTRA_LDFLAGS_FOR_TARGET"
)

if test -z "''${targetConfig-}"; then
if test -z "${ifNullThen targetConfig ""}"; then
makeFlagsArray+=(
"BOOT_CFLAGS=$EXTRA_FLAGS $EXTRA_LDFLAGS"
"BOOT_LDFLAGS=$EXTRA_FLAGS_FOR_TARGET $EXTRA_LDFLAGS_FOR_TARGET"
)
fi

if test "$withoutTargetLibc" == 1; then
# We don't want the gcc build to assume there will be a libc providing
# limits.h in this stage
makeFlagsArray+=(
'LIMITS_H_TEST=false'
)
else
makeFlagsArray+=(
'LIMITS_H_TEST=true'
)
fi
# We don't want the gcc build to assume there will be a libc providing
# limits.h in this stage
makeFlagsArray+=(
'LIMITS_H_TEST=${lib.boolToString (!finalAttrs.withoutTargetLibc)}'
)
fi

eval "$oldOpts"
'';

preConfigure = (originalAttrs.preConfigure or "") + ''
if test -n "$newlibSrc"; then
tar xvf "$newlibSrc" -C ..
ln -s ../newlib-*/newlib newlib
# Patch to get armvt5el working:
sed -i -e 's/ arm)/ arm*)/' newlib/configure.host
fi
'' + lib.optionalString (finalAttrs.newlibSrc or false) ''
tar xvf "$newlibSrc" -C ..
ln -s ../newlib-*/newlib newlib
# Patch to get armvt5el working:
sed -i -e 's/ arm)/ arm*)/' newlib/configure.host

'' + ''
# Bug - they packaged zlib
if test -d "zlib"; then
# This breaks the build without-headers, which should build only
Expand All @@ -167,33 +163,33 @@ originalAttrs: (stdenv.mkDerivation (finalAttrs: originalAttrs // {
rm -Rf zlib
fi

if test -n "$crossMingw" -a -n "$withoutTargetLibc"; then
mkdir -p ../mingw
# --with-build-sysroot expects that:
cp -R $libcCross/include ../mingw
configureFlags="$configureFlags --with-build-sysroot=`pwd`/.."
fi
'' + lib.optionalString (finalAttrs.crossMingw && finalAttrs.withoutTargetLibc) ''
mkdir -p ../mingw
# --with-build-sysroot expects that:
cp -R $libcCross/include ../mingw
configureFlags="$configureFlags --with-build-sysroot=`pwd`/.."

'' + ''
# Perform the build in a different directory.
mkdir ../build
cd ../build
configureScript=../$sourceRoot/configure
'';

# Avoid store paths when embedding ./configure flags into gcc.
# Mangled arguments are still useful when reporting bugs upstream.
postConfigure = ''
# Avoid store paths when embedding ./configure flags into gcc.
# Mangled arguments are still useful when reporting bugs upstream.
sed -e "/TOPLEVEL_CONFIGURE_ARGUMENTS=/ s|$NIX_STORE/[a-z0-9]\{32\}-|$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-|g" -i Makefile
'';

preInstall = ''
mkdir -p "$out/''${targetConfig}/lib"
mkdir -p "''${!outputLib}/''${targetConfig}/lib"
mkdir -p "$out/${ifNullThen targetConfig ""}/lib"
mkdir -p "${builtins.placeholder "lib"}/${ifNullThen targetConfig ""}/lib"
'' +
# Make `lib64` symlinks to `lib`.
lib.optionalString (!enableMultilib && stdenv.hostPlatform.is64bit && !stdenv.hostPlatform.isMips64n32) ''
ln -s lib "$out/''${targetConfig}/lib64"
ln -s lib "''${!outputLib}/''${targetConfig}/lib64"
ln -s lib "$out/${ifNullThen targetConfig ""}/lib64"
ln -s lib "${builtins.placeholder "lib"}/${ifNullThen targetConfig ""}/lib64"
'' +
# On mips platforms, gcc follows the IRIX naming convention:
#
Expand All @@ -203,35 +199,35 @@ originalAttrs: (stdenv.mkDerivation (finalAttrs: originalAttrs // {
#
# Make `lib32` symlinks to `lib`.
lib.optionalString (!enableMultilib && stdenv.targetPlatform.isMips64n32) ''
ln -s lib "$out/''${targetConfig}/lib32"
ln -s lib "''${!outputLib}/''${targetConfig}/lib32"
ln -s lib "$out/${ifNullThen targetConfig ""}/lib32"
ln -s lib "${builtins.placeholder "lib"}/${ifNullThen targetConfig ""}/lib32"
'';

# Move runtime libraries to lib output.
postInstall = ''
# Move runtime libraries to lib output.
moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.so*" "''${!outputLib}"
moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.la" "''${!outputLib}"
moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.dylib" "''${!outputLib}"
moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.dll.a" "''${!outputLib}"
moveToOutput "share/gcc-*/python" "''${!outputLib}"

if [ -z "$enableShared" ]; then
moveToOutput "''${targetConfig+$targetConfig/}lib/lib*.a" "''${!outputLib}"
fi

for i in "''${!outputLib}/''${targetConfig}"/lib/*.{la,py}; do
substituteInPlace "$i" --replace "$out" "''${!outputLib}"
moveToOutput "${targetConfigSlash}lib/lib*.so*" "${builtins.placeholder "lib"}"
moveToOutput "${targetConfigSlash}lib/lib*.la" "${builtins.placeholder "lib"}"
moveToOutput "${targetConfigSlash}lib/lib*.dylib" "${builtins.placeholder "lib"}"
moveToOutput "${targetConfigSlash}lib/lib*.dll.a" "${builtins.placeholder "lib"}"
moveToOutput "share/gcc-*/python" "${builtins.placeholder "lib"}"

'' + lib.optionalString (!finalAttrs.enableShared) ''
moveToOutput "${targetConfigSlash}lib/lib*.a" "${builtins.placeholder "lib"}"
'' + ''

for i in "${builtins.placeholder "lib"}/${ifNullThen targetConfig ""}"/lib/*.{la,py}; do
substituteInPlace "$i" --replace "$out" "${builtins.placeholder "lib"}"
done

if [ -n "$enableMultilib" ]; then
moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.so*" "''${!outputLib}"
moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.la" "''${!outputLib}"
moveToOutput "''${targetConfig+$targetConfig/}lib64/lib*.dylib" "''${!outputLib}"
'' + lib.optionalString (finalAttrs.enableMultilib) ''
moveToOutput "${targetConfigSlash}lib64/lib*.so*" "${builtins.placeholder "lib"}"
moveToOutput "${targetConfigSlash}lib64/lib*.la" "${builtins.placeholder "lib"}"
moveToOutput "${targetConfigSlash}lib64/lib*.dylib" "${builtins.placeholder "lib"}"

for i in "''${!outputLib}/''${targetConfig}"/lib64/*.{la,py}; do
substituteInPlace "$i" --replace "$out" "''${!outputLib}"
done
fi
for i in "${builtins.placeholder "lib"}/${ifNullThen targetConfig ""}"/lib64/*.{la,py}; do
substituteInPlace "$i" --replace "$out" "${builtins.placeholder "lib"}"
done
'' + ''

# Remove `fixincl' to prevent a retained dependency on the
# previous gcc.
Expand All @@ -242,10 +238,10 @@ originalAttrs: (stdenv.mkDerivation (finalAttrs: originalAttrs // {
rm -rf $out/bin/gccbug

if type "install_name_tool"; then
for i in "''${!outputLib}"/lib/*.*.dylib "''${!outputLib}"/lib/*.so.[0-9]; do
for i in "${builtins.placeholder "lib"}"/lib/*.*.dylib "${builtins.placeholder "lib"}"/lib/*.so.[0-9]; do
install_name_tool -id "$i" "$i" || true
for old_path in $(otool -L "$i" | grep "$out" | awk '{print $1}'); do
new_path=`echo "$old_path" | sed "s,$out,''${!outputLib},"`
new_path=`echo "$old_path" | sed "s,$out,${builtins.placeholder "lib"},"`
install_name_tool -change "$old_path" "$new_path" "$i" || true
done
done
Expand All @@ -256,10 +252,10 @@ originalAttrs: (stdenv.mkDerivation (finalAttrs: originalAttrs // {
# of $dir headers and use it later as `-isysroot`. This prevents
# cc-wrapper from overriding libc headers with `-idirafter`.
# It should be safe to drop it and rely solely on the cc-wrapper.
local sysinc_dir=$out/''${targetConfig+$targetConfig/}sys-include
local sysinc_dir=$out/${targetConfigSlash}sys-include
if [ -d "$sysinc_dir" ]; then
chmod -R u+w "$out/''${targetConfig+$targetConfig/}sys-include"
rm -rfv "$out/''${targetConfig+$targetConfig/}sys-include"
chmod -R u+w "$out/${targetConfigSlash}sys-include"
rm -rfv "$out/${targetConfigSlash}sys-include"
fi

# Get rid of some "fixed" header files
Expand All @@ -286,4 +282,4 @@ originalAttrs: (stdenv.mkDerivation (finalAttrs: originalAttrs // {
fi
done
'';
}))
})))