| Autoconf, Automake, and Libtool | ||
|---|---|---|
| <<< Previous | Next >>> | |
This chapter develops the worked example described in the chapter called A Small GNU Autotools Project. Again, the example is heavily colored by my own views, and there certainly are other, very different, but equally valid ways of achieving the same objectives.
I will explain how I incorporated libtool into the Sic project, and how to put the project documentation and test suite under the control of GNU Autotools. I pointed out some problems with the project when I first introduced it - this chapter will address those issues, and present my favored solution to each.
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
|
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 [1] . See the section called Extra Macros for Libtool in the chapter called Using GNU Libtool with configure.in and Makefile.am, 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 the section called Extra Macros for Libtool in the chapter called Using GNU Libtool with configure.in and Makefile.am):
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 the section called Introduction to Distributions in the chapter called Rolling Distribution Tarballs.
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:
AC_SUBST(ac_aux_dir)
|
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 the chapter called 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.
| [1] | Actually the suffix will be whatever is appropriate for the target host: such as @samp{.obj} on Windows for example. |
| <<< Previous | Home | Next >>> |
| Convenience Libraries | Removing --foreign |