## Auto-converted by kwiki2moinmoin v2005-10-07 = RPATH issue = == Background == There is quite a lot of information on the RPATH issue in Debian, however there is no document which consistently explains what the problem actually is, why the use of RPATH is discouraged in Debian and what are the preferred ways to correct upstream builds that use this feature. This page was created by JurijSmakov with the intention of collecting all the relevant information on the subject. == The Problem == === Dynamic linking === The job of the dynamic linker and loader ({{{ld.so}}}) is to resolve the executable's dependencies on shared libraries and to load the required ones at run-time. It relies on the executable's NEEDED headers to find the shared libraries with a matching SONAME (which includes the library name and ABI version). The dynamic linker will look for a matching library in the following locations, in this order, which can be changed (see the footnotes below): 1. the DT_RPATH dynamic section attribute of the library causing the lookup 2. the DT_RPATH dynamic section attribute of the executable 3. the LD_LIBRARY_PATH environment variable, unless the executable is setuid/setgid. 4. the DT_RUNPATH dynamic section attribute of the executable 5. {{{/etc/ld.so.cache}}} 6. base library directories ({{{/lib}}} and {{{/usr/lib}}}) Footnotes (the small print...): * Regarding steps 1 and 2: The DT_RPATH attribute is ignored if the DT_RUNPATH attribute is found. Then, LD_LIBRARY_PATH is searched first! * Regarding step 3: LD_LIBRARY_PATH can be overridden by calling the dynamic linker with the option {{{--library-path}}} (e.g. {{{/lib/ld-linux.so.2 --library-path $HOME/mylibs myprogram}}} * Regarding steps 5 and 6: If the executable was linked with -z nodeflib linker option, /lib and /usr/lib are skipped at step 5 and 6. * Regarding all steps: If the dynamic linker is called using {{{--inhibit-rpath LIST}}}, the objects in {{{LIST}}} are ignored. * Before library searching takes place, the libraries in LD_PRELOAD are loaded === Why RPATH is an issue === A problem arises when binary A defines a NEEDED dependency on libraries B.so.1 and C.so.'''2''', while library B.so.1 depends on library C.so.'''1'''. This means parts of the code will use one version of a library and other parts another. The many versions of a library scenario is needed to deal with gradual migrations, but maintainers shuffle libraries around when dealing with such a situation and packages with {{{RPATH}}} could end up finding the wrong version of a dependent library, one with incompatible dependencies. Since {{{RPATH}}} is set at build-time, it can only be overridden with a rebuild or by setting the {{{LD_LIBRARY_PATH}}} variable and this turns packages using it into management problems: * {{{LD_LIBRARY_PATH}}} can't be used because it has its own problems: it'll be inherited by all processes generated by the parent and is therefore also discouraged for distribution-wide use for its possible side-effects. * Needing a rebuild means that all dependencies of the affected library would need to be rebuilt during any move, which is an unacceptable scenario for a distribution. This situation would be better dealt with by the dynamic linker, since maintainers would have a central place to inform all dependent packages where to find libraries during transitional periods. === libtool's role === Historically, GNU {{{libtool}}} made extensive use of the {{{RPATH}}} feature, including the hardcoded library path information by default into all executables and shared libraries, which meant that this issue used to appear on many {{{libtool}}} based packages whose {{{libtool}}} used {{{RPATH}}} as default and didn't specifically implement workarounds for it. Since {{{libtool}}} 1.5.2 (released 2004-01-25), on Linux libtool no longer sets {{{RPATH}}} for any directories in the dynamic linker search path, so this should no longer be an issue unless upstream used a really old version of libtool when creating their distribution tarball. === Debian's Stance === While there's no policy dictating the accepted use of RPATH, it's been a general consensus that RPATH use is discouraged, given the interactions between the above reasons and Debian's way of dealing with libraries and package dependencies. Currently, the only generally accepted use of this feature in Debian is to add non-standard library path (like {{{/usr/lib/}}}) to libraries that are only intended to be used by the executables or other libraries within the same source package. == Possible solutions == === Upstream changes === Ideally, upstream should implement a build-system that supports turning {{{RPATH}}} usage off during configuration. If the build-system is based on pre-1.5.2 libtool, suggest upstream upgrade to a newer version. === Patching the build-system === Alternatively, the build-system can be patched to avoid {{{RPATH}}} at build-time. ==== Autotools with libtool ==== Following example (taken from {{{configure.ac}}} in {{{wmaker}}}) illustrates it: {{{ AC_PROG_LIBTOOL }}} {{{ # by Marcelo Magallon # Turn around -rpath problem with libtool 1.0c # This define should be improbable enough to not conflict with anything case ${host} in *-pc-linux-gnu) AC_MSG_RESULT([Fixing libtool for -rpath problems.]) sed < libtool > libtool-2 \ 's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_IS_A_FOOL__ "/' mv libtool-2 libtool chmod 755 libtool ;; esac }}} Another possibility (similar by the spirit) is [[http://lists.debian.org/debian-devel/2003/debian-devel-200306/msg00569.html|presented]] by Matthew Garrett: {{{ AC_MSG_RESULT(patching libtool to fix HIDEOUS BREAKAGE) test -f libtool.old |||| (mv libtool libtool.old && cp libtool.old libtool) sed -e s/^hardcode_direct.*$/hardcode_direct=yes/g libtool || \ sed -e s/^hardcode_minus_L.*$/hardcode_minus_L=yes/g || \ sed -e s/^hardcode_shlibpath_var.*$/hardcode_shlibpath_var=no/g >libtool.new mv libtool.new libtool }}} Or more generally, it's also possible to patch the configure generated libtool script, the {{{autoconf}}} generated configure script or the raw {{{acloca.m4}}} script via ''debian/rules'' with: {{{ sed -i -r 's/(hardcode_into_libs)=.*$/\1=no/' $(CURDIR)/ }}} '''NOTE:''' if by need or choice the aclocal.m4, configure.in or configure.ac files were patched, it's necessary to re-run autoconf in order to generate an up-to-date configure script. ==== CMake ==== You can stop cmake adding the flags for rpath-setting by adding {{{ SKIP_BUILD_RPATH TRUE }}} to the properties on the relevant binary in {{{CMakeLists.txt}}} e.g. {{{ set_target_properties(foolib PROPERTIES SKIP_BUILD_RPATH TRUE) }}} Ideally this change would be upstreamed. === Using chrpath === The package {{{chrpath}}} can be used during debian/rules' {{{install}}} target to strip the {{{RPATH}}} header from the generated binary. === rpath issue on amd64 === Fedora (and possibly some other distros) patched their libtool 1.5 packages so that on 64 bit Linux platforms it calculates the list of directories ld.so searches as /lib64 and /usr/lib64 plus anything in ld.so.conf (rather than /lib and /usr/lib plus anything in ld.so.conf which is what vanilla upstream libtool does). Debian use /lib and /usr/lib on all architectures, so if upstream built their tarballs on a Fedora 10 or earlier box, then an rpath would end up set in Debian packages for 64 bit architectures. The libtool packages in Fedora 11 and later (which are of libtool 2.2.6) have a revised patch which '''adds''' /lib64 and /usr/lib64 while keeping /lib and /usr/lib, so this problem is now resolved unless upstream uses a no longer supported version of Fedora (or hasn't made a release in a while). == References == * [[http://lists.debian.org/debian-devel/1995/12/msg00099.html|first mention of not using RPATH as a Debian "best practice"]] * [[http://lists.debian.org/debian-devel/1999/01/msg02245.html|discussion with libtool's upstream about RPATH problem]] * [[http://lists.debian.org/debian-devel/2002/07/msg02030.html|breakdown of acceptable RPATH use in Debian]] * [[http://lists.debian.org/debian-devel/2004/06/msg00734.html|yet another thread rehashing the issue]] * [[http://lists.debian.org/debian-devel/2008/01/msg00308.html|rpath issue on amd64, solution]] * [[http://www.eyrie.org/~eagle/notes/rpath.html|Shared Library Search Paths]]