libtool.info-3   [plain text]


This is libtool.info, produced by makeinfo version 4.0 from
libtool.texi.

INFO-DIR-SECTION GNU programming tools
START-INFO-DIR-ENTRY
* Libtool: (libtool).           Generic shared library support script.
END-INFO-DIR-ENTRY

INFO-DIR-SECTION Individual utilities
START-INFO-DIR-ENTRY
* libtoolize: (libtool)Invoking libtoolize.     Adding libtool support.
END-INFO-DIR-ENTRY

   This file documents GNU Libtool 1.4.2

   Copyright (C) 1996-2000 Free Software Foundation, Inc.

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with the
no Invariant Sections, with no Front-Cover Texts, and with no
Back-Cover Texts.  A copy of the license is included in the section
entitled "GNU Free Documentation License".


File: libtool.info,  Node: Libltdl interface,  Next: Modules for libltdl,  Up: Using libltdl

How to use libltdl in your programs
===================================

The libltdl API is similar to the dlopen interface of Solaris and Linux,
which is very simple but powerful.

To use libltdl in your program you have to include the header file
`ltdl.h':

     #include <ltdl.h>

The last release of libltdl used some symbols that violated the POSIX
namespace conventions.  These symbols are now deprecated, and have been
replaced by those described here.  If you have code that relies on the
old deprecated symbol names, defining `LT_NON_POSIX_NAMESPACE' before
you include `ltdl.h' provides conversion macros.  Whichever set of
symbols you use, the new api is not binary compatible with the last, so
you will need to recompile your application in order to use this
version of libltdl.

Note that libltdl is not threadsafe, i.e. a multithreaded application
has to use a mutex for libltdl.  It was reported that GNU/Linux's glibc
2.0's `dlopen' with `RTLD_LAZY' (which libltdl uses by default) is not
thread-safe, but this problem is supposed to be fixed in glibc 2.1.  On
the other hand, `RTLD_NOW' was reported to introduce problems in
multi-threaded applications on FreeBSD.  Working around these problems
is left as an exercise for the reader; contributions are certainly
welcome.

The following types are defined in `ltdl.h':

 - Type: lt_ptr
     `lt_ptr' is a generic pointer.

 - Type: lt_dlhandle
     `lt_dlhandle' is a module "handle".  Every lt_dlopened module has
     a handle associated with it.

 - Type: lt_dlsymlist
     `lt_dlsymlist' is a symbol list for dlpreopened modules.  This
     structure is described in *note Dlpreopening::.

libltdl provides the following functions:

 - Function: int lt_dlinit (void)
     Initialize libltdl.  This function must be called before using
     libltdl and may be called several times.  Return 0 on success,
     otherwise the number of errors.

 - Function: int lt_dlexit (void)
     Shut down libltdl and close all modules.  This function will only
     then shut down libltdl when it was called as many times as
     `lt_dlinit' has been successfully called.  Return 0 on success,
     otherwise the number of errors.

 - Function: lt_dlhandle lt_dlopen (const char *FILENAME)
     Open the module with the file name FILENAME and return a handle
     for it.  `lt_dlopen' is able to open libtool dynamic modules,
     preloaded static modules, the program itself and native dynamic
     libraries.

     Unresolved symbols in the module are resolved using its dependency
     libraries (not implemented yet) and previously dlopened modules.
     If the executable using this module was linked with the
     `-export-dynamic' flag, then the global symbols in the executable
     will also be used to resolve references in the module.

     If FILENAME is `NULL' and the program was linked with
     `-export-dynamic' or `-dlopen self', `lt_dlopen' will return a
     handle for the program itself, which can be used to access its
     symbols.

     If libltdl cannot find the library and the file name FILENAME does
     not have a directory component it will additionally search in the
     following search paths for the module (in the order as follows):

       1. user-defined search path: This search path can be set by the
          program using the functions `lt_dlsetsearchpath' and
          `lt_dladdsearchdir'.

       2. libltdl's search path: This search path is the value of the
          environment variable LTDL_LIBRARY_PATH.

       3. system library search path: The system dependent library
          search path (e.g. on Linux it is LD_LIBRARY_PATH).

     Each search path must be a colon-separated list of absolute
     directories, for example, `"/usr/lib/mypkg:/lib/foo"'.

     If the same module is loaded several times, the same handle is
     returned.  If `lt_dlopen' fails for any reason, it returns `NULL'.

 - Function: lt_dlhandle lt_dlopenext (const char *FILENAME)
     The same as `lt_dlopen', except that it tries to append different
     file name extensions to the file name.  If the file with the file
     name FILENAME cannot be found libltdl tries to append the
     following extensions:

       1. the libtool archive extension `.la'

       2. the extension used for native dynamic libraries on the host
          platform, e.g., `.so', `.sl', etc.

     This lookup strategy was designed to allow programs that don't
     have knowledge about native dynamic libraries naming conventions
     to be able to `dlopen' such libraries as well as libtool modules
     transparently.

 - Function: int lt_dlclose (lt_dlhandle HANDLE)
     Decrement the reference count on the module HANDLE.  If it drops
     to zero and no other module depends on this module, then the
     module is unloaded.  Return 0 on success.

 - Function: lt_ptr lt_dlsym (lt_dlhandle HANDLE, const char *NAME)
     Return the address in the module HANDLE, where the symbol given by
     the null-terminated string NAME is loaded.  If the symbol cannot
     be found, `NULL' is returned.

 - Function: const char * lt_dlerror (void)
     Return a human readable string describing the most recent error
     that occurred from any of libltdl's functions.  Return `NULL' if
     no errors have occurred since initialization or since it was last
     called.

 - Function: int lt_dlpreload (const lt_dlsymlist *PRELOADED)
     Register the list of preloaded modules PRELOADED.  If PRELOADED is
     `NULL', then all previously registered symbol lists, except the
     list set by `lt_dlpreload_default', are deleted. Return 0 on
     success.

 - Function: int lt_dlpreload_default (const lt_dlsymlist *PRELOADED)
     Set the default list of preloaded modules to PRELOADED, which
     won't be deleted by `lt_dlpreload'.  Note that this function does
     _not_ require libltdl to be initialized using `lt_dlinit' and can
     be used in the program to register the default preloaded modules.
     Instead of calling this function directly, most programs will use
     the macro `LTDL_SET_PRELOADED_SYMBOLS'.

     Return 0 on success.

 - Macro: LTDL_SET_PRELOADED_SYMBOLS()
     Set the default list of preloaded symbols.  Should be used in your
     program to initialize libltdl's list of preloaded modules.

          #include <ltdl.h>
          
          int main() {
            /* ... */
            LTDL_SET_PRELOADED_SYMBOLS();
            /* ... */
          }

 - Function: int lt_dladdsearchdir (const char *SEARCH_DIR)
     Add the search directory SEARCH_DIR to the user-defined library
     search path. Return 0 on success.

 - Function: int lt_dlsetsearchpath (const char *SEARCH_PATH)
     Replace the current user-defined library search path with
     SEARCH_PATH, which must be a colon-separated list of absolute
     directories.  Return 0 on success.

 - Function: const char * lt_dlgetsearchpath (void)
     Return the current user-defined library search path.

 - Function: int lt_dlmakeresident (lt_dlhandle HANDLE)
     Mark a module so that it cannot be `lt_dlclose'd.  This can be
     useful if a module implements some core functionality in your
     project, which would cause your code to crash if removed.  Return
     0 on success.

     If you use `lt_dlopen (NULL)' to get a HANDLE for the running
     binary, that handle will always be marked as resident, and
     consequently cannot be successfully `lt_dlclose'd.

 - Function: int lt_dlisresident (lt_dlhandle HANDLE)
     Check whether a particular module has been marked as resident,
     returning 1 if it has or 0 otherwise.  If there is an error while
     executing this function, return -1 and set an error message for
     retrieval with `lt_dlerror'.

 - Variable: lt_ptr (*) (size_t SIZE) lt_dlmalloc
 - Variable: void (*) (lt_ptr PTR) lt_dlfree
     These variables are set to `malloc' and `free', by default, but
     you can set them to any other functions that provides equivalent
     functionality.  However, you must not modify their values after
     calling any libltdl function other than `lt_dlpreopen_default' or
     the macro `LTDL_SET_PRELOADED_SYMBOLS'.


