autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

macros for rpath support


From: Bruno Haible
Subject: macros for rpath support
Date: Tue, 21 May 2002 14:45:46 +0200 (CEST)

The "GNU build system" has a solution for _building_ shared libraries
portably, namely libtool. As paradoxical as it sounds, it does not yet
have a solution for _using_ shared libraries portably.

The linker command line for using a shared library is fortunately the
same everywhere on Unix, namely -lfoo. But when this simple approach
is used, the resulting executables on many platforms need additional
measures to be taken in order to run: the user needs to set an environment
variable like LD_LIBRARY_PATH, LIBPATH or SHLIB_PATH, or needs to register
the directory in a file like /etc/ld.so.config. Quite painful in practice.

Most systems nowadays have a way to hardwire a shared library search path
(or the precise location of each required shared library) in the executable.
Let me call it the "rpath facility". This solves the LD_LIBRARY_PATH
problem, but has two disadvantages:
1) It hardcodes pathnames. But this is not a problem for packages built
   using autoconf: they cannot be relocatabled in the filesystem anyway.
   (The $prefix is used in the Makefile and hardwired in various places,
   from -DLOCALEDIR=$localedir to address@hidden@...)
2) The syntax used to specify a shared library's search path is platform
   dependent.

libtool 1.4 and newer is using the rpath facility, so that when libtool
is used to create an executable, the resulting executable runs out of the
box and does not have the LD_LIBRARY_PATH problem.

I suggested last year that every package that uses a shared library
(for example, -lintl for internationalization) use libtool to create its
executables. There was consensus that this is not the right approach,
mostly for practical reasons: it increases a package's size by 500 KB
(120 KB once for libtool.m4, once again for aclocal.m4, once more for
configure, and finally 140 KB for ltmain.sh). Also the configure script
then spends time checking for irrelevant features, like the output syntax
of "nm".

So I set out and realized in gettext-0.11.2 a solution of the LD_LIBRARY_PATH
problem that:

   1) is lightweight to use, and integrates well with autoconf and automake,
   2) integrates well with libtool, i.e. can be equally well used
      in projects that use libtool as in projects that don't,
   3) copes with dependencies between shared libraries (example:
      -lintl depends on -liconv), even on systems where these dependencies
      are not explicit
   4) handles all kinds of libraries, whether shared or static, whether
      built with or without libtool (example: zlib).
   5) works when cross-compiling,
   6) is easy to port to new platforms,
   7) allows support for new platforms to be added without rebuilding
      'configure'.

You find it in gettext-0.11.2, contained in the files
   m4/lib-ld.m4
   m4/lib-link.m4
   m4/lib-prefix.m4
   config.rpath
   tests/rpath*
   portions of tests/Makefile.am and Makefile.am related to tests/rpath*

The solution seems mature now. I have gotten no bug report about it since
the release of gettext-0.11.2.


I would propose this facility for inclusion in GNU autoconf. The reason is
that although it has been developed to deal with -lintl and -liconv, the
macros are generally useful and can equally well be used to locate libz
or libxml.


Of course you can rewrite the entire facility the way you like, but
first let me explain more details.

- There is a single autoconf macro:

  AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
  the libraries corresponding to explicit and implicit dependencies.
  Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
  augments the CPPFLAGS variable.

- Goal 1 is achieved by defining an autoconf macro which sets and AC_SUBSTs
  some variables.

  I made some experiments with a libtool like wrapper script for the link
  command line. It turns out that it is too intrusive (the programmer needs
  to look at all his link command line invocations, and automake would need
  modifications), and its size is still one third of libtool.m4.

  I also considered shell scripts of the form foo-config, but found that
  - they don't observe a standard pattern (some can give you CPPFLAGS, some
    can give you CFLAGS, some give you -L$libdir without rpath option, some
    with rpath option),
  - even if they were standardized, there would be the problem that the
    -rpath option is compiler and linker dependent: the ones contained in the
    foo-config script have been determined for the compiler that compiled
    libfoo, not for the compiler that uses it.
  - libtool and "gcc -shared" create libraries without creating foo-config
    scripts, therefore there are many more shared libraries around than
    foo-config scripts.

- Goal 2 is achieved by defining variables for use with libtool and variables
  for use without libtool. The first will contain "-Rdirectory" whereas the
  second one will contain "-Wl,-rpath,directory". This is needed because
  we cannot use the same variable for both cases: the linker does not accept
  "-Rdirectory", and libtool does not recognize "-Wl,-rpath,directory" and
  its variants with spaces.

- Goal 3: Dependencies between libraries. If libtool .la files are present,
  there is no need to specify the dependencies as argument of
  AC_LIB_LINKFLAGS. Only when the .la files are not there, it is needed
  to put a-priori knowledge into the AC_LIB_LINKFLAGS invocation.
  (It's needed for the case with static libraries, or platforms without
  implicit shared library dependencies.)

- Goal 4: Look into the macro :-)

- Goal 5: The autoconf test does not run any program, it only looks
  for files. Therefore a database of system capabilities, based on the
  canonical triple, is used.

- Goal 6: Porting to new platforms is made easy by a script rpathcfg.sh
  which infers the values which can be put into that database of system
  capabilities.

- Goal 7: The database of system capabilities has been put into a separate
  file, config.rpath, which is called from configure, not included in it.
  This way, when someone ports to a new platform and builds dozens of
  packages for it, he needs to patch all the config.rpath files the same
  way; he doesn't need to rerun aclocal and autoconf.

- Why does the macro modify CPPFLAGS? It could also define a variable
  INC${NAME} that the programmer would add to his DEFS Makefile variable.
  The reasons are:
  - So that later tests in the configure script can use the added
    library.
  - A set of Makefiles is more robust if all source files are compiled
    with the same -I options. (Just imagine one file being compiled
    with GNU libintl.h and another file with Solaris libintl.h... Messy.)

- On systems like OSF/1, where rpath options are not cumulative,
  the facility has the limitation that no more than one library directory
  can be used. I.e.
     --with-libiconv-prefix=/opt/gnu1 --with-libintl-prefix=/opt/gnu2
  will not solve the LD_LIBRARY_PATH problem. There are three workarounds:
  a) The user can use the same --prefix for all his packages.
  b) The user can create symlinks for the installed libraries, so that
     they become accessible from a single directory.
  c) The programmer could use libtool to create his executables.

- On systems like SCO 3.2.5, there is no rpath facility in the system at
  all. I haven't seen such systems for the last couple of years, but I
  believe that in this case the use of AC_LIB_LINKFLAGS will not harm
  (and have no positive effect either).

Bruno



reply via email to

[Prev in Thread] Current Thread [Next in Thread]