GNU Libtool Notes

Source: http://www.gnu.org/software/libtool/manual/libtool.html

GNU Libtool 2.4.2

1 Introduction

There are several examples throughout this document. All assume the same environment: we want to build a library, libhello, in a generic way.

libhello could be a shared library, a static library, or both whatever is available on the host system, as long as libtool has been ported to it.

3.1 Creating object files

To create library object files for foo.c and hello.c, simply invoke libtool with the standard compilation command as arguments (see Compile mode):

     a23$ libtool --mode=compile gcc -g -O -c foo.c
     gcc -g -O -c foo.c -o foo.o
     a23$ libtool --mode=compile gcc -g -O -c hello.c
     gcc -g -O -c hello.c -o hello.o
     a23$

Note that libtool silently creates an additional control file on each ‘compile’ invocation. The .lo file is the libtool object, which Libtool uses to determine what object file may be built into a shared library. On ‘a23’, only static libraries are supported so the library objects look like this:

     # foo.lo - a libtool object file
     # Generated by ltmain.sh (GNU libtool) 2.4.2
     #
     # Please DO NOT delete this file!
     # It is necessary for linking the library.

     # Name of the PIC object.
     pic_object=none

     # Name of the non-PIC object.
     non_pic_object='foo.o'

On shared library systems, libtool automatically generates an additional PIC object by inserting the appropriate PIC generation flags into the compilation command:

     burger$ libtool --mode=compile gcc -g -O -c foo.c
     mkdir .libs
     gcc -g -O -c foo.c -fPIC -DPIC -o .libs/foo.o
     gcc -g -O -c foo.c -o foo.o >/dev/null 2>&1
     burger$

Note that Libtool automatically created .libs directory upon its first execution, where PIC library object files will be stored.

Since ‘burger’ supports shared libraries, and requires PIC objects to build them, Libtool has compiled a PIC object this time, and made a note of it in the libtool object:

     # foo.lo - a libtool object file
     # Generated by ltmain.sh (GNU libtool) 2.4.2
     #
     # Please DO NOT delete this file!
     # It is necessary for linking the library.

     # Name of the PIC object.
     pic_object='.libs/foo.o'

     # Name of the non-PIC object.
     non_pic_object='foo.o'

