Differences between revisions 35 and 36
Revision 35 as of 2009-06-29 13:59:55
Size: 7691
Comment:
Revision 36 as of 2009-11-13 10:18:49
Size: 7770
Comment: fix error in libtool version
Deletions are marked like this. Additions are marked like this.
Line 111: Line 111:
Apparently upstream has fixed the problem reported with libsuff on amd64 and ppc64, the following can be used to check whether used libtool needs an upgrade Apparently upstream [[http://lists.debian.org/debian-devel/2008/01/msg00308.html|has fixed]] the problem reported with libsuff on amd64 and ppc64, the following can be used to check whether used libtool needs an upgrade
Line 113: Line 113:
(eval `sed -n '/^VERSION=/p' ./ltmain.sh` && dpkg --compare-versions $VERSION le 2.2.26 && echo "update") (eval `sed -n '/^VERSION=/p' ./ltmain.sh` && dpkg --compare-versions "$VERSION" le 2.2.6 && echo "run libtoolize/aclocal")
Line 115: Line 115:
/!\ what is actual version of fixed libtool? at least 2.2.26 is fixed /!\ what is actual version of fixed libtool? at least 2.2.6 is fixed

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 API version).

The dynamic linker will look for a matching library in the following locations, in this order (based on analysis of glibc-2.3.6.ds1):

  1. the RPATH binary header (set at build-time) of the library causing the lookup (if any)
  2. the RPATH binary header (set at build-time) of the executable
  3. the LD_LIBRARY_PATH environment variable (set at run-time)
  4. the RUNPATH binary header (set at build-time) of the executable
  5. /etc/ld.so.cache

  6. base library directories (/lib and /usr/lib)

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 makes extensive use of the RPATH feature, including the hardcoded library path information by default into all executables and shared libraries, which makes this issue particularly abundant.

Since libtool is meant to enable library interaction in many Unix-derived systems, some of which don't have dynamic linkers or whose linker can't handle coexistent libraries with same SONAMEs but different dependencies, it has defended its use of RPATH as the best way of handling the issue.

This issue therefore appears on many libtool based packages whose libtool used RPATH as default and didn't specifically implement workarounds for it.

According to ?JeffCarr, automake versions bigger than 1.9 don't have this problem, probably by avoiding RPATH on Linux hosts per default. (can someone confirm this?)

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/<package>) 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 libtool, it may supply the --disable-rpath configure option, and if not, asking upstream to add the relocatable.m4 and lib-link.m4 macros (from the gettext source) might solve it.

Another option for upstream is relibtoolizing with a changed version of the libtool script, that doesn't use RPATH by default, by patching it with:

 sed -i -r 's/(hardcode_into_libs=).*$/\1no/' `which libtool`

Patching the build-system

Alternatively, the build-system can be patched to avoid RPATH at build-time.

Following example (taken from configure.ac in wmaker) illustrates it:

 AC_PROG_LIBTOOL

 # by Marcelo Magallon <mmagallo@efis.ucr.ac.cr>
 # 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 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)/<file to patch>

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.

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

Apparently upstream has fixed the problem reported with libsuff on amd64 and ppc64, the following can be used to check whether used libtool needs an upgrade

(eval `sed -n '/^VERSION=/p' ./ltmain.sh` && dpkg --compare-versions "$VERSION" le 2.2.6 && echo "run libtoolize/aclocal")

/!\ what is actual version of fixed libtool? at least 2.2.6 is fixed

/!\ $ac_aux_dir might not be ./

References