12.1 Using Libtool Libraries
As you have seen, It is very easy to convert automake built
static libraries to automake built Libtool libraries. In order
to build `libsic' as a Libtool library, I have changed the name of
the library from `libsic.a' (the old archive name in Libtool
terminology) to `libsic.la' (the pseudo-library), and must
use the LTLIBRARIES Automake primary:
|
lib_LTLIBRARIES = libsic.la
libsic_la_LIBADD = $(top_builddir)/replace/libreplace.la
libsic_la_SOURCES = builtin.c error.c eval.c list.c sic.c \
syntax.c xmalloc.c xstrdup.c xstrerror.c
| Notice the `la' in libsic_la_SOURCES is new too.
It is similarly easy to take advantage of Libtool convenience
libraries. For the purposes of Sic, `libreplace' is an ideal
candidate for this treatment -- I can create the library as a separate
entity from selected sources in their own directory, and add those
objects to `libsic'. This technique ensures that the installed
library has all of the support functions it needs without having to
link `libreplace' as a separate object.
In `replace/Makefile.am', I have again changed the name of the
library from `libreplace.a' to `libreplace.la', and changed
the automake primary from `LIBRARIES' to `LTLIBRARIES'.
Unfortunately, those changes alone are insufficient. Libtool libraries
are compiled from Libtool objects (which have the `.lo' suffix), so
I cannot use `LIBOBJS' which is a list of `.o' suffixed
objects(22).
See section 11.1.2 Extra Macros for Libtool, for more details. Here is
`replace/Makefile.am':
|
MAINTAINERCLEANFILES = Makefile.in
noinst_LTLIBRARIES = libreplace.la
libreplace_la_SOURCES =
libreplace_la_LIBADD = @LTLIBOBJS@
|
And not forgetting to set and use the `LTLIBOBJS' configure
substitution (see section 11.1.2 Extra Macros for Libtool):
|
Xsed="sed -e s/^X//"
LTLIBOBJS=echo X"$LIBOBJS" | \
[$Xsed -e s,\.[^.]* ,.lo ,g;s,\.[^.]*$,.lo,']
AC_SUBST(LTLIBOBJS)
|
As a consequence of using libtool to build the project
libraries, the increasing number of configuration files being added to
the `config' directory will grow to include `ltconfig' and
`ltmain.sh'. These files will be used on the installer's machine
when Sic is configured, so it is important to distribute them. The
naive way to do it is to give the `config' directory a
`Makefile.am' of its own; however, it is not too difficult to
distribute these files from the top `Makefile.am', and it saves
clutter, as you can see here:
|
AUX_DIST = $(ac_aux_dir)/config.guess \
$(ac_aux_dir)/config.sub \
$(ac_aux_dir)/install-sh \
$(ac_aux_dir)/ltconfig \
$(ac_aux_dir)/ltmain.sh \
$(ac_aux_dir)/mdate-sh \
$(ac_aux_dir)/missing \
$(ac_aux_dir)/mkinstalldirs
AUX_DIST_EXTRA = $(ac_aux_dir)/readline.m4 \
$(ac_aux_dir)/sys_errlist.m4 \
$(ac_aux_dir)/sys_siglist.m4
EXTRA_DIST = bootstrap
MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config-h.in \
stamp-h.in $(AUX_DIST)
dist-hook:
(cd $(distdir) && mkdir $(ac_aux_dir))
for file in $(AUX_DIST) $(AUX_DIST_EXTRA); do \
cp $$file $(distdir)/$$file; \
done
|
The `dist-hook' rule is used to make sure the `config'
directory and the files it contains are correctly added to the
distribution by the `make dist' rules, see section 13.1 Introduction to Distributions.
I have been careful to use the configure script's location for
ac_aux_dir , so that it is defined (and can be changed) in only
one place. This is achieved by adding the following macro to
`configure.in':
There is no need to explicity set a macro in the `Makefile.am',
because Automake automatically creates macros for every value that you
`AC_SUBST' from `configure.in'.
I have also added the AC_PROG_LIBTOOL macro to
`configure.in' in place of AC_PROG_RANLIB as described in
11. Using GNU Libtool with `configure.in' and `Makefile.am'.
Now I can upgrade the configury to use libtool -- the greater
part of this is running the libtoolize script that comes with
the Libtool distribution. The bootstrap script then needs to
be updated to run libtoolize at the correct juncture:
|
#! /bin/sh
set -x
aclocal -I config
libtoolize --force --copy
autoheader
automake --add-missing --copy
autoconf
|
Now I can re-bootstrap the entire project so that it can make use of
libtool :
|
$ ./bootstrap
+ aclocal -I config
+ libtoolize --force --copy
Putting files in AC_CONFIG_AUX_DIR, config.
+ autoheader
+ automake --add-missing --copy
automake: configure.in: installing config/install-sh
automake: configure.in: installing config/mkinstalldirs
automake: configure.in: installing config/missing
+ autoconf
|
The new macros are evident by the new output seen when the newly
regenerated configure script is executed:
|
$ ./configure --with-readline
...
checking host system type... i586-pc-linux-gnu
checking build system type... i586-pc-linux-gnu
checking for ld used by GCC... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for /usr/bin/ld option to reload object files... -r
checking for BSD-compatible nm... /usr/bin/nm -B
checking whether ln -s works... yes
checking how to recognise dependent libraries... pass_all
checking for object suffix... o
checking for executable suffix... no
checking for ranlib... ranlib
checking for strip... strip
...
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
creating libtool
...
$ make
...
gcc -g -O2 -o .libs/sic sic.o sic_builtin.o sic_repl.o sic_syntax.o \
../sic/.libs/libsic.so -lreadline -Wl,--rpath -Wl,/usr/local/lib
creating sic
...
$ src/sic
] libtool --mode=execute ldd src/sic
libsic.so.0 => /tmp/sic/sic/.libs/libsic.so.0 (0x40014000)
libreadline.so.4 => /lib/libreadline.so.4 (0x4001e000)
libc.so.6 => /lib/libc.so.6 (0x40043000)
libncurses.so.5 => /lib/libncurses.so.5 (0x40121000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
] exit
$
|
As you can see, sic is now linked against a shared library
build of `libsic', but not directly against the convenience
library, `libreplace'.
|