Skip to content

Commit

Permalink
autoPatchelfHook: Support arbitrary paths in runtimeDependencies
Browse files Browse the repository at this point in the history
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 66462ae
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 6 deletions.
11 changes: 6 additions & 5 deletions doc/stdenv/stdenv.xml
Expand Up @@ -1991,7 +1991,7 @@ addEnvHooks "$hostOffset" myBashFunction
</para>
</listitem>
</varlistentry>
<varlistentry>
<varlistentry xml:id="setup-hook-autopatchelfhook">
<term>
autoPatchelfHook
</term>
Expand All @@ -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.
Expand Down
10 changes: 9 additions & 1 deletion pkgs/build-support/setup-hooks/auto-patchelf.sh
Expand Up @@ -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
Expand Down

0 comments on commit 66462ae

Please sign in to comment.