Notice that the second run of GCC has its output discarded. This is done so that compiler warnings aren’t annoyingly duplicated. If you need to see both sets of warnings (you might have conditional code inside ‘#ifdef PIC’ for example), you can turn off suppression with the -no-suppress option to libtool’s compile mode:

     burger$ libtool --mode=compile gcc -no-suppress -g -O -c hello.c
     gcc -g -O -c hello.c -fPIC -DPIC -o .libs/hello.o
     gcc -g -O -c hello.c -o hello.o
     burger$

3.2 Linking libraries

Now, let’s try the same trick on the shared library platform:

     burger$ libtool --mode=link gcc -g -O -o libhello.la foo.lo hello.lo \
                     -rpath /usr/local/lib -lm
     rm -fr .libs/libhello.a .libs/libhello.la
     ld -Bshareable -o .libs/libhello.so.0.0 .libs/foo.o .libs/hello.o -lm
     ar cru .libs/libhello.a foo.o hello.o
     ranlib .libs/libhello.a
     creating libhello.la
     (cd .libs && rm -f libhello.la && ln -s ../libhello.la libhello.la)
     burger$

Now that’s significantly cooler Libtool just ran an obscure ld command to create a shared library, as well as the static library.

Note how libtool creates extra files in the .libs subdirectory, rather than the current directory. This feature is to make it easier to clean up the build directory, and to help ensure that other programs fail horribly if you accidentally forget to use libtool when you should.

3.3 Linking executables

then you don’t need to use libtool to do the linking. Simply use the appropriate -L and -l flags to specify the library’s location.

Here’s the old way of linking against an uninstalled library:

     burger$ gcc -g -O -o hell.old main.o libhello.a -lm
     burger$

Libtool’s way is almost the same2 (see Link mode):

     a23$ libtool --mode=link gcc -g -O -o hell main.o libhello.la
     gcc -g -O -o hell main.o ./.libs/libhello.a -lm
     a23$

3.4 Debugging executables

Fortunately, we can forget all about the .libs directory, and just run it on the executable wrapper (see Execute mode):

     burger$ libtool --mode=execute gdb hell

3.5 Installing libraries

Installing libraries on a non-libtool system is quite straightforward just copy them into place:4

     burger# cp libhello.a /usr/local/lib/libhello.a

Oops, don’t forget the ranlib command:

     burger# ranlib /usr/local/lib/libhello.a

Libtool installation is quite simple, as well. Just use the install or cp command that you normally would (see Install mode):

     a23# libtool --mode=install cp libhello.la /usr/local/lib/libhello.la

Here is the shared library example:

     burger# libtool --mode=install install -c libhello.la \
                     /usr/local/lib/libhello.la

First, you must make sure that where the library is installed actually agrees with the -rpath flag you used to build it.

Then, running ‘libtool -n finish libdir’ can give you further hints on what to do (see Finish mode):

     burger# libtool -n finish /usr/local/lib
     PATH="$PATH:/sbin" ldconfig -m /usr/local/lib
     -----------------------------------------------------------------
     Libraries have been installed in:
        /usr/local/lib

     To link against installed libraries in a given directory, LIBDIR,
     you must use the `-LLIBDIR' flag during linking.

      You will also need to do one of the following:
        - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
          during execution
        - add LIBDIR to the `LD_RUN_PATH' environment variable
          during linking
        - use the `-RLIBDIR' linker flag

     See any operating system documentation about shared libraries for
     more information, such as the ld and ld.so manual pages.
     -----------------------------------------------------------------

3.6 Installing executables

On shared library systems that require wrapper scripts, libtool just ignores the wrapper script and installs the correct binary:

     burger# libtool --mode=install -c hell /usr/local/bin/hell

3.7 Linking static libraries

     burger$ libtool --mode=install ./install-sh -c libhello.a \
                     /local/lib/libhello.a
     ./install-sh -c libhello.a /local/lib/libhello.a
     ranlib /local/lib/libhello.a
     burger$
When GNU Automake is used, you should use noinst_LTLIBRARIES instead of lib_LTLIBRARIES for convenience libraries, so that the -rpath option is not passed when they are linked. 

As a rule of thumb, link a libtool convenience library into at most one libtool library, and never into a program, and link libtool static convenience libraries only into programs, and only if you need to carry library dependency information to the user of the static convenience library.

Another common situation where static linking is desirable is in creating a standalone binary. Use libtool to do the linking and add the -all-static flag.

4 Invoking libtool

The libtool program has the following synopsis:

     libtool [option]... [mode-arg]...

and accepts the following options:

–config
Display libtool configuration variables and exit.
–debug
Dump a trace of shell script execution to standard output. This produces a lot of output, so you may wish to pipe it to less (or more) or redirect to a file.
-n
–dry-run
Don’t create, modify, or delete any files, just show what commands would be executed by libtool.
–features
Display basic configuration options. This provides a way for packages to determine whether shared or static libraries will be built.
–finish
Same as –mode=finish.
-h
Display short help message.
–help
Display a help message and exit. If –mode=mode is specified, then detailed help for mode is displayed.
–help-all
Display help for the general options as well as detailed help for each operation mode, and exit.
–mode=mode
Use mode as the operation mode. When using libtool from the command line, you can give just mode (or a unique abbreviation of it) as the first argument as a shorthand for the full –mode=mode. For example, the following are equivalent:
          $ libtool --mode=execute --dry-run gdb prog.exe
          $ libtool execute --dry-run gdb prog.exe
          $ libtool exe --dry-run gdb prog.exe
          $ libtool e --dry-run gdb prog.exe

mode must be set to one of the following:

compile
Compile a source file into a libtool object.
execute
Automatically set the library path so that another program can use uninstalled libtool-generated programs or libraries.
link
Create a library or an executable.
install
Install libraries or executables.
finish
Complete the installation of libtool libraries on the system.
uninstall
Delete installed libraries or executables.
clean
Delete uninstalled libraries or executables.
–tag=tag
Use configuration variables from tag tag (see Tags).
–preserve-dup-deps
Do not remove duplicate dependencies in libraries. When building packages with static libraries, the libraries may depend circularly on each other (shared libs can too, but for those it doesn’t matter), so there are situations, where -la -lb -la is required, and the second -la may not be stripped or the link will fail. In cases where these duplications are required, this option will preserve them, only stripping the libraries that libtool knows it can safely.
–quiet
–silent
Do not print out any progress or informational messages.
-v
–verbose
Print out progress and informational messages (enabled by default), as well as additional messages not ordinary seen by default.
–no-quiet
–no-silent
Print out the progress and informational messages that are seen by default. This option has no effect on whether the additional messages seen in –verbose mode are shown.
–no-verbose
Do not print out any additional informational messages beyond those ordinarily seen by default.

4.1 Compile mode

-o
Note that the -o option is now fully supported. It is emulated on the platforms that don’t support it (by locking and moving the objects), so it is really easy to use libtool, just with minor modifications to your Makefiles.
-no-suppress
If both PIC and non-PIC objects are being built, libtool will normally suppress the compiler output for the PIC object compilation to save showing very similar, if not identical duplicate output for each object. If the -no-suppress option is given in compile mode, libtool will show the compiler output for both objects.
-prefer-pic
Libtool will try to build only PIC objects.
-prefer-non-pic
Libtool will try to build only non-PIC objects.
-shared
Even if Libtool was configured with –enable-static, the object file Libtool builds will not be suitable for static linking. Libtool will signal an error if it was configured with –disable-shared, or if the host does not support shared libraries.
-static
Even if libtool was configured with –disable-static, the object file Libtool builds will be suitable for static linking.
-Wc,flag
-Xcompiler flag
Pass a flag directly to the compiler. With -Wc,, multiple flags may be separated by commas, whereas -Xcompiler passes through commas unchanged.

4.2 Link mode

-all-static
If output-file is a program, then do not link it against any shared libraries at all. If output-file is a library, then only create a static library. In general, this flag cannot be used together with ‘disable-static’ (see LT_INIT).
-avoid-version
Tries to avoid versioning (see Versioning) for libraries and modules, i.e. no version information is stored and no symbolic links are created. If the platform requires versioning, this option has no effect.
-bindir
Pass the absolute name of the directory for installing executable programs (see Directory Variables). libtool may use this value to install shared libraries there on systems that do not provide for any library hardcoding and use the directory of a program and the PATH variable as library search path.
-dlopen file
Same as -dlpreopen file, if native dlopening is not supported on the host platform (see Dlopened modules) or if the program is linked with -static, -static-libtool-libs, or -all-static. Otherwise, no effect. If file is self Libtool will make sure that the program can dlopen itself, either by enabling -export-dynamic or by falling back to -dlpreopen self.
-dlpreopen file
Link file into the output program, and add its symbols to the list of preloaded symbols (see Dlpreopening). If file is self, the symbols of the program itself will be added to preloaded symbol lists. If file is force Libtool will make sure that a preloaded symbol list is always defined, regardless of whether it’s empty or not.
-export-dynamic
Allow symbols from output-file to be resolved with dlsym (see Dlopened modules).
-export-symbols symfile
Tells the linker to export only the symbols listed in symfile. The symbol file should end in .sym and must contain the name of one symbol per line. This option has no effect on some platforms. By default all symbols are exported.
-export-symbols-regex regex
Same as -export-symbols, except that only symbols matching the regular expression regex are exported. By default all symbols are exported.
-Llibdir
Search libdir for required libraries that have already been installed.
-lname
output-file requires the installed library libname. This option is required even when output-file is not an executable.
-module
Creates a library that can be dlopened (see Dlopened modules). This option doesn’t work for programs. Module names don’t need to be prefixed with ‘lib’. In order to prevent name clashes, however, libname and name must not be used at the same time in your package.
-no-fast-install
Disable fast-install mode for the executable output-file. Useful if the program won’t be necessarily installed.
-no-install
Link an executable output-file that can’t be installed and therefore doesn’t need a wrapper script on systems that allow hardcoding of library paths. Useful if the program is only used in the build tree, e.g., for testing or generating other files.
-no-undefined
Declare that output-file does not depend on any libraries other than the ones listed on the command line, i.e., after linking, it will not have unresolved symbols. Some platforms require all symbols in shared libraries to be resolved at library creation (see Inter-library dependencies), and using this parameter allows libtool to assume that this will not happen.
-o output-file
Create output-file from the specified objects and libraries.
-objectlist file
Use a list of object files found in file to specify objects.
-precious-files-regex regex
Prevents removal of files from the temporary output directory whose names match this regular expression. You might specify ‘\.bbg?$’ to keep those files created with gcc -ftest-coverage for example.
-release release
Specify that the library was generated by release release of your package, so that users can easily tell which versions are newer than others. Be warned that no two releases of your package will be binary compatible if you use this flag. If you want binary compatibility, use the -version-info flag instead (see Versioning).
-rpath libdir
If output-file is a library, it will eventually be installed in libdir. If output-file is a program, add libdir to the run-time path of the program. On platforms that don’t support hardcoding library paths into executables and only search PATH for shared libraries, such as when output-file is a Windows (or other PE platform) DLL, the .la control file will be installed in libdir, but see -bindir above for the eventual destination of the .dll or other library file itself.
-R libdir
If output-file is a program, add libdir to its run-time path. If output-file is a library, add -Rlibdir to its dependency_libs, so that, whenever the library is linked into a program, libdir will be added to its run-time path.
-shared
If output-file is a program, then link it against any uninstalled shared libtool libraries (this is the default behavior). If output-file is a library, then only create a shared library. In the later case, libtool will signal an error if it was configured with –disable-shared, or if the host does not support shared libraries.
-shrext suffix
If output-file is a libtool library, replace the system’s standard file name extension for shared libraries with suffix (most systems use .so here). This option is helpful in certain cases where an application requires that shared libraries (typically modules) have an extension other than the default one. Please note you must supply the full file name extension including any leading dot.
-static
If output-file is a program, then do not link it against any uninstalled shared libtool libraries. If output-file is a library, then only create a static library.
-static-libtool-libs
If output-file is a program, then do not link it against any shared libtool libraries. If output-file is a library, then only create a static library.
-version-info current[:revision[:age]]
If output-file is a libtool library, use interface version information current, revision, and age to build it (see Versioning). Do not use this flag to specify package release information, rather see the -release flag.
-version-number major[:minor[:revision]]
If output-file is a libtool library, compute interface version information so that the resulting library uses the specified major, minor and revision numbers. This is designed to permit libtool to be used with existing projects where identical version numbers are already used across operating systems. New projects should use the -version-info flag instead.
-weak libname
if output-file is a libtool library, declare that it provides a weak libname interface. This is a hint to libtool that there is no need to append libname to the list of dependency libraries of output-file, because linking against output-file already supplies the same interface (see Linking with dlopened modules).
-Wc,flag
-Xcompiler flag
Pass a linker-specific flag directly to the compiler. With -Wc,, multiple flags may be separated by commas, whereas -Xcompiler passes through commas unchanged.
-Wl,flag
-Xlinker flag
Pass a linker-specific flag directly to the linker.
-XCClinker flag
Pass a link-specific flag to the compiler driver (CC) during linking.

If the output-file ends in .la, then a libtool library is created, which must be built only from library objects (.lo files). The -rpath option is required. In the current implementation, libtool libraries may not depend on other uninstalled libtool libraries (see Inter-library dependencies).

If the output-file ends in .a, then a standard library is created using ar and possibly ranlib.

If output-file ends in .o or .lo, then a reloadable object file is created from the input files (generally using ‘ld -r’). This method is often called partial linking.

4.3 Execute mode

-dlopen file
Add the directory containing file to the library path.

4.4 Install mode

In install mode, libtool interprets most of the elements of mode-args as an installation command beginning with cp, or a BSD-compatible install program.

The following components of mode-args are treated specially:

-inst-prefix-dir inst-prefix-dir
When installing into a temporary staging area, rather than the final prefix, this argument is used to reflect the temporary path, in much the same way automake uses DESTDIR. For instance, if prefix is /usr/local, but inst-prefix-dir is /tmp, then the object will be installed under /tmp/usr/local/. If the installed object is a libtool library, then the internal fields of that library will reflect only prefix, not inst-prefix-dir:
          # Directory that this library needs to be installed in:
          libdir='/usr/local/lib'
not
          # Directory that this library needs to be installed in:
          libdir='/tmp/usr/local/lib'
inst-prefix is also used to insure that if the installed object must be relinked upon installation, that it is relinked against the libraries in inst-prefix-dir/prefix, not prefix.

5 Integrating libtool with your package

Typically, the Libtool macro files as well as ltmain.sh are copied into your package using libtoolize and aclocal after setting up the configure.ac and toplevel Makefile.am, then autoconf adds the needed tests to the configure script. These individual steps are often automated with autoreconf.
     libtool.m4 -----. .--> aclocal.m4 -----.
     ltoptions.m4 ---+ .-> aclocal* -+ +--> autoconf*
     ltversion.m4 ---+--+ `--> [copy in m4/] --+ |
     ltsugar.m4 -----+ | ^ | \/
     lt~obsolete.m4 -+ +-> libtoolize* -----' | configure
     [ltdl.m4] ------+ | |
                        `----------------------------------'

     ltmain.sh -----------> libtoolize* -> [copy in build-aux/]

During configuration, the libtool script is generated either through config.status or config.lt:

                  .--> config.status* --.
     configure* --+ +--> libtool
                  `--> [config.lt*] ----' ^
                                               |
     ltmain.sh --------------------------------'
At make run time, libtool is then invoked as needed as a wrapper around compilers, linkers, install and cleanup programs.

5.1 Autoconf macros exported by libtool

Macro: LT_CMD_MAX_LEN

Finds the longest command line that can be safely passed to ‘$SHELL’ without being truncated, and store in the shell variable ‘$max_cmd_len’. It is only an approximate value, but command lines of this length or shorter are guaranteed not to be truncated.

Macros in the ‘LT_FUNC_’ namespace check characteristics of library functions:

Macro: LT_FUNC_DLSYM_USCORE

AC_DEFINE’ the preprocessor symbol ‘DLSYM_USCORE’ if we have to add an underscore to symbol-names passed in to ‘dlsym’.

Macros in the ‘LT_LIB_’ namespace check characteristics of system libraries:

Macro: LT_LIB_M

Set ‘LIBM’ to the math library or libraries required on this machine, if any.

Macro: LT_LIB_DLLOAD

This is the macro used by ‘libltdl’ to determine which dlloaders to use on this machine, if any. Several shell variables are set (and ‘AC_SUBST’ed) depending on the dlload interfaces are available on this machine. ‘LT_DLLOADERS’ contains a list of libtool libraries that can be used, and if necessary also sets ‘LIBADD_DLOPEN’ if additional system libraries are required by the ‘dlopen’ loader, and ‘LIBADD_SHL_LOAD’ if additional system libraries are required by the ‘shl_load’ loader, respectively. Finally some symbols are set in config.h depending on the loaders that are found to work: ‘HAVE_LIBDL’, ‘HAVE_SHL_LOAD’, ‘HAVE_DYLD’, ‘HAVE_DLD’.

Macros in the ‘LT_PATH_’ namespace search the system for the full path to particular system commands:

Macro: LT_PATH_LD

Add a –with-gnu-ld option to configure. Try to find the path to the linker used by ‘$CC’, and whether it is the GNU linker. The result is stored in the shell variable ‘$LD’, which is AC_SUBSTed.

Macro: LT_PATH_NM

Try to find a BSD-compatible nm or a MS-compatible dumpbin command on this machine. The result is stored in the shell variable ‘$NM’, which is AC_SUBSTed.

Macros in the ‘LT_SYS_’ namespace probe for system characteristics:

Macro: LT_SYS_DLOPEN_SELF

Tests whether a program can dlopen itself, and then also whether the same program can still dlopen itself when statically linked. Results are stored in the shell variables ‘$enable_dlopen_self’ and ‘enable_dlopen_self_static’ respectively.

Macro: LT_SYS_DLOPEN_DEPLIBS

Define the preprocessor symbol ‘LTDL_DLOPEN_DEPLIBS’ if the OS needs help to load dependent libraries for ‘dlopen’ (or equivalent).

Macro: LT_SYS_DLSEARCH_PATH

Define the preprocessor symbol ‘LT_DLSEARCH_PATH’ to the system default library search path.

Macro: LT_SYS_MODULE_EXT

Define the preprocessor symbol ‘LT_MODULE_EXT’ to the extension used for runtime loadable modules. If you use libltdl to open modules, then you can simply use the libtool library extension, .la.

Macro: LT_SYS_MODULE_PATH

Define the preprocessor symbol ‘LT_MODULE_PATH_VAR’ to the name of the shell environment variable that determines the run-time module search path.

Macro: LT_SYS_SYMBOL_USCORE

Set the shell variable ‘sys_symbol_underscore’ to ‘no’ unless the compiler prefixes global symbols with an underscore.

5.3 Using Automake with libtool

Libtool library support is implemented under the ‘LTLIBRARIES’ primary.

First, to link a program against a libtool library, just use the ‘program_LDADD’5 variable:

     bin_PROGRAMS = hell hell_static

     # Build hell from main.c and libhello.la
     hell_SOURCES = main.c
     hell_LDADD = libhello.la

     # Create a statically linked version of hell.
     hell_static_SOURCES = main.c
     hell_static_LDADD = libhello.la
     hell_static_LDFLAGS = -static

Building a libtool library is almost as trivial note the use of ‘libhello_la_LDFLAGS’ to pass the -version-info (see Versioning) option to libtool:

     # Build a libtool library, libhello.la for installation in libdir.
     lib_LTLIBRARIES = libhello.la
     libhello_la_SOURCES = hello.c foo.c
     libhello_la_LDFLAGS = -version-info 3:12:1

5.4.1 The LT_INIT macro

If you are using GNU Autoconf (or Automake), you should add a call to LT_INIT to your configure.ac file. This macro adds many new tests to the configure script so that the generated libtool script will understand the characteristics of the host. It’s the most important of a number of macros defined by Libtool:

Macro: LT_PREREQ (version)

Ensure that a recent enough version of Libtool is being used. If the version of Libtool used for LT_INIT is earlier than version, print an error message to the standard error output and exit with failure (exit status is 63). For example:

          LT_PREREQ([2.4.2])

Macro: LT_INIT (options)
— Macro: AC_PROG_LIBTOOL
— Macro: AM_PROG_LIBTOOL

Add support for the –enable-shared, –disable-shared, –enable-static, –disable-static, –with-pic, and –without-pic configure flags.6 AC_PROG_LIBTOOL and AM_PROG_LIBTOOL are deprecated names for older versions of this macro; autoupdate will upgrade your configure.ac files.

By default, this macro turns on shared libraries if they are available, and also enables static libraries if they don’t conflict with the shared libraries. You can modify these defaults by passing either disable-shared or disable-static in the option list to LT_INIT, or using AC_DISABLE_SHARED or AC_DISABLE_STATIC.

          # Turn off shared libraries during beta-testing, since they
          # make the build process take too long.
          LT_INIT([disable-shared])

The user may specify modified forms of the configure flags –enable-shared and –enable-static to choose whether shared or static libraries are built based on the name of the package. For example, to have shared ‘bfd’ and ‘gdb’ libraries built, but not shared ‘libg++’, you can run all three configure scripts as follows:

          trick$ ./configure --enable-shared=bfd,gdb

In general, specifying –enable-shared=pkgs is the same as configuring with –enable-shared every package named in the comma-separated pkgs list, and every other package with –disable-shared. The –enable-static=pkgs flag behaves similarly, but it uses –enable-static and –disable-static. The same applies to the –enable-fast-install=pkgs flag, which uses –enable-fast-install and –disable-fast-install.

The package name ‘default’ matches any packages that have not set their name in the PACKAGE environment variable.

The –with-pic and –without-pic configure flags can be used to specify whether or not libtool uses PIC objects. By default, libtool uses PIC objects for shared libraries and non-PIC objects for static libraries. The –with-pic option also accepts a comma-separated list of package names. Specifying –with-pic=pkgs is the same as configuring every package in pkgs with –with-pic and every other package with the default configuration. The package name ‘default’ is treated the same as for –enable-shared and –enable-static.

This macro also sets the shell variable LIBTOOL_DEPS, that you can use to automatically update the libtool script if it becomes out-of-date. In order to do that, add to your configure.ac:

          LT_INIT
          AC_SUBST([LIBTOOL_DEPS])

and, to Makefile.in or Makefile.am:

          LIBTOOL_DEPS = @LIBTOOL_DEPS@
          libtool: $(LIBTOOL_DEPS)
                  $(SHELL) ./config.status libtool

If you are using GNU Automake, you can omit the assignment, as Automake will take care of it. You’ll obviously have to create some dependency on libtool.

Macro: LT_LANG (language)

Enable libtool support for the language given if it has not yet already been enabled. Languages accepted are “C++”, “Fortran 77”, “Java”, “Go”, and “Windows Resource”.

If Autoconf language support macros such as AC_PROG_CXX are used in your configure.ac, Libtool language support will automatically be enabled.

Conversely using LT_LANG to enable language support for Libtool will automatically enable Autoconf language support as well.

Both of the following examples are therefore valid ways of adding C++ language support to Libtool.

          LT_INIT
          LT_LANG([C++])
          LT_INIT
          AC_PROG_CXX

Macro: AC_LIBTOOL_DLOPEN

This macro is deprecated, the ‘dlopen’ option to LT_INIT should be used instead.

Macro: AC_LIBTOOL_WIN32_DLL

This macro is deprecated, the ‘win32-dll’ option to LT_INIT should be used instead.

Macro: AC_DISABLE_FAST_INSTALL

This macro is deprecated, the ‘disable-fast-install’ option to LT_INIT should be used instead.

Macro: AC_DISABLE_SHARED
— Macro: AM_DISABLE_SHARED

Change the default behaviour for LT_INIT to disable shared libraries. The user may still override this default by specifying ‘–enable-shared’. The option ‘disable-shared’ to LT_INIT is a shorthand for this. AM_DISABLE_SHARED is a deprecated alias for AC_DISABLE_SHARED.

Macro: AC_ENABLE_SHARED
— Macro: AM_ENABLE_SHARED

Change the default behaviour for LT_INIT to enable shared libraries. This is the default on all systems where Libtool knows how to create shared libraries. The user may still override this default by specifying ‘–disable-shared’. The option ‘shared’ to LT_INIT is a shorthand for this. AM_ENABLE_SHARED is a deprecated alias for AC_ENABLE_SHARED.

Macro: AC_DISABLE_STATIC
— Macro: AM_DISABLE_STATIC

Change the default behaviour for LT_INIT to disable static libraries. The user may still override this default by specifying ‘–enable-static’. The option ‘disable-static’ to LT_INIT is a shorthand for this. AM_DISABLE_STATIC is a deprecated alias for AC_DISABLE_STATIC.

Macro: AC_ENABLE_STATIC
— Macro: AM_ENABLE_STATIC

Change the default behaviour for LT_INIT to enable static libraries. This is the default on all systems where shared libraries have been disabled for some reason, and on most systems where shared libraries have been enabled. If shared libraries are enabled, the user may still override this default by specifying ‘–disable-static’. The option ‘static’ to LT_INIT is a shorthand for this. AM_ENABLE_STATIC is a deprecated alias for AC_ENABLE_STATIC.

The tests in LT_INIT also recognize the following environment variables:

Variable: CC

The C compiler that will be used by the generated libtool. If this is not set, LT_INIT will look for gcc or cc.

Variable: CFLAGS

Compiler flags used to generate standard object files. If this is not set, LT_INIT will not use any such flags. It affects only the way LT_INIT runs tests, not the produced libtool.

Variable: CPPFLAGS

C preprocessor flags. If this is not set, LT_INIT will not use any such flags. It affects only the way LT_INIT runs tests, not the produced libtool.

Variable: LD

The system linker to use (if the generated libtool requires one). If this is not set, LT_INIT will try to find out what is the linker used by CC.

Variable: LDFLAGS

The flags to be used by libtool when it links a program. If this is not set, LT_INIT will not use any such flags. It affects only the way LT_INIT runs tests, not the produced libtool.

Variable: LIBS

The libraries to be used by LT_INIT when it links a program. If this is not set, LT_INIT will not use any such flags. It affects only the way LT_INIT runs tests, not the produced libtool.

Variable: NM

Program to use rather than checking for nm.

Variable: RANLIB

Program to use rather than checking for ranlib.

Variable: LN_S

A command that creates a link of a program, a soft-link if possible, a hard-link otherwise. LT_INIT will check for a suitable program if this variable is not set.

Variable: DLLTOOL

Program to use rather than checking for dlltool. Only meaningful for Cygwin/MS-Windows.

Variable: OBJDUMP

Program to use rather than checking for objdump. Only meaningful for Cygwin/MS-Windows.

Variable: AS

Program to use rather than checking for as. Only used on Cygwin/MS-Windows at the moment.

Variable: MANIFEST_TOOL

Program to use rather than checking for mt, the Manifest Tool. Only used on Cygwin/MS-Windows at the moment.

Macro: LT_OUTPUT

By default, the configured libtool script is generated by the call to AC_OUTPUT command, and there is rarely any need to use libtool from configure. However, sometimes it is necessary to run configure time compile and link tests using libtool. You can add LT_OUTPUT to your configure.ac any time after LT_INIT and any LT_LANG calls; that done, libtool will be created by a specially generated config.lt file, and available for use in later tests.

Also, when LT_OUTPUT is used, for backwards compatibility with Automake regeneration rules, config.status will call config.lt to regenerate libtool, rather than generating the file itself.

When you invoke the libtoolize program (see Invoking libtoolize), it will tell you where to find a definition of LT_INIT. If you use Automake, the aclocal program will automatically add LT_INIT support to your configure script when it sees the invocation of LT_INIT in configure.ac.

5.5 Including libtool in your package

In order to use libtool, you need to include the following files with your package:

config.guess
Attempt to guess a canonical system name.
config.sub
Canonical system name validation subroutine script.
install-sh
BSD-compatible install replacement script.
ltmain.sh
A generic script implementing basic libtool functionality.

Note that the libtool script itself should not be included with your package. See Configuring.

You should use the libtoolize program, rather than manually copying these files into your package.

5.5.1 Invoking libtoolize

The libtoolize program has the following synopsis:

     libtoolize [option]...

and accepts the following options:

–copy
-c
Copy files from the libtool data directory rather than creating symlinks.
–debug
Dump a trace of shell script execution to standard output. This produces a lot of output, so you may wish to pipe it to less (or more) or redirect to a file.
–dry-run
-n
Don’t run any commands that modify the file system, just print them out.
–force
-f
Replace existing libtool files. By default, libtoolize won’t overwrite existing files.
–help
Display a help message and exit.
–ltdl [target-directory-name]
Install libltdl in the target-directory-name subdirectory of your package. Normally, the directory is extracted from the argument to LT_CONFIG_LTDL_DIR in configure.ac, though you can also specify a subdirectory name here if you are not using Autoconf for example. If libtoolize can’t determine the target directory, ‘libltdl’ is used as the default.
–no-warn
Normally, Libtoolize tries to diagnose use of deprecated libtool macros and other stylistic issues. If you are deliberately using outdated calling conventions, this option prevents Libtoolize from explaining how to update your project’s Libtool conventions.
–nonrecursive
If passed in conjunction with –ltdl, this option will cause the libltdl installed by ‘libtoolize’ to be set up for use with a non-recursive automake build. To make use of it, you will need to add the following to the Makefile.am of the parent project:
          ## libltdl/Makefile.inc appends to the following variables
          ## so we set them here before including it:
          BUILT_SOURCES =

          AM_CPPFLAGS =
          AM_LDFLAGS =

          include_HEADERS =
          noinst_LTLIBRARIES =
          lib_LTLIBRARIES =
          EXTRA_LTLIBRARIES =

          EXTRA_DIST =

          CLEANFILES =
          MOSTLYCLEANFILES =

          include libltdl/Makefile.inc
–quiet
-q
Work silently. ‘libtoolize –quiet’ is used by GNU Automake to add libtool files to your package if necessary.
–recursive
If passed in conjunction with –ltdl, this option will cause the libtoolize installed ‘libltdl’ to be set up for use with a recursive automake build. To make use of it, you will need to adjust the parent project’s configure.ac:
          AC_CONFIG_FILES([libltdl/Makefile])

and Makefile.am:

          SUBDIRS += libltdl
–subproject
If passed in conjunction with –ltdl, this option will cause the libtoolize installed ‘libltdl’ to be set up for independent configuration and compilation as a self-contained subproject. To make use of it, you should arrange for your build to call libltdl/configure, and then run make in the libltdl directory (or the subdirectory you put libltdl into). If your project uses Autoconf, you can use the supplied ‘LT_WITH_LTDL’ macro, or else call ‘AC_CONFIG_SUBDIRS’ directly.
Previous releases of ‘libltdl’ built exclusively in this mode, but now it is the default mode both for backwards compatibility and because, for example, it is suitable for use in projects that wish to use ‘libltdl’, but not use the Autotools for their own build process.
–verbose
-v
Work noisily! Give a blow by blow account of what libtoolize is doing.

If libtoolize detects an explicit call to AC_CONFIG_AUX_DIR (see The Autoconf Manual) in your configure.ac, it will put the other support files in the specified directory. Otherwise they too end up in the project root directory.

5.5.2 Autoconf and LTLIBOBJS

People used to add code like the following to their configure.ac:

     LTLIBOBJS=`echo "$LIBOBJS" | sed 's/\.[^.]* /.lo /g;s/\.[^.]*$/.lo/'`
     AC_SUBST([LTLIBOBJS])

Provided you are using a recent (2.54 or better) incarnation of Autoconf, the call to AC_OUTPUT takes care of setting LTLIBOBJS up correctly, so you can simply delete such snippets from your configure.ac if you had them.

7.3 Updating library version information

This flag accepts an argument of the form ‘current[:revision[:age]]’. So, passing -version-info 3:12:1 sets current to 3, revision to 12, and age to 1.

8 Tips for interface design

Here is a brief list of tips for library interface design that may help you in your exploits:

Plan ahead
Try to make every interface truly minimal, so that you won’t need to delete entry points very often.
Avoid interface changes
Some people love redesigning and changing entry points just for the heck of it (note: renaming a function is considered changing an entry point). Don’t be one of those people. If you must redesign an interface, then try to leave compatibility functions behind so that users don’t need to rewrite their existing code.
Use opaque data types
The fewer data type definitions a library user has access to, the better. If possible, design your functions to accept a generic pointer (that you can cast to an internal data type), and provide access functions rather than allowing the library user to directly manipulate the data. That way, you have the freedom to change the data structures without changing the interface.
This is essentially the same thing as using abstract data types and inheritance in an object-oriented system.
Use header files
If you are careful to document each of your library’s global functions and variables in header files, and include them in your library source files, then the compiler will let you know if you make any interface changes by accident (see C header files).
Use the static keyword (or equivalent) whenever possible
The fewer global functions your library has, the more flexibility you’ll have in changing them. Static functions and variables may change forms as often as you like your users cannot access them, so they aren’t interface changes.
Be careful with array dimensions
The number of elements in a global array is part of an interface, even if the header just declares extern int foo[];. This is because on i386 and some other SVR4/ELF systems, when an application references data in a shared library the size of that data (whatever its type) is included in the application executable. If you might want to change the size of an array or string then provide a pointer not the actual array.

8.1 Writing C header files

Do not be naive about writing portable code. Following the tips given above will help you miss the most obvious problems, but there are definitely other subtle portability issues. You may need to cope with some of the following issues:

  • Pre-ANSI compilers do not always support the void * generic pointer type, and so need to use char * in its place.
  • The const, inline and signed keywords are not supported by some compilers, especially pre-ANSI compilers.

The long double type is not supported by many compilers.

10 Dlopened modules

It can sometimes be confusing to discuss dynamic linking, because the term is used to refer to two different concepts:

  1. Compiling and linking a program against a shared library, which is resolved automatically at run time by the dynamic linker. In this process, dynamic linking is transparent to the application.
  2. The application calling functions such as dlopen that load arbitrary, user-specified modules at runtime. This type of dynamic linking is explicitly controlled by the application.

To mitigate confusion, this manual refers to the second type of dynamic linking as dlopening a module.

Libtool provides support for dlopened modules. However, you should indicate that your package is willing to use such support, by using the LT_INIT option ‘dlopen’ in configure.ac. If this option is not given, libtool will assume no dlopening mechanism is available, and will try to simulate it.

10.1 Building modules to dlopen

For example, if we wanted to build a shared library, hello, that would later be dlopened by an application, we would add -module to the other link flags:

     burger$ libtool --mode=link gcc -module -o hello.la foo.lo \
                     hello.lo -rpath /usr/local/lib -lm
     burger$

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*