bintools-wrapper: skip dynamic linker for static binaries

Changed files
+54 -19
pkgs
build-support
bintools-wrapper
cc-wrapper
development
compilers
test
cc-wrapper
+5
pkgs/build-support/bintools-wrapper/add-flags.sh
···
NIX_IGNORE_LD_THROUGH_GCC
NIX_LDFLAGS
NIX_LDFLAGS_BEFORE
+
NIX_DYNAMIC_LINKER
NIX_LDFLAGS_AFTER
NIX_LDFLAGS_HARDEN
NIX_HARDENING_ENABLE
···
if [ -e @out@/nix-support/libc-ldflags ]; then
NIX_LDFLAGS_@suffixSalt@+=" $(< @out@/nix-support/libc-ldflags)"
+
fi
+
+
if [ -z "$NIX_DYNAMIC_LINKER_@suffixSalt@" ] && [ -e @out@/nix-support/ld-set-dynamic-linker ]; then
+
NIX_DYNAMIC_LINKER_@suffixSalt@="$(< @out@/nix-support/dynamic-linker)"
fi
if [ -e @out@/nix-support/libc-ldflags-before ]; then
+8 -13
pkgs/build-support/bintools-wrapper/default.nix
···
if [ -n "''${dynamicLinker-}" ]; then
echo $dynamicLinker > $out/nix-support/dynamic-linker
-
'' + (if targetPlatform.isDarwin then ''
-
printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook
-
'' else ''
-
if [ -e ${libc_lib}/lib/32/ld-linux.so.2 ]; then
-
echo ${libc_lib}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32
-
fi
-
''
-
# The dynamic linker is passed in `ldflagsBefore' to allow
-
# explicit overrides of the dynamic linker by callers to ld
-
# (the *last* value counts, so ours should come first).
-
+ ''
-
echo -dynamic-linker "$dynamicLinker" >> $out/nix-support/libc-ldflags-before
-
'') + ''
+
${if targetPlatform.isDarwin then ''
+
printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook
+
'' else ''
+
if [ -e ${libc_lib}/lib/32/ld-linux.so.2 ]; then
+
echo ${libc_lib}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32
+
fi
+
touch $out/nix-support/ld-set-dynamic-linker
+
''}
fi
'')
+12 -1
pkgs/build-support/bintools-wrapper/ld-wrapper.sh
···
source @out@/nix-support/add-flags.sh
fi
+
setDynamicLinker=1
# Optionally filter out paths not refering to the store.
expandResponseParams "$@"
···
# Our ld is not built with sysroot support (Can we fix that?)
:
else
+
if [[ "$p" = -static || "$p" = -static-pie ]]; then
+
# Using a dynamic linker for static binaries can lead to crashes.
+
# This was observed for rust binaries.
+
setDynamicLinker=0
+
fi
rest+=("$p")
fi
n+=1
···
if [ -z "${NIX_LDFLAGS_SET_@suffixSalt@:-}" ]; then
extraAfter+=($NIX_LDFLAGS_@suffixSalt@)
extraBefore+=($NIX_LDFLAGS_BEFORE_@suffixSalt@)
+
# By adding dynamic linker to extraBefore we allow the users set their
+
# own dynamic linker as NIX_LD_FLAGS will override earlier set flags
+
if [[ "$setDynamicLinker" = 1 && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then
+
extraBefore+=("-dynamic-linker" "$NIX_DYNAMIC_LINKER_@suffixSalt@")
+
fi
fi
extraAfter+=($NIX_LDFLAGS_AFTER_@suffixSalt@)
···
done
fi
-
if [ -e "@out@/nix-support/dynamic-linker-m32" ] && (( "$link32" )); then
+
if [[ "$link32" = "1" && "$setDynamicLinker" = 1 && -e "@out@/nix-support/dynamic-linker-m32" ]]; then
# We have an alternate 32-bit linker and we're producing a 32-bit ELF, let's
# use it.
extraAfter+=(
+6
pkgs/build-support/cc-wrapper/cc-wrapper.sh
···
[[ "@prog@" = *++ ]] && isCpp=1 || isCpp=0
cppInclude=1
cInclude=1
+
setDynamicLinker=1
expandResponseParams "$@"
declare -i n=0
···
cppInclude=0
elif [ "$p" = -nostdinc++ ]; then
cppInclude=0
+
elif [[ "$p" = -static || "$p" = -static-pie ]]; then
+
setDynamicLinker=0
elif [[ "$p" != -?* ]]; then
# A dash alone signifies standard input; it is not a flag
nonFlagArgs=1
···
for i in $NIX_LDFLAGS_BEFORE_@suffixSalt@; do
extraBefore+=("-Wl,$i")
done
+
if [[ "$setDynamicLinker" = 1 && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then
+
extraBefore+=("-Wl,-dynamic-linker=$NIX_DYNAMIC_LINKER_@suffixSalt@")
+
fi
for i in $NIX_LDFLAGS_@suffixSalt@; do
if [ "${i:0:3}" = -L/ ]; then
extraAfter+=("$i")
+4 -1
pkgs/development/compilers/gcc/builder.sh
···
# Figure out what extra flags when linking to pass to the gcc
# compilers being generated to make sure that they use our libc.
extraLDFlags=($(< "${!curBintools}/nix-support/libc-ldflags") $(< "${!curBintools}/nix-support/libc-ldflags-before" || true))
+
if [ -e ${!curBintools}/nix-support/ld-set-dynamic-linker ]; then
+
extraLDFlags=-dynamic-linker=$(< ${!curBintools}/nix-support/dynamic-linker)
+
fi
# The path to the Libc binaries such as `crti.o'.
libc_libdir="$(< "${!curBintools}/nix-support/orig-libc")/lib"
···
if [[ targetConfig == *"linux"* ]]; then
# For some reason, when building for linux on darwin, the libs retain
-
# RPATH to $out.
+
# RPATH to $out.
for i in "$lib"/"$targetConfig"/lib/{libtsan,libasan,libubsan}.so.*.*.*; do
PREV_RPATH=`patchelf --print-rpath "$i"`
NEW_RPATH=`echo "$PREV_RPATH" | sed "s,:${out}[^:]*,,g"`
+19 -4
pkgs/test/cc-wrapper/default.nix
···
-
{ stdenv }:
+
{ stdenv, glibc }:
with stdenv.lib;
let
# Sanitizers are not supported on Darwin.
# Sanitizer headers aren't available in older libc++ stdenvs due to a bug
-
sanitizersWorking =
-
(stdenv.cc.isClang && versionAtLeast (getVersion stdenv.cc.name) "5.0.0")
-
|| (stdenv.cc.isGNU && stdenv.isLinux);
+
sanitizersWorking = !stdenv.hostPlatform.isMusl && (
+
(stdenv.cc.isClang && versionAtLeast (getVersion stdenv.cc.name) "5.0.0")
+
|| (stdenv.cc.isGNU && stdenv.isLinux)
+
);
+
staticLibc = optionalString (stdenv.hostPlatform.libc == "glibc") "-L ${glibc.static}/lib";
in stdenv.mkDerivation {
name = "cc-wrapper-test";
···
mkdir -p foo/lib
$CC -framework CoreFoundation -o core-foundation-check ${./core-foundation-main.c}
./core-foundation-check
+
''}
+
+
+
${optionalString (!stdenv.isDarwin) ''
+
printf "checking whether compiler builds valid static C binaries... " >&2
+
$CC ${staticLibc} -static -o cc-static ${./cc-main.c}
+
./cc-static
+
# our glibc does not have pie enabled yet.
+
${optionalString (stdenv.hostPlatform.isMusl && stdenv.cc.isGNU) ''
+
printf "checking whether compiler builds valid static pie C binaries... " >&2
+
$CC ${staticLibc} -static-pie -o cc-static-pie ${./cc-main.c}
+
./cc-static-pie
+
''}
''}
printf "checking whether compiler uses NIX_CFLAGS_COMPILE... " >&2