| || |
Because libltdl supports so many different platforms(40) it needs to be configured for the host platform before it can be used.
The path of least resistance to successfully integrating libltdl into your own project, dictates that the project use Libtool for linking its module loader with libltdl. This is certainly the method I use and recommend, and is the method discussed in this chapter. However, I have seen projects which did not use Libtool ( specifically because Libtool's poor C++ support made it difficult to adopt), but which wanted the advantages of libltdl. It is possible to use libltdl entirely without Libtool, provided you take care to use the configuration macros described here, and use the results of those running these macros to determine how to link your application with libltdl.
The easiest wat to add libltdl support to your own projects is with the following simple steps:
- You must add the libltdl sources to your project distribution. If you are not already using Libtool in some capacity for your project, you should add `AC_PROG_LIBTOOL' (41) to your `configure.in' . That done, move to the top level directory of the project, and execute:
| || |
$ libtoolize --ltdl $ ls -F aclocal.m4 configure.in libltdl/ $ ls libltdl/ COPYING.LIB README aclocal.m4 configure.in stamp-h.in Makefile.am acconfig.h config.h.in ltdl.c Makefile.in acinclude.m4 configure ltdl.h
- libltdl has its own configuration to run in addition to the configuration for your project, so you must be careful to call the subdirectory configuration from your top level `configure.in' :
| || |
And you must ensure that Automake knows that it must descend into the libltdl source directory at make time, by adding the name of that subdirectory to the `SUBDIRS' macro in your top level `Makefile.am' :
- You must also arrange for the code of libltdl to be linked into your application. There are two ways to do this: as a regular Libtool library; or as a convenience library (see section Creating Convenience Libraries). Either way there are catches to be aware of, which will be addressed in a future release. Until libltdl is present on the average user 's machine, I recommend building a convenience library. You can do that in `configure.in' :
| || |
The main thing to be aware of when you follow these steps, is that you can only have one copy of the code from libltdl in any application. Once you link the objects into a library, that library will not work with any other library which has also linked with libltdl, or any application which has its own copy of the objects. If you were to try, the libltdl symbol names would clash .
The alternative is to substitute `AC_LIBLTDL_CONVENIENCE' with
`AC_LIBLTDL_INSTALLABLE' . Unfortunately there are currently many potential problems with this approach. This macro will try to find an already installed libltdl and use that, or else the embedded libltdl will be built as a standard shared library, which must be installed along with any libraries or applications that use it. There is no testing for version compatibility, so it is possible that two or more applications that use this method will overwrite one anothers copies of the installed libraries and headers. Also, the code which searches for the already installed version of libltdl tends not to find the library on many hosts , due to the native libraries it depends on being difficult to predict.
Both of the `AC_LIBLTDL_...' macros set the values of `INCLTDL' and `LIBLTDL' so that they can be used to add the correct include and library flags to the compiler in your Makefiles. They are not substituted by default. If you need to use them you must also add the following macros to your `configure.in' :
| || |
- Many of the libltdl supported hosts require that a separate shared library be linked into any application that uses dynamic runtime loading. libltdl is wrapped around this native implementation on these hosts, so it is important to link that library too. Adding support for module loading through the wrapped native implementation is independent of Libtools determination of how shared objects are compiled. On GNU/Linux, you would need to link your program with libltdl and `libdl' , for example.
Libtool installs a macro, `AC_LIBTOOL_DLOPEN' , which adds tests to your `configure' that will search for this native library. Whenever you use libltdl you should add this macro to your `configure.in' before `AC_PROG_LIBTOOL' :
| || |
AC_LIBTOOL_DLOPEN AC_LIBLTDL_CONVENIENCE AC_PROG_LIBTOOL ... AC_SUBST(INCLTDL) AC_SUBST(LIBLTDL)
`AC_LIBTOOL_DLOPEN' takes care to substitute a suitable value of `LIBADD_DL' into your `Makefile.am' , so that your code will compile correctly wherever the implementation library is discovered :
| || |
INCLUDES += @INCLTDL@ bin_PROGRAMS = your_app your_app_SOURCES = main.c support.c your_app_LDADD = @LIBLTDL@ @LIBADD_DL@
Libtool 1.4 has much improved inter-library dependency tracking code which no longer requires `@LIBADD_DL@' be explicitly referenced in your `Makefile.am' . When you install libltdl, Libtool 1.4 (or better) will make a note of any native library that libltdl depends on -- linking it automatically, provided that you link `libltdl.la' with
libtool . You might want to omit the `@LIBADD_DL@' from your `Makefile.am' in this case, if seeing the native library twice (once as a dependee of libltdl, and again as an expansion of `@LIBADD_DL@' ) on the link line bothers you.
Beyond this basic configury setup, you will also want to write some code to form a module loading subsystem for your project, and of course some modules! That process is described in Module Loader and Dynamic Module respectively.