File: libtool.info,  Node: Modules for libltdl,  Next: Thread Saftey in libltdl,  Prev: Libltdl interface,  Up: Using libltdl

Creating modules that can be `dlopen'ed
=======================================

   Libtool modules are like normal libtool libraries with a few
exceptions:

   You have to link the module with libtool's `-module' switch, and you
should link any program that is intended to dlopen the module with
`-dlopen modulename.la' so that libtool can dlpreopen the module on
platforms which don't support dlopening.  If the module depends on any
other libraries, make sure you specify them either when you link the
module or when you link programs that dlopen it.  If you want to
disable *note Versioning:: for a specific module you should link it
with the `-avoid-version' switch.  Note that libtool modules don't need
to have a "lib" prefix.  However, automake 1.4 or higher is required to
build such modules.

   Usually a set of modules provide the same interface, i.e, exports
the same symbols, so that a program can dlopen them without having to
know more about their internals.  In order to avoid symbol conflicts
all exported symbols must be prefixed with "modulename_LTX_"
(`modulename' is the name of the module).  Internal symbols must be
named in such a way that they won't conflict with other modules, for
example, by prefixing them with "_modulename_".  Although some
platforms support having the same symbols defined more than once it is
generally not portable and it makes it impossible to dlpreopen such
modules.  libltdl will automatically cut the prefix off to get the real
name of the symbol.  Additionally, it supports modules which don't use
a prefix so that you can also dlopen non-libtool modules.

   `foo1.c' gives an example of a portable libtool module.  Exported
symbols are prefixed with "foo1_LTX_", internal symbols with "_foo1_".
Aliases are defined at the beginning so that the code is more readable.

     /* aliases for the exported symbols */
     #define foo	foo1_LTX_foo
     #define bar	foo1_LTX_bar
     
     /* a global variable definition */
     int bar = 1;
     
     /* a private function */
     int _foo1_helper() {
       return bar;
     }
     
     /* an exported function */
     int foo() {
       return _foo1_helper();
     }

The `Makefile.am' contains the necessary rules to build the module
`foo1.la':

     ...
     lib_LTLIBRARIES = foo1.la
     
     foo1_la_SOURCES = foo1.c
     foo1_la_LDFLAGS = -module
     ...


File: libtool.info,  Node: Thread Saftey in libltdl,  Next: User defined module data,  Prev: Modules for libltdl,  Up: Using libltdl

Using libtldl in a multi threaded environment
=============================================

   Using the `lt_dlmutex_register()' function, and by providing some
appropriate callback function definitions, libltdl can be used in a
multi-threaded environment.

 - Type: void lt_dlmutex_lock (void)
     This is the type of a function pointer holding the address of a
     function which will be called at the start of parts of the libltdl
     implementation code which require a mutex lock.

     Because libltdl is inherantly recursive, it is important that the
     locking mechanism employed by these callback functions are
     reentrant, or else strange problems will occur.

 - Type: void lt_dlmutex_unlock (void)
     The type of a matching unlock function.

 - Type: void lt_dlmutex_seterror (const char *ERROR);
     Many of the functions in the libltdl API have a special return
     value to indicate to the client that an error has occured.
     Normally (in single threaded applications) a string describing
     that error can be retrieved from internal storage with
     `lt_dlerror()'.

     A function of this type must be registered with the library in
     order for it to work in a multi-threaded context.  The function
     should store any error message passed in thread local storage.

 - Type: const char * lt_dlmutex_geterror (void)
     The type of a matching callback function to retrieve the last
     stored error message from thread local storage.

     When regeistered correctly this function will be used by
     `lt_dlerror())' from all threads to retrieve error messages for the
     client.

 - Function: int lt_dlmutex_register (lt_dlmutex_lock *LOCK,
          lt_dlmutex_unlock *UNLOCK, lt_dlmutex_set_error *SETERROR,
          lt_dlmutex_geterror *GETERROR)
     Use this function to register one of each of function ttypes
     described above in preparation for multi-threaded use of libltdl.
     All arguments must be valid non-`NULL' function addresses, or else
     all `NULL' to return to single threaded operation.


File: libtool.info,  Node: User defined module data,  Next: Module loaders for libltdl,  Prev: Thread Saftey in libltdl,  Up: Using libltdl

Data associated with loaded modules
===================================

   Some of the internal information about each loaded module that is
maintained by libltdl is available to the user, in the form of this
structure:

 - Type: struct lt_dlinfo { char *FILENAME; char *NAME; int REF_COUNT; }
     `lt_dlinfo' is used to store information about a module.  The
     FILENAME attribute is a null-terminated character string of the
     real module file name.  If the module is a libtool module then
     NAME is its module name (e.g. `"libfoo"' for `"dir/libfoo.la"'),
     otherwise it is set to `NULL'.  The REF_COUNT attribute is a
     reference counter that describes how often the same module is
     currently loaded.

   The following function will return a pointer to libltdl's internal
copy of this structure for the given HANDLE:

 - Function: const lt_dlinfo * lt_dlgetinfo (lt_dlhandle HANDLE)
     Return a pointer to a struct that contains some information about
     the module HANDLE.  The contents of the struct must not be
     modified.  Return `NULL' on failure.

   Furthermore, in order to save you from having to keep a list of the
handles of all the modules you have loaded, these functions allow you to
iterate over libltdl's list of loaded modules:

 - Function: int lt_dlforeach
          (int (*FUNC) (lt_dlhandle HANDLE, lt_ptr DATA), lt_ptr DATA)
     For each loaded module call the function FUNC.  The argument
     HANDLE is the handle of one of the loaded modules, DATA is the
     DATA argument passed to `lt_dlforeach'.  As soon as FUNC returns a
     non-zero value for one of the handles, `lt_dlforeach' will stop
     calling FUNC and immediately return 1.  Otherwise 0 is returned.

 - Function: lt_dlhandle lt_dlhandle_next (lt_dlhandle place)
     Iterate over the loaded module handles, returning the first handle
     in the list if PLACE is `NULL', and the next one on subsequent
     calls.  If PLACE is the last element in the list of loaded
     modules, this function returns `NULL'.

   Of course, you would still need to maintain your own list of loaded
module handles to parallel the list maintained by libltdl if there are
any other data that you need to associate with each handle for the
purposes of your application.  However, if you use the following API
calls to associate your application data with individual module handles
as they are loaded there is actually no need to do that.  You must
first obtain a unique caller id from libltdl which you subsequently use
to retrieve the data you stored earlier.  This allows for different
libraries that each wish to store their own data against loaded modules
to do so without interfering with one another's data.

 - Type: lt_dlcaller_id
     The opaque type used to hold individual data set keys.

 - Function: lt_dlcaller_id lt_dlcaller_register (void)
     Use this to obtain a unique key to store and retrieve individual
     sets of per module data.

 - Function: lt_ptr lt_dlcaller_set_data (lt_dlcaller_id KEY,
          lt_dlhandle HANDLE, lt_ptr DATA)
     Set DATA as the set of data uniquely associated with KEY and
     HANDLE for later retrieval.  This function returns the DATA
     previously associated with KEY and HANDLE if any.  A result of 0,
     may indicate that a diagnostic for the last error (if any) is
     available from `lt_dlerror()'.

     For example, to correctly remove some associated data:

              lt_ptr stale = lt_dlcaller_set_data (key, handle, 0);
              if (stale == NULL)
                {
                  char *error_msg = lt_dlerror ();
          
                  if (error_msg != NULL)
                    {
                      my_error_handler (error_msg);
                      return STATUS_FAILED;
                    }
                }
              else
                {
                  free (stale);
                }

 - Function: lt_ptr lt_dlcaller_get_data (lt_dlcaller_id KEY,
          lt_dlhandle HANDLE)
     Return the address of the data associated with KEY and HANDLE, or
     else `NULL' if there is none.

   The preceding functions can be combined with `lt_dlforeach' to
implement search and apply operations without the need for your
application to track the modules that have been loaded and unloaded:

     int
     my_dlcaller_callback (lt_dlhandle handle, lt_ptr key_ptr)
     {
       struct my_module_data *my_data;
     
       my_data = lt_dlcaller_get_data (handle, (lt_dlcaller_id) *key_ptr);
     
       return process (my_data);
     }
     
     int
     my_dlcaller_foreach (lt_dlcaller_id key)
     {
       lt_dlforeach (my_dlcaller_callback, (lt_ptr) &key);
     }


File: libtool.info,  Node: Module loaders for libltdl,  Next: Distributing libltdl,  Prev: User defined module data,  Up: Using libltdl

How to create and register new module loaders
=============================================

   Sometimes libltdl's many ways of gaining access to modules are not
sufficient for the purposes of a project.  You can write your own
loader, and register it with libltdl so that `lt_dlopen' will be able
to use it.

   Writing a loader involves writing at least three functions which can
be called  by `lt_dlopen', `lt_dlsym' and `lt_dlclose'.  Optionally,
you can provide a finalisation function to perform any cleanup
operations when `lt_dlexit' executes, and a symbol prefix string which
will be prepended to any symbols passed to `lt_dlsym'.  These functions
must match the function pointer types below, after which they can be
allocated to an instance of `lt_user_dlloader' and registered.

   Registering the loader requires that you choose a name for it, so
that it can be recognised by `lt_dlloader_find' and removed with
`lt_dlloader_remove'.  The name you choose must be unique, and not
already in use by libltdl's builtin loaders:

"dlopen"
     The system dynamic library loader, if one exists.

"dld"
     The GNU dld loader, if `libdld' was installed when libltdl was
     built.

"dlpreload"
     The loader for `lt_dlopen'ing of preloaded static modules.

   The prefix "dl" is reserved for loaders supplied with future
versions of libltdl, so you should not use that for your own loader
names.

The following types are defined in `ltdl.h':

 - Type: lt_module
     `lt_module' is a dlloader dependent module.  The dynamic module
     loader extensions communicate using these low level types.

 - Type: lt_dlloader
     `lt_dlloader' is a handle for module loader types.

 - Type: lt_dlloader_data
     `lt_dlloader_data' is used for specifying loader instance data.

 - Type: struct lt_user_dlloader {const char *SYM_PREFIX;
          lt_module_open *MODULE_OPEN;lt_module_close *MODULE_CLOSE;
          lt_find_sym *FIND_SYM; lt_dlloader_exit *DLLOADER_EXIT;
          lt_dlloader_data DLLOADER_DATA; }
     If you want to define a new way to open dynamic modules, and have
     the `lt_dlopen' API use it, you need to instantiate one of these
     structures and pass it to `lt_dlloader_add'.  You can pass whatever
     you like in the DLLOADER_DATA field, and it will be passed back as
     the value of the first parameter to each of the functions
     specified in the function pointer fields.

 - Type: lt_module lt_module_open (lt_user_data LOADER_DATA,
          const char *FILENAME)
     The type of the loader function for an `lt_dlloader' module
     loader.  The value set in the dlloader_data field of the `struct
     lt_user_dlloader' structure will be passed into this function in
     the LOADER_DATA parameter.  Implementation of such a function
     should attempt to load the named module, and return an `lt_module'
     suitable for passing in to the associated `lt_module_close' and
     `lt_sym_find' function pointers.  If the function fails it should
     return `NULL', and set the error message with `lt_dlseterror'.

 - Type: int lt_module_close (lt_dlloader_data LOADER_DATA,
          lt_module MODULE)
     The type of the unloader function for a user defined module loader.
     Implementatation of such a function should attempt to release any
     resources tied up by the MODULE module, and then unload it from
     memory.  If the function fails for some reason, set the error
     message with `lt_dlseterror' and return non-zero.

 - Type: lt_ptr lt_find_sym (lt_user_data LOADER_DATA,
          lt_module MODULE, const char *SYMBOL)
     The type of the symbol lookup function for a user defined module
     loader.  Implementation of such a function should return the
     address of the named SYMBOL in the module MODULE, or else set the
     error message with `lt_dlseterror' and return `NULL' if lookup
     fails.

 - Type: int lt_dlloader_exit (lt_user_data LOADER_DATA)
     The type of the finalisation function for a user defined module
     loader.  Implementation of such a function should free any
     resources associated with the loader, including any user specified
     data in the `dlloader_data' field of the `lt_user_dlloader'.  If
     non-`NULL', the function will be called by `lt_dlexit', and
     `lt_dlloader_remove'.

   For example:

     int
     register_myloader (void)
     {
       lt_user_dlloader dlloader;
     
       /* User modules are responsible for their own initialisation. */
       if (myloader_init () != 0)
         return MYLOADER_INIT_ERROR;
     
       dlloader.sym_prefix    = NULL;
       dlloader.module_open   = myloader_open;
       dlloader.module_close  = myloader_close;
       dlloader.find_sym      = myloader_find_sym.
       dlloader.dlloader_exit = myloader_exit;
       dlloader.dlloader_data = (lt_user_data)myloader_function;
     
       /* Add my loader as the default module loader. */
       if (lt_dlloader_add (lt_dlloader_next (NULL), &dlloader, "myloader") != 0)
         return ERROR;
     
       return OK;
     }

   Note that if there is any initialisation required for the loader, it
must be performed manually before the loader is registered - libltdl
doesn't handle user loader initialisation.

   Finalisation _is_ handled by libltdl however, and it is important to
ensure the `dlloader_exit' callback releases any resources claimed
during the initialisation phase.

libltdl provides the following functions for writing your own module
loaders:

 - Function: int lt_dlloader_add (lt_dlloader *PLACE,
          lt_user_dlloader *DLLOADER, const char *LOADER_NAME)
     Add a new module loader to the list of all loaders, either as the
     last loader (if PLACE is `NULL'), else immediately before the
     loader passed as PLACE.  LOADER_NAME will be returned by
     `lt_dlloader_name' if it is subsequently passed a newly registered
     loader.  These LOADER_NAMEs must be unique, or
     `lt_dlloader_remove' and `lt_dlloader_find' cannot work. Returns 0
     for success.

          {
            /* Make myloader be the last one. */
            if (lt_dlloader_add (NULL, myloader) != 0)
              perror (lt_dlerror ());
          }

 - Function: int lt_dlloader_remove (const char *LOADER_NAME)
     Remove the loader identified by the unique name, LOADER_NAME.
     Before this can succeed, all modules opened by the named loader
     must have been closed.  Returns 0 for success, otherwise an error
     message can be obtained from `lt_dlerror'.

          {
            /* Remove myloader. */
            if (lt_dlloader_remove ("myloader") != 0)
              perror (lt_dlerror ());
          }

 - Function: lt_dlloader * lt_dlloader_next (lt_dlloader *PLACE)
     Iterate over the module loaders, returning the first loader if
     PLACE is `NULL', and the next one on subsequent calls. The handle
     is for use with `lt_dlloader_add'.

          {
            /* Make myloader be the first one. */
            if (lt_dlloader_add (lt_dlloader_next (NULL), myloader) != 0)
              return ERROR;
          }

 - Function: lt_dlloader * lt_dlloader_find (const char *LOADER_NAME)
     Return the first loader with a matching LOADER_NAME identifier, or
     else `NULL', if the identifier is not found.

     The identifiers which may be used by libltdl itself, if the host
     architecture supports them are "dlopen"(1), "dld" and "dlpreload".

          {
            /* Add a user loader as the next module loader to be tried if
               the standard dlopen loader were to fail when lt_dlopening. */
            if (lt_dlloader_add (lt_dlloader_find ("dlopen"), myloader) != 0)
              return ERROR;
          }

 - Function: const char * lt_dlloader_name (lt_dlloader *PLACE)
     Return the identifying name of PLACE, as obtained from
     `lt_dlloader_next' or `lt_dlloader_find'.  If this function fails,
     it will return `NULL' and set an error for retrieval with
     `lt_dlerror'.

 - Function: lt_user_data * lt_dlloader_data (lt_dlloader *PLACE)
     Return the address of the `dlloader_data' of PLACE, as obtained
     from `lt_dlloader_next' or `lt_dlloader_find'.  If this function
     fails, it will return `NULL' and set an error for retrieval with
     `lt_dlerror'.

Error handling within user module loaders
-----------------------------------------

 - Function: int lt_dladderror (const char *DIAGNOSTIC)
     This function allows you to integrate your own error messages into
     `lt_dlerror'.  Pass in a suitable diagnostic message for return by
     `lt_dlerror', and an error identifier for use with `lt_dlseterror'
     is returned.

     If the allocation of an identifier fails, this function returns -1.

          int myerror = lt_dladderror ("Doh!");
          if (myerror < 0)
            perror (lt_dlerror ());

 - Function: int lt_dlseterror (int ERRORCODE)
     When writing your own module loaders, you should use this function
     to raise errors so that they are propogated through the
     `lt_dlerror' interface. All of the standard errors used by libltdl
     are declared in `ltdl.h', or you can add more of your own with
     `lt_dladderror'.  This function returns 0 on success.

          if (lt_dlseterror (LTDL_ERROR_NO_MEMORY) != 0)
            perror (lt_dlerror ());

   ---------- Footnotes ----------

   (1) This is used for the host dependent module loading API -
`shl_load' and `LoadLibrary' for example


File: libtool.info,  Node: Distributing libltdl,  Prev: Module loaders for libltdl,  Up: Using libltdl

How to distribute libltdl with your package
===========================================

   Even though libltdl is installed together with libtool, you may wish
to include libltdl in the distribution of your package, for the
convenience of users of your package that don't have libtool or libltdl
installed.  In this case, you must decide whether to manually add the
`ltdl' objects to your package, or else which flavor of libltdl you
want to use: a convenience library or an installable libtool library.

   The most simplistic way to add `libltdl' to your package is to copy
the source files, `ltdl.c' and `ltdl.h', to a source directory withing
your package and to build and link them along with the rest of your
sources.  To help you do this, the m4 macros for autoconf are available
in `ltdl.m4'.  You must ensure that they are available in `aclocal.m4'
before you run autoconf - by appending the contents of `ltdl.m4' to
`acinclude.m4', if you are using automake, or to `aclocal.m4' if you
are not.  Having made the macros available, you must add a call to the
`AC_LIB_LTDL' macro to your package's `configure.in' to perform the
configure time checks required to build `ltdl.o' correctly.  This
method has problems if you then try to link the package binaries with
an installed libltdl, or a library which depends on libltdl: you may
have problems with duplicate symbol definitions.

   One advantage of the convenience library is that it is not
installed, so the fact that you use libltdl will not be apparent to the
user, and it will not overwrite a pre-installed version of libltdl a
user might have.  On the other hand, if you want to upgrade libltdl for
any reason (e.g. a bugfix) you'll have to recompile your package
instead of just replacing an installed version of libltdl.  However, if
your programs or libraries are linked with other libraries that use
such a pre-installed version of libltdl, you may get linker errors or
run-time crashes.  Another problem is that you cannot link the
convenience library into more than one libtool library, then link a
single program with these libraries, because you may get duplicate
symbols. In general you can safely use the convenience library in
programs which don't depend on other libraries that might use libltdl
too.  In order to enable this flavor of libltdl, you should add the
line `AC_LIBLTDL_CONVENIENCE' to your `configure.in', _before_
`AC_PROG_LIBTOOL'.

   In order to select the installable version of libltdl, you should
add a call of the macro `AC_LIBLTDL_INSTALLABLE' to your `configure.in'
_before_ `AC_PROG_LIBTOOL'.  This macro will check whether libltdl is
already installed and, if not, request the libltdl embedded in your
package to be built and installed.  Note, however, that no version
checking is performed.  The user may override the test and determine
that the libltdl embedded must be installed, regardless of the
existence of another version, using the configure switch
`--enable-ltdl-install'.

   In order to embed libltdl into your package, just add `--ltdl' to
the `libtoolize' command line. It will copy the libltdl sources to a
subdirectory `libltdl' in your package.  Both macros accept an optional
argument to specify the location of the `libltdl' directory. By the
default both macros assume that it is `${top_srcdir}/libltdl'.

   Whatever macro you use, it is up to you to ensure that your
`configure.in' will configure libltdl, using `AC_CONFIG_SUBDIRS', and
that your `Makefile's will start sub-makes within libltdl's directory,
using automake's SUBDIRS, for example.  Both macros define the shell
variables LIBLTDL, to the link flag that you should use to link with
libltdl, and INCLTDL, to the preprocessor flag that you should use to
compile with programs that include `ltdl.h'.  It is up to you to use
`AC_SUBST' to ensure that this variable will be available in
`Makefile's, or add them to variables that are `AC_SUBST'ed by default,
such as LIBS and CPPFLAGS.

   If you're using the convenience libltdl, LIBLTDL will be the
pathname for the convenience version of libltdl and INCLTDL will be
`-I' followed by the directory that contains libltdl, both starting
with `${top_builddir}/' or `${top_srcdir}/', respectively.

   If you request an installed version of libltdl and one is found(1),
LIBLTDL will be set to `-lltdl' and INCLTDL will be empty (which is
just a blind assumption that `ltdl.h' is somewhere in the include path
if libltdl is in the library path).  If an installable version of
libltdl must be built, its pathname, starting with `${top_builddir}/',
will be stored in LIBLTDL, and INCLTDL will be set just like in the
case of convenience library.

   So, when you want to link a program with libltdl, be it a
convenience, installed or installable library, just compile with
`$(INCLTDL)' and link it with `$(LIBLTDL)', using libtool.

   You should probably also add `AC_LIBTOOL_DLOPEN' to your
`configure.in' _before_ `AC_PROG_LIBTOOL', otherwise libtool will
assume no dlopening mechanism is supported, and revert to dlpreopening,
which is probably not what you want.

   Avoid using the `-static' or `-all-static' switches when linking
programs with libltdl.  This will not work on all platforms, because
the dlopening functions may not be available for static linking.

   The following example shows you how to embed the convenience libltdl
in your package.  In order to use the installable variant just replace
`AC_LIBLTDL_CONVENIENCE' with `AC_LIBLTDL_INSTALLABLE'.  We assume that
libltdl was embedded using `libtoolize --ltdl'.

   configure.in:
     ...
     dnl Enable building of the convenience library
     dnl and set LIBLTDL accordingly
     AC_LIBLTDL_CONVENIENCE
     dnl Substitute INCLTDL and LIBLTDL in the Makefiles
     AC_SUBST(INCLTDL)
     AC_SUBST(LIBLTDL)
     dnl Check for dlopen support
     AC_LIBTOOL_DLOPEN
     dnl Configure libtool
     AC_PROG_LIBTOOL
     dnl Configure libltdl
     AC_CONFIG_SUBDIRS(libltdl)
     ...

   Makefile.am:
     ...
     SUBDIRS = libltdl
     
     INCLUDES = $(INCLTDL)
     
     myprog_LDFLAGS = -export-dynamic
     # The quotes around -dlopen below fool automake <= 1.4 into accepting it
     myprog_LDADD = $(LIBLTDL) "-dlopen" self "-dlopen" foo1.la
     myprog_DEPENDENCIES = $(LIBLTDL) foo1.la
     ...

   ---------- Footnotes ----------

   (1) Even if libltdl is installed, `AC_LIBLTDL_INSTALLABLE' may fail
to detect it, if libltdl depends on symbols provided by libraries other
than the C library.  In this case, it will needlessly build and install
libltdl.


File: libtool.info,  Node: Other languages,  Next: Troubleshooting,  Prev: Using libltdl,  Up: Top

Using libtool with other languages
**********************************

   Libtool was first implemented in order to add support for writing
shared libraries in the C language.  However, over time, libtool is
being integrated with other languages, so that programmers are free to
reap the benefits of shared libraries in their favorite programming
language.

   This chapter describes how libtool interacts with other languages,
and what special considerations you need to make if you do not use C.

* Menu:

* C++ libraries::


File: libtool.info,  Node: C++ libraries,  Up: Other languages

Writing libraries for C++
=========================

   Creating libraries of C++ code should be a fairly straightforward
process, because its object files differ from C ones in only three ways:

  1. Because of name mangling, C++ libraries are only usable by the C++
     compiler that created them.  This decision was made by the
     designers of C++ in order to protect users from conflicting
     implementations of features such as constructors, exception
     handling, and RTTI.

  2. On some systems, the C++ compiler must take special actions for the
     dynamic linker to run dynamic (i.e., run-time) initializers.  This
     means that we should not call `ld' directly to link such
     libraries, and we should use the C++ compiler instead.

  3. C++ compilers will link some Standard C++ library in by default,
     but libtool does not know which are these libraries, so it cannot
     even run the inter-library dependence analyzer to check how to
     link it in.  Therefore, running `ld' to link a C++ program or
     library is deemed to fail.  However, running the C++ compiler
     directly may lead to problems related with inter-library
     dependencies.

   The conclusion is that libtool is not ready for general use for C++
libraries.  You should avoid any global or static variable
initializations that would cause an "initializer element is not
constant" error if you compiled them with a standard C compiler.

   There are other ways of working around this problem, but they are
beyond the scope of this manual.

   Furthermore, you'd better find out, at configure time, what are the
C++ Standard libraries that the C++ compiler will link in by default,
and explicitly list them in the link command line.  Hopefully, in the
future, libtool will be able to do this job by itself.


File: libtool.info,  Node: Troubleshooting,  Next: Maintaining,  Prev: Other languages,  Up: Top

Troubleshooting
***************

   Libtool is under constant development, changing to remain up-to-date
with modern operating systems.  If libtool doesn't work the way you
think it should on your platform, you should read this chapter to help
determine what the problem is, and how to resolve it.

* Menu:

* Libtool test suite::          Libtool's self-tests.
* Reporting bugs::              How to report problems with libtool.


File: libtool.info,  Node: Libtool test suite,  Next: Reporting bugs,  Up: Troubleshooting

The libtool test suite
======================

   Libtool comes with its own set of programs that test its
capabilities, and report obvious bugs in the libtool program.  These
tests, too, are constantly evolving, based on past problems with
libtool, and known deficiencies in other operating systems.

   As described in the `INSTALL' file, you may run `make check' after
you have built libtool (possibly before you install it) in order to
make sure that it meets basic functional requirements.

* Menu:

* Test descriptions::           The contents of the test suite.
* When tests fail::             What to do when a test fails.


File: libtool.info,  Node: Test descriptions,  Next: When tests fail,  Up: Libtool test suite

Description of test suite
-------------------------

   Here is a list of the current programs in the test suite, and what
they test for:

`cdemo-conf.test'
`cdemo-exec.test'
`cdemo-make.test'
`cdemo-static.test'
`cdemo-shared.test'
     These programs check to see that the `cdemo' subdirectory of the
     libtool distribution can be configured and built correctly.

     The `cdemo' subdirectory contains a demonstration of libtool
     convenience libraries, a mechanism that allows build-time static
     libraries to be created, in a way that their components can be
     later linked into programs or other libraries, even shared ones.

     The tests `cdemo-make.test' and `cdemo-exec.test' are executed
     three times, under three different libtool configurations:
     `cdemo-conf.test' configures `cdemo/libtool' to build both static
     and shared libraries (the default for platforms that support
     both), `cdemo-static.test' builds only static libraries
     (`--disable-shared'), and `cdemo-shared.test' builds only shared
     libraries (`--disable-static').

`demo-conf.test'
`demo-exec.test'
`demo-inst.test'
`demo-make.test'
`demo-unst.test'
`demo-static.test'
`demo-shared.test'
`demo-nofast.test'
`demo-pic.test'
`demo-nopic.test'
     These programs check to see that the `demo' subdirectory of the
     libtool distribution can be configured, built, installed, and
     uninstalled correctly.

     The `demo' subdirectory contains a demonstration of a trivial
     package that uses libtool.  The tests `demo-make.test',
     `demo-exec.test', `demo-inst.test' and `demo-unst.test' are
     executed four times, under four different libtool configurations:
     `demo-conf.test' configures `demo/libtool' to build both static
     and shared libraries, `demo-static.test' builds only static
     libraries (`--disable-shared'), and `demo-shared.test' builds only
     shared libraries (`--disable-static').  `demo-nofast.test'
     configures `demo/libtool' to disable the fast-install mode
     (`--enable-fast-install=no').  `demo-pic.test' configures
     `demo/libtool' to prefer building PIC code (`--with-pic'),
     `demo-nopic.test' to prefer non-PIC code (`--without-pic').

`deplibs.test'
     Many systems cannot link static libraries into shared libraries.
     libtool uses a `deplibs_check_method' to prevent such cases.  This
     tests checks whether libtool's `deplibs_check_method' works
     properly.

`hardcode.test'
     On all systems with shared libraries, the location of the library
     can be encoded in executables that are linked against it *note
     Linking executables::.  This test checks the conditions under
     which your system linker hardcodes the library location, and
     guarantees that they correspond to libtool's own notion of how
     your linker behaves.

`build-relink.test'
     Checks whether variable SHLIBPATH_OVERRIDES_RUNPATH is properly
     set.  If the test fails and VERBOSE is set, it will indicate what
     the variable should have been set to.

`noinst-link.test'
     Checks whether libtool will not try to link with a previously
     installed version of a library when it should be linking with a
     just-built one.

`depdemo-conf.test'
`depdemo-exec.test'
`depdemo-inst.test'
`depdemo-make.test'
`depdemo-unst.test'
`depdemo-static.test'
`depdemo-shared.test'
`depdemo-nofast.test'
     These programs check to see that the `depdemo' subdirectory of the
     libtool distribution can be configured, built, installed, and
     uninstalled correctly.

     The `depdemo' subdirectory contains a demonstration of
     inter-library dependencies with libtool.  The test programs link
     some interdependent libraries.

     The tests `depdemo-make.test', `depdemo-exec.test',
     `depdemo-inst.test' and `depdemo-unst.test' are executed four
     times, under four different libtool configurations:
     `depdemo-conf.test' configures `depdemo/libtool' to build both
     static and shared libraries, `depdemo-static.test' builds only
     static libraries (`--disable-shared'), and `depdemo-shared.test'
     builds only shared libraries (`--disable-static').
     `depdemo-nofast.test' configures `depdemo/libtool' to disable the
     fast-install mode (`--enable-fast-install=no'.

`mdemo-conf.test'
`mdemo-exec.test'
`mdemo-inst.test'
`mdemo-make.test'
`mdemo-unst.test'
`mdemo-static.test'
`mdemo-shared.test'
     These programs check to see that the `mdemo' subdirectory of the
     libtool distribution can be configured, built, installed, and
     uninstalled correctly.

     The `mdemo' subdirectory contains a demonstration of a package that
     uses libtool and the system independent dlopen wrapper `libltdl' to
     load modules.  The library `libltdl' provides a dlopen wrapper for
     various platforms (Linux, Solaris, HP/UX etc.) including support
     for dlpreopened modules (*note Dlpreopening::).

     The tests `mdemo-make.test', `mdemo-exec.test', `mdemo-inst.test'
     and `mdemo-unst.test' are executed three times, under three
     different libtool configurations: `mdemo-conf.test' configures
     `mdemo/libtool' to build both static and shared libraries,
     `mdemo-static.test' builds only static libraries
     (`--disable-shared'), and `mdemo-shared.test' builds only shared
     libraries (`--disable-static').

`dryrun.test'
     This test checks whether libtool's `--dry-run' mode works properly.

`assign.test'
     Checks whether we don't put break or continue on the same line as
     an assignment in the libtool script.

`link.test'
     This test guarantees that linking directly against a non-libtool
     static library works properly.

`link-2.test'
     This test makes sure that files ending in `.lo' are never linked
     directly into a program file.

`nomode.test'
     Check whether we can actually get help for libtool.

`quote.test'
     This program checks libtool's metacharacter quoting.

`sh.test'
     Checks whether a `test' command was forgotten in libtool.

`suffix.test'
     When other programming languages are used with libtool (*note
     Other languages::), the source files may end in suffixes other
     than `.c'.  This test validates that libtool can handle suffixes
     for all the file types that it supports, and that it fails when
     the suffix is invalid.


File: libtool.info,  Node: When tests fail,  Prev: Test descriptions,  Up: Libtool test suite

When tests fail
---------------

   Each of the above tests are designed to produce no output when they
are run via `make check'.  The exit status of each program tells the
`Makefile' whether or not the test succeeded.

   If a test fails, it means that there is either a programming error in
libtool, or in the test program itself.

   To investigate a particular test, you may run it directly, as you
would a normal program.  When the test is invoked in this way, it
produces output which may be useful in determining what the problem is.

   Another way to have the test programs produce output is to set the
VERBOSE environment variable to `yes' before running them.  For
example, `env VERBOSE=yes make check' runs all the tests, and has each
of them display debugging information.


File: libtool.info,  Node: Reporting bugs,  Prev: Libtool test suite,  Up: Troubleshooting

Reporting bugs
==============

   If you think you have discovered a bug in libtool, you should think
twice: the libtool maintainer is notorious for passing the buck (or
maybe that should be "passing the bug").  Libtool was invented to fix
known deficiencies in shared library implementations, so, in a way, most
of the bugs in libtool are actually bugs in other operating systems.
However, the libtool maintainer would definitely be happy to add support
for somebody else's buggy operating system.  [I wish there was a good
way to do winking smiley-faces in Texinfo.]

   Genuine bugs in libtool include problems with shell script
portability, documentation errors, and failures in the test suite
(*note Libtool test suite::).

   First, check the documentation and help screens to make sure that the
behaviour you think is a problem is not already mentioned as a feature.

   Then, you should read the Emacs guide to reporting bugs (*note
Reporting Bugs: (emacs)Bugs.).  Some of the details listed there are
specific to Emacs, but the principle behind them is a general one.

   Finally, send a bug report to the libtool bug reporting address
<bug-libtool@gnu.org> with any appropriate _facts_, such as test suite
output (*note When tests fail::), all the details needed to reproduce
the bug, and a brief description of why you think the behaviour is a
bug.  Be sure to include the word "libtool" in the subject line, as
well as the version number you are using (which can be found by typing
`libtool --version').


File: libtool.info,  Node: Maintaining,  Next: GNU Free Documentation License,  Prev: Troubleshooting,  Up: Top

Maintenance notes for libtool
*****************************

   This chapter contains information that the libtool maintainer finds
important.  It will be of no use to you unless you are considering
porting libtool to new systems, or writing your own libtool.

* Menu:

* New ports::                   How to port libtool to new systems.
* Tested platforms::            When libtool was last tested.
* Platform quirks::             Information about different library systems.
* libtool script contents::     Configuration information that libtool uses.
* Cheap tricks::                Making libtool maintainership easier.


File: libtool.info,  Node: New ports,  Next: Tested platforms,  Up: Maintaining

Porting libtool to new systems
==============================

   Before you embark on porting libtool to an unsupported system, it is
worthwhile to send e-mail to the libtool mailing list
<libtool@gnu.org>, to make sure that you are not duplicating existing
work.

   If you find that any porting documentation is missing, please
complain!  Complaints with patches and improvements to the
documentation, or to libtool itself, are more than welcome.

* Menu:

* Information sources::         Where to find relevant documentation
* Porting inter-library dependencies::  Implementation details explained