Skip to content
Permalink
Browse files

autoPatchelfHook: Support arbitrary paths in runtimeDependencies

Previously, the setup hooks configuration variable only accepted packages
and added lib subdirectory of those packages to rpath.
That was insufficient for including shared libraries like `lib/libv4l/v4l2convert.so`
so this patch allows for passing .so file paths whose parent directory will be added to rpath.
The patch also makes the process more strict, failing when a package not containing lib
or not a .so file is passed to avoid hard to debug failures like passing a wrong output.
  • Loading branch information
jtojnar committed Feb 13, 2020
1 parent 8130f3c commit 66462aef93ff20e2ed2b1338f9df9a15a10d2b06
Showing with 15 additions and 6 deletions.
  1. +6 −5 doc/stdenv/stdenv.xml
  2. +9 −1 pkgs/build-support/setup-hooks/auto-patchelf.sh
@@ -1991,7 +1991,7 @@ addEnvHooks "$hostOffset" myBashFunction
</para>
</listitem>
</varlistentry>
<varlistentry>
<varlistentry xml:id="setup-hook-autopatchelfhook">
<term>
autoPatchelfHook
</term>
@@ -2000,15 +2000,16 @@ addEnvHooks "$hostOffset" myBashFunction
This is a special setup hook which helps in packaging proprietary software in that it automatically tries to find missing shared library dependencies of ELF files based on the given <varname>buildInputs</varname> and <varname>nativeBuildInputs</varname>.
</para>
<para>
You can also specify a <envar>runtimeDependencies</envar> environment variable which lists dependencies that are unconditionally added to all executables.
</para>
<para>
You can also specify a <varname>runtimeDependencies</varname> variable which lists dependencies or paths to shared libraries to be unconditionally added to <term>rpath</term> of all executables.
This is useful for programs that use <citerefentry>
<refentrytitle>dlopen</refentrytitle>
<manvolnum>3</manvolnum> </citerefentry> to load libraries at runtime.
</para>
<note>
<para>When you pass a library path such as <literal>${libv4l}/lib/libv4l/v4l2convert.so</literal> to <envar>runtimeDependencies</envar>, the whole <literal>${libv4l}/lib/libv4l</literal> directory is added to <term>rpath</term>. This enables the patched program to find all other libraries in the directory, not just the single library you chose.</para>
</note>
<para>
In certain situations you may want to run the main command (<command>autoPatchelf</command>) of the setup hook on a file or a set of directories instead of unconditionally patching all outputs. This can be done by setting the <envar>dontAutoPatchelf</envar> environment variable to a non-empty value.
In certain situations you may want to run the main command (<command>autoPatchelf</command>) of the setup hook on a file or a set of directories instead of unconditionally patching all outputs. This can be done by setting the <varname>dontAutoPatchelf</varname> environment variable to a non-empty value.
</para>
<para>
The <command>autoPatchelf</command> command also recognizes a <parameter class="command">--no-recurse</parameter> command line flag, which prevents it from recursing into subdirectories.
@@ -106,7 +106,15 @@ autoPatchelfFile() {
patchelf --set-interpreter "$interpreter" "$toPatch"
if [ -n "$runtimeDependencies" ]; then
for dep in $runtimeDependencies; do
rpath="$rpath${rpath:+:}$dep/lib"
if [[ -f "$dep" && "$dep" =~ \.so(\.[0-9]+)*$ ]]; then
rpath="$rpath${rpath:+:}$(dirname "$dep")"
elif [[ -d "$dep" && -d "$dep/lib" ]]; then
rpath="$rpath${rpath:+:}$dep/lib"
else
echo "autoPatchelfFile: ERROR: $dep passed to \$runtimeDependencies must be" \
"either a directory containing lib subdirectory or a .so file."
return 1
fi
done
fi
fi

0 comments on commit 66462ae

Please sign in to comment.
You can’t perform that action at this time.