diff --git a/doc/stdenv.xml b/doc/stdenv.xml
index 94bd7365dd9a6f..0b5dabb06d27d5 100644
--- a/doc/stdenv.xml
+++ b/doc/stdenv.xml
@@ -1499,6 +1499,15 @@ installTargets = "install-bin install-doc";
dependencies.
+
+
+ On Linux, it uses patchelf on all libraries in
+ the lib tree to make the DT_SONAME
+ an absolute path to the library. This makes other binaries that
+ link against it access it directly rather than searching through
+ DT_RUNPATH, which increases efficiency.
+
+
It rewrites the interpreter paths of shell scripts to paths found in
@@ -1621,6 +1630,18 @@ installTargets = "install-bin install-doc";
+
+
+ noAbsoluteSoname
+
+
+
+ If set, the DT_SONAME entries of the shared
+ libraries in the output will be left unmodified. Only applies
+ to Linux.
+
+
+
dontPatchShebangs
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index 2caab69cbb95ce..c61e8606c703b1 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -61,6 +61,13 @@ let
ld*.so.?) continue;;
esac
+ # $next might be an absolute path
+ if [ -f "$next" ]; then
+ echo "$next"
+ add_needed "$next"
+ continue
+ fi
+
IFS=: read -ra paths <<< $rpath
res=
for path in "''${paths[@]}"; do
@@ -166,16 +173,25 @@ let
stripDirs "$STRIP" "lib bin" "-s"
# Run patchelf to make the programs refer to the copied libraries.
- find $out/bin $out/lib -type f | while read i; do
+ ( find $out/bin -type f ; find $out/lib -type f -not -name "ld*" ) | while read i; do
if ! test -L $i; then
- nuke-refs -e $out $i
+ echo "patching $i..."
+ libs=$(patchelf --print-needed $i)
+ replacements=""
+ for library in $libs; do
+ [[ library = */ld* ]] && continue
+ replacements+="--replace-needed $library $(basename $library) "
+ done
+ patchelf $replacements $i || true
+ patchelf --set-rpath $out/lib $i || true
+ [[ $i = $out/bin/* ]] && patchelf --set-interpreter $out/lib/ld*.so.? $i || true
fi
done
- find $out/bin -type f | while read i; do
+ # Remove any remaining refs to the outside
+ find $out/bin $out/lib -type f | while read i; do
if ! test -L $i; then
- echo "patching $i..."
- patchelf --set-interpreter $out/lib/ld*.so.? --set-rpath $out/lib $i || true
+ nuke-refs -e $out $i
fi
done
diff --git a/pkgs/build-support/setup-hooks/set-soname.sh b/pkgs/build-support/setup-hooks/set-soname.sh
new file mode 100644
index 00000000000000..5a408905e8ae01
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/set-soname.sh
@@ -0,0 +1,8 @@
+[[ -z "$noAbsoluteSoname" ]] && fixupOutputHooks+=(_doAbsoluteSoname)
+
+_doAbsoluteSoname() {
+ echo "Making sonames absolute"
+ if test -d "$prefix" ; then
+ find "$prefix" -type f '(' -name "lib*.so.*" -or -name 'lib*.so' ')' -not -name 'ld*' -exec patchelf --set-soname {} {} ';'
+ fi
+}
diff --git a/pkgs/development/compilers/gcc/6/default.nix b/pkgs/development/compilers/gcc/6/default.nix
index 0fb390758954ac..060b8123c185d3 100644
--- a/pkgs/development/compilers/gcc/6/default.nix
+++ b/pkgs/development/compilers/gcc/6/default.nix
@@ -162,6 +162,8 @@ stdenv.mkDerivation ({
builder = ../builder.sh;
+ noAbsoluteSoname = true;
+
src = fetchurl {
url = "mirror://gnu/gcc/gcc-${version}/gcc-${version}.tar.xz";
sha256 = "1m0lr7938lw5d773dkvwld90hjlcq2282517d1gwvrfzmwgg42w5";
diff --git a/pkgs/development/libraries/glibc/common.nix b/pkgs/development/libraries/glibc/common.nix
index 8b4a213aae0517..8a6c18140278ca 100644
--- a/pkgs/development/libraries/glibc/common.nix
+++ b/pkgs/development/libraries/glibc/common.nix
@@ -145,6 +145,8 @@ stdenv.mkDerivation ({
# prevent a retained dependency on the bootstrap tools in the stdenv-linux
# bootstrap.
BASH_SHELL = "/bin/sh";
+
+ noAbsoluteSoname = true;
}
// (removeAttrs args [ "withLinuxHeaders" "withGd" ]) //
diff --git a/pkgs/development/tools/misc/binutils/default.nix b/pkgs/development/tools/misc/binutils/default.nix
index 890ff7b64a9153..ddc895b8900e34 100644
--- a/pkgs/development/tools/misc/binutils/default.nix
+++ b/pkgs/development/tools/misc/binutils/default.nix
@@ -78,6 +78,7 @@ stdenv.mkDerivation rec {
buildInputs = [ zlib ];
inherit noSysDirs;
+ noAbsoluteSoname = true;
preConfigure = ''
# Clear the default library search path.
diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix
index 2eac9e58daa643..a7d0d33686abd1 100644
--- a/pkgs/stdenv/generic/default.nix
+++ b/pkgs/stdenv/generic/default.nix
@@ -47,6 +47,7 @@ let
../../build-support/setup-hooks/compress-man-pages.sh
../../build-support/setup-hooks/strip.sh
../../build-support/setup-hooks/patch-shebangs.sh
+ ../../build-support/setup-hooks/set-soname.sh
]
# FIXME this on Darwin; see
# https://github.com/NixOS/nixpkgs/commit/94d164dd7#commitcomment-22030369