|
11.2.1 Creating Libtool Libraries with Automake
Continuing in the spirit of making Libtool library management look like
native static archive management, converting a `Makefile.am' from
static archive use to Libtool library use is a matter of changing the
name of the library, and adding a Libtool prefix somewhere. For
example, a `Makefile.am' for building a static archive might be:
|
lib_LIBRARIES = libshell.a
libshell_a_SOURCES = object.c subr.c symbol.c
|
This would build a static archive called `libshell.a' consisting of
the objects `object.o', `subr.o' and `bar.o'. To build
an equivalent Libtool library from the same objects, you change this to:
|
lib_LTLIBRARIES = libshell.la
libshell_la_SOURCES = object.c subr.c symbol.c
|
The only changes are that the library is now named with a .la
suffix, and the Automake primary is now `LTLIBRARIES'.
Note that since the name of the library has changed, you also need to
use `libshell_la_SOURCES', and similarly for any other Automake
macros which used to refer to the old archive. As for native libraries,
Libtool library names should begin with the letters `lib', so that
the linker will be able to find them when passed `-l' options.
Often you will need to add extra objects to the library as determined by
configure , but this is also a mechanical process. When
building native libraries, the `Makefile.am' would have contained:
|
libshell_a_LDADD = xmalloc.o @LIBOBJS@
|
To add the same objects to an equivalent Libtool library would require:
|
libshell_la_LDADD = xmalloc.lo @LTLIBOBJS@
|
That is, objects added to a Libtool library must be Libtool objects
(with a .lo ) suffix. You should add code to `configure.in'
to ensure that `LTALLOCA' and `LTLIBOBJS' are set
appropriately, See section 11.1.2 Extra Macros for Libtool. Automake will
take care of generating appropriate rules for building the Libtool
objects mentioned in an `LDADD' macro.
If you want to pass any additional flags to libtool when it is
building, you use the `LDFLAGS' macro for that library, like this:
|
libshell_la_LDFLAGS = -version-info 1:0:1
|
For a detailed list of all the available options, see section `Link mode' in The Libtool Manual.
Libtool's use of `-rpath' has been a point of contention for some
users, since it prevents you from moving shared libraries to another
location in the library search path. Or, at least, if you do, all of
the executables that were linked with `-rpath' set to the old
location will need to be relinked.
We (the Libtool maintainers) assert that always using `-rpath' is
a good thing: Mainly because you can guarantee that any executable
linked with `-rpath' will find the correct version of the
library, in the rpath directory, that was intended when the executable
was linked. Library versions can still be managed correctly, and will
be found by the run time loader, by installing newer versions to the
same directory. Additionally, it is much harder for a malicious user to
leave a modified copy of system library in a directory that someone
might wish to list in their `LD_LIBRARY_PATH' in the hope that some
code they have written will be executed unexpectedly.
The argument against `-rpath' was instigated when one of the
GNU/Linux distributions moved some important system libraries to
another directory to make room for a different version, and discovered
that all of the executables that relied on these libraries and were
linked with Libtool no longer worked. Doing this was, arguably, bad
system management -- the new libraries should have been placed in a new
directory, and the old libraries left alone. Refusing to use
`-rpath' incase you want to restructure the system library
directories is a very weak argument.
The `-rpath' option (which is required for Libtool libraries) is
automatically supplied by automake based on the installation
directory specified with the library primary.
|
lib_LTLIBRARIES = libshell.la
|
The example would use the value of the make macro $(libdir) as
the argument to `-rpath', since that is where the library will be
installed.
A few of the other options you can use in the library `LDFLAGS' are:
- `-no-undefined'
- Modern architectures allow us to create shared libraries with undefined
symbols, provided those symbols are resolved (usually by the executable
which loads the library) at runtime. Unfortunately, there are some
architectures (notably AIX and Windows) which require that
all symbols are resolved when the library is linked. If you know
that your library has no unresolved symbols at link time, then adding
this option tells
libtool that it will be able to build a
shared library, even on architectures which have this requirement.
- `-static'
- Using this option will force
libtool to build only a static
archive for this library.
- `-release'
- On occasion, it is desirable to encode the release number of a library
into its name. By specifying the release number with this option,
libtool will build a library that does this, but will break
binary compatibility for each change of the release number. By breaking
binary compatibility this way, you negate the possibility of fixing bugs
in installed programs by installing an updated shared library. You
should probably be using `-version-info' instead.
|
libshell_la_LDFLAGS = -release 27
|
The above fragment might create a library called
`libshell-27.so.0.0.0' for example.
- `-version-info'
- Set the version number of the library according to the native versioning
rules based on the numbers supplied, See section 11.4 Library Versioning. You
need to be aware that the library version number is for the use of the
runtime loader, and is completely unrelated to the release number of
your project. If you really want to encode the project release into the
library, you can use `-release' to do it.
If this option is not supplied explicitly, it defaults to
`-version-info 0:0:0'.
Historically, the default behaviour of Libtool was as if
`-no-undefined' was always passed on the command line, but it
proved to be annoying to developers who had to constantly turn it off so
that their ELF libraries could be featureful. Now it has to be
defined explicitly if you need it.
There are is a tradeoff:
-
If you don't specify `-no-undefined', then Libtool will not build
shared libraries on platforms which don't allow undefined symbols at
link time for such a library.
-
It is only safe to specify this flag when you know for certain that
all of the libraries symbols are defined at link time, otherwise
the `-no-undefined' link will appear to work until it is tried on
a platform which requires all symbols to be defined. Libtool will try
to link the shared library in this case (because you told it that you
have not left any undefined symbols), but the link will fail, because
there are undefined symbols in spite of what you told Libtool.
For more information about this topic, see 18.3 Portable Library Design.
|