+2000-02-05 Ossama Othman <ossama@debian.org>
+
+ * bootstrap: Merged updates from HEAD branch.
+ (sub): Added tagdemo to list of subdirectories to be
+ bootstrapped.
+ * ltcf-cxx.sh (AR): Removed redefinition of $AR to C++ compiler on
+ Solaris for the Sun C++ and Green Hills C++ compilers. `ar' must
+ be used to extract object files from the archives, despite the
+ fact that the archive must be created by the compiler.
+ Reported by Stephan Kulow <coolo@kde.org>
+ (predeps, postdeps): Remove any space between "-{L,R}" and the
+ path. Some compilers, such as HP aCC add space between them.
+ * ltconfig.in (dlopen, dlopen_support): Merged updates from HEAD
+ branch.
+ * ltmain.in: Merged updates from HEAD branch.
+ (libext): Do not reset $libext to `al' when creating convenience
+ libraries. Some compilers have problems with such a non-standard
+ extension.
+ Reported by Stephan Kulow <coolo@kde.org>
+ * doc/libtool.texi: Merged updates from HEAD branch.
+ * libltdl/Makefile.am, libltdl/configure.in, libltdl/ltdl.c,
+ libltdl/ltdl.h: Merged updates from HEAD branch.
+
2000-02-03 Ossama Othman <ossama@debian.org>
* ltconfig.in (available_tags): The name of each newly added
automake --gnu --add-missing
autoconf
-for sub in demo depdemo libltdl mdemo cdemo; do
+for sub in libltdl demo depdemo libltdl mdemo cdemo tagdemo; do
cd $sub
rm -f acinclude.m4
- cp ../libtool.m4 acinclude.m4
+ cat ../libtool.m4 > acinclude.m4
+ test "$sub" = libltdl && cat ../ltdl.m4 >> acinclude.m4
aclocal
test "$sub" = libltdl && autoheader
automake --gnits --add-missing
@ifinfo
This file documents GNU Libtool @value{VERSION}
-Copyright (C) 1996-1999 Free Software Foundation, Inc.
+Copyright (C) 1996-2000 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1996-1999 Free Software Foundation, Inc.
+Copyright @copyright{} 1996-2000 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
* Libltdl interface:: How to use libltdl in your programs.
* Modules for libltdl:: Creating modules that can be @code{dlopen}ed.
* Distributing libltdl:: How to distribute libltdl with your package.
+* Module loaders for libltdl:: Creating user defined module loaders.
Using libtool with other languages
Libtool provides special support for dlopening libtool object and
libtool library files, so that their symbols can be resolved @emph{even
on platforms without any @code{dlopen} and @code{dlsym}
-functions.}.
+functions}.
Consider the following alternative ways of loading code into your
program, in order of increasing ``laziness'':
* Libltdl interface:: How to use libltdl in your programs.
* Modules for libltdl:: Creating modules that can be @code{dlopen}ed.
* Distributing libltdl:: How to distribute libltdl with your package.
+* Module loaders for libltdl:: Creating user defined module loaders.
@end menu
@node Libltdl interface
@deftp {Type} lt_dlhandle
@code{lt_dlhandle} is a module "handle".
-Every dlopened module has a handle associated with it.
+Every lt_dlopened module has a handle associated with it.
@end deftp
+@deftypefn {Type} {struct} lt_dlinfo @{ @w{char *@var{filename};} @w{char *@var{name};} @w{int @var{ref_count};} @}
+@code{lt_dlinfo} is used to store information about a module.
+The @var{filename} attribute is a null-terminated character string of the
+real module file name. If the module is a libtool module then @var{name}
+is its module name (e.g. @code{"libfoo"} for @code{"dir/libfoo.la"}),
+otherwise it is set to @code{NULL}.
+The @var{ref_count} attribute is a reference counter that describes how often
+the same module is currently loaded.
+@end deftypefn
+
@deftp {Type} lt_dlsymlist
@code{lt_dlsymlist} is a symbol list for dlpreopened modules.
This structure is described in @pxref{Dlpreopening}.
flag, then the global symbols in the executable will also be used to
resolve references in the module.
-If @var{filename} is NULL and the program was linked with
+If @var{filename} is @code{NULL} and the program was linked with
@code{-export-dynamic} or @code{-dlopen self}, @code{lt_dlopen} will
return a handle for the program itself, which can be used to access its
symbols.
for example, @code{"/usr/lib/mypkg:/lib/foo"}.
If the same module is loaded several times, the same handle is returned.
-If @code{lt_dlopen} fails for any reason, it returns NULL.
+If @code{lt_dlopen} fails for any reason, it returns @code{NULL}.
@end deftypefun
@deftypefun lt_dlhandle lt_dlopenext (const char *@var{filename})
@deftypefun lt_ptr_t lt_dlsym (lt_dlhandle @var{handle}, const char *@var{name})
Return the address in the module @var{handle}, where the symbol given
by the null terminated string @var{name} is loaded.
-If the symbol cannot be found, NULL is returned.
+If the symbol cannot be found, @code{NULL} is returned.
@end deftypefun
@deftypefun {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
+Return @code{NULL} if no errors have occurred since initialization
or since it was last called.
@end deftypefun
@deftypefun int lt_dlpreload (const lt_dlsymlist *@var{preloaded})
Register the list of preloaded modules @var{preloaded}.
-If @var{preloaded} is NULL, then all previously registered
+If @var{preloaded} is @code{NULL}, then all previously registered
symbol lists, except the list set by @code{lt_dlpreload_default},
are deleted. Return 0 on success.
@end deftypefun
Return the current user-defined library search path.
@end deftypefun
-@deftypevar {lt_ptr_t (*} lt_dlmalloc ) (size_t size)
-@deftypevarx {void (*} lt_dlfree ) (lt_ptr_t ptr)
+@deftypefun {const lt_dlinfo *} lt_dlgetinfo (lt_dlhandle @var{handle})
+Return a pointer to a struct that contains some information about
+the module @var{handle}. The contents of the struct must not be modified.
+Return @code{NULL} on failure.
+@end deftypefun
+
+@deftypefun int lt_dlforeach (int (*@var{func})(lt_dlhandle @var{handle}, lt_ptr_t @var{data}), lt_ptr_t @var{data})
+For each loaded module call the function @var{func}. The argument
+@var{handle} is the handle of one of the loaded modules, @var{data} is
+the @var{data} argument passed to @code{lt_dlforeach}.
+As soon as @var{func} returns a non-zero value for one of the handles,
+@code{lt_dlforeach} will stop calling @var{func} and immediately return 1.
+Otherwise 0 is returned.
+@end deftypefun
+
+@deftypevar {lt_ptr_t (*} lt_dlmalloc ) (size_t @var{size})
+@deftypevarx {void (*} lt_dlfree ) (lt_ptr_t @var{ptr})
These variables are set to @code{malloc} and @code{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
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 may decide which flavor of libltdl you want to use: a
-convenience library or an installable libtool library.
+In this case, you must decide whether to manually add the @code{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 @code{ltdl} to your package is to copy
+the source files, @file{ltdl.c} and @file{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 @file{ltdl.m4}. You must ensure that they are available in
+@file{aclocal.m4} before you run autoconf -- by appending the contents
+of @file{ltdl.m4} to @file{acinclude.m4}, if you are using automake, or
+to @file{aclocal.m4} if you are not. Having made the macros available,
+you must add a call to the @samp{AC_LIB_LTDL} macro to your package's
+@file{configure.in} to perform the configure time checks required to
+build @file{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
...
@end example
+
+@node Module loaders for libltdl
+@section 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 @code{lt_dlopen} will be
+able to use it.
+
+Writing a loader involves writing at least three functions which can be
+called by @code{lt_dlopen}, @code{lt_dlsym} and @code{lt_dlclose}.
+Optionally, you can provide a finalisation function to perform any
+cleanup operations when @code{lt_dlexit} executes, and a symbol prefix
+string which will be prepended to any symbols passed to @code{lt_dlsym}.
+These functions must match the function pointer types below, after
+which they can be allocated to an instance of @code{lt_user_dlloader}
+and registered.
+
+Registering the loader requires that you choose a name for it, so that it
+can be recognised by @code{lt_find_dlloader} and removed with
+@code{lt_remove_dlloader}. The name you choose must be unique, and not
+already in use by libltdl's builtin loaders:
+
+@table @asis
+@item "dlopen"
+The system dynamic library loader, if one exists.
+@item "dld"
+The @sc{gnu} dld loader, if @file{libdld} wasinstalled when libltdl was
+built.
+@item "dlpreload"
+The loader for @code{lt_dlopen}ing of preloaded static modules.
+@end table
+
+The prefix "dl" is reserved for loaders supplied with future versions of
+libltdl, so you should not use that for your own loader names.
+
+@noindent
+The following types are defined in @file{ltdl.h}:
+
+@deftp {Type} lt_module_t
+@code{lt_module_t} is a dlloader dependent module.
+The dynamic module loader extensions communicate using these low
+level types.
+@end deftp
+
+@deftp {Type} lt_dlloader_t
+@code{lt_dlloader_t} is a handle for module loader types.
+@end deftp
+
+@deftypefn {Type} {struct} lt_user_dlloader @{@w{const char *@var{sym_prefix};} @w{lt_module_open_t *@var{module_open};} @w{lt_module_close_t *@var{module_close};} @w{lt_find_sym_t *@var{find_sym};} @w{lt_dlloader_exit_t *@var{dlloader_exit};} @}
+If you want to define a new way to open dynamic modules, and have the
+@code{lt_dlopen} @sc{api} use it, you need to instantiate one of these
+structures and pass it to @code{lt_add_dlloader}.
+@end deftypefn
+
+@deftypefn {Type} lt_module_t lt_module_open_t (@w{const char *@var{filename}})
+The type of the loader function for an @code{lt_dlloader_t} module
+loader. Implementation of such a function should attempt to load the
+named module, and return an @code{lt_module_t} suitable for passing in
+to the associated @code{lt_module_close_t} and @code{lt_sym_find_t}
+function pointers. If the function fails it should return NULL, and set
+the error message with @code{lt_dlseterror}.
+@end deftypefn
+
+@deftypefn {Type} int lt_module_close_t (@w{lt_module_t @var{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 @var{module} module, and then unload it
+from memory. If the function fails for some reason, set the error
+message with @code{lt_dlseterror} and return non-zero.
+@end deftypefn
+
+@deftypefn {Type} lt_ptr_t lt_find_sym_t (@w{lt_module_t @var{module},} @w{const char *@var{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
+@var{symbol} in the module @var{module}, or else set the error message
+with @code{lt_dlseterror} and return NULL if lookup fails.
+@end deftypefn
+
+@deftypefn {Type} int lt_dlloader_exit_t (void)
+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. If non-NULL, the function will be called by
+@code{lt_dlexit}.
+@end deftypefn
+
+For example:
+
+@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;
+
+ /* Add my loader as the default module loader. */
+ if (lt_add_dlloader (lt_next_dlloader (NULL), &dlloader, "myloader") != 0)
+ return ERROR;
+
+ return OK;
+@}
+@end example
+
+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 @emph{is} handled by libltdl however, and it is important
+to ensure the @code{dlloader_exit} callback releases any resources claimed
+during the initialisation phase.
+
+@page
+@noindent
+libltdl provides the following functions for writing your own module
+loaders:
+
+@deftypefun int lt_add_dlloader (@w{lt_dlloader_t *@var{place},} @w{lt_user_dlloader *@var{dlloader},} @w{const char *@var{loader_name}})
+Add a new module loader to the list of all loaders, either as the
+last loader (if @var{place} is @code{NULL}), else immediately before the
+loader passed as @var{place}. @var{loader_name} will be returned by
+@code{lt_dlloader_name} if it is subsequently passed a newly
+registered loader. These @var{loader_name}s must be unique, or
+@code{lt_remove_dlloader} and @code{lt_find_dlloader} cannot
+work. Returns 0 for success.
+
+@example
+@{
+ /* Make myloader be the last one. */
+ if (lt_add_dlloader (NULL, myloader) != 0)
+ perror (lt_dlerror ());
+@}
+@end example
+@end deftypefun
+
+@deftypefun int lt_remove_dlloader (@w{const char *@var{loader_name}})
+Remove the loader identified by the unique name, @var{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 @code{lt_dlerror}.
+
+@example
+@{
+ /* Remove myloader. */
+ if (lt_remove_dlloader ("myloader") != 0)
+ perror (lt_dlerror ());
+@}
+@end example
+@end deftypefun
+
+@deftypefun lt_dlloader_t *lt_next_dlloader (@w{lt_dlloader_t *@var{place}})
+Iterate over the module loaders, returning the first loader if @var{place} is
+@code{NULL}, and the next one on subsequent calls. The handle is for use with
+@code{lt_add_dlloader}.
+
+@example
+@{
+ /* Make myloader be the first one. */
+ if (lt_add_dlloader (lt_next_dlloader (NULL), myloader) != 0)
+ return ERROR;
+@}
+@end example
+@end deftypefun
+
+@deftypefun lt_dlloader_t *lt_find_dlloader (@w{const char *@var{loader_name}})
+Return the first loader with a matching @var{loader_name} identifier, or else
+@code{NULL}, if the identifier is not found.
+
+The identifiers which may be used by ltdl itself, if the host
+architecture supports them are @dfn{dlopen}@footnote{This is used for
+the host dependent module loading @sc{api} -- @code{shl_load} and
+@code{LoadLibrary} for example}, @dfn{dld} and @dfn{dlpreload}.
+
+@example
+@{
+ /* 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_add_dlloader (lt_find_dlloader ("dlopen"), myloader) != 0)
+ return ERROR;
+@}
+@end example
+@end deftypefun
+
+@deftypefun char *lt_dlloader_name (@w{lt_dlloader_t *@var{place}})
+Return the identifying name of @var{PLACE}, as obtained from
+@code{lt_next_dlloader} or @code{lt_find_dlloader}. If this function fails,
+it will return @code{NULL} and set an error for retrieval with
+@code{lt_dlerror}.
+@end deftypefun
+
+@subsection Error handling within user module loaders
+
+@deftypefun int lt_dladderror (@w{const char *@var{diagnostic}})
+This function allows you to integrate your own error messages into
+@code{lt_dlerror}. Pass in a suitable diagnostic message for return by
+@code{lt_dlerror}, and an error identifier for use with
+@code{lt_dlseterror} is returned.
+
+If the allocation of an identifier fails, this function returns -1.
+
+@example
+int myerror = lt_dladderror ("Doh!");
+if (myerror < 0)
+ perror (lt_dlerror ());
+@end example
+@end deftypefun
+
+@deftypefun int lt_dlseterror (@w{int @var{errorcode}})
+When writing your own module loaders, you should use this function to
+raise errors so that they are propogated through the @code{lt_dlerror}
+interface. All of the standard errors used by libltdl are declared in
+@file{ltdl.h}, or you can add more of your own with
+@code{lt_dladderror}. This function returns 0 on success.
+
+@example
+if (lt_dlseterror (LTDL_ERROR_NO_MEMORY) != 0)
+ perror (lt_dlerror ());
+@end example
+@end deftypefun
+
@node Other languages
@chapter Using libtool with other languages
@cindex C, not using
Set to @samp{yes} or @samp{no}.
@end defvar
-@defvar dlopen
+@defvar dlopen_support
Whether @code{dlopen} is supported on the platform.
Set to @samp{yes} or @samp{no}.
@end defvar
endif
libltdl_la_SOURCES = ltdl.c
-libltdl_la_LDFLAGS = -version-info 1:2:1
+libltdl_la_LDFLAGS = -no-undefined -version-info 2:0:2
libltdl_la_LIBADD = $(LIBADD_DL)
libltdlc_la_SOURCES = ltdl.c
AC_INIT(ltdl.c)
+dnl We shouldn't be using these internal macros of autoconf,
+dnl but CONFIG_AUX_DIR($with_auxdir) breaks automake.
+AC_ARG_WITH(auxdir,
+[ --with-auxdir=DIR path to autoconf auxiliary files],
+[AC_CONFIG_AUX_DIRS($with_auxdir)],
+[AC_CONFIG_AUX_DIR_DEFAULT])
+
if test -z "$enable_ltdl_install$enable_ltdl_convenience"; then
if test -f ${srcdir}/ltconfig && test -f ${srcdir}/ltmain.sh; then
# if libltdl is libtoolized, it is assumed to be stand-alone and
fi
fi
-AM_INIT_AUTOMAKE(libltdl,1.0,-)
+AM_INIT_AUTOMAKE(libltdl,1.1,-)
AM_CONFIG_HEADER(config.h)
AM_MAINTAINER_MODE
AC_PROG_CC
AC_C_CONST
AC_C_INLINE
+
+AC_LIBTOOL_WIN32_DLL
AM_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
-AC_ARG_ENABLE(ltdl-install,
-[ --enable-ltdl-install install libltdl])
-
-AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno)
-AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno)
-
-dnl Read the libtool configuration
-rm -f conftest
-./libtool --config > conftest
-. ./conftest
-rm -f conftest
-
-AC_CACHE_CHECK([which extension is used for shared libraries],
- libltdl_cv_shlibext, [dnl
-(
- last=
- for spec in $library_names_spec; do
- last="$spec"
- done
-changequote(, )
- echo "$last" | sed 's/\[.*\]//;s/^[^.]*//;s/\$.*$//;s/\.$//' > conftest
-changequote([, ])
-)
-libltdl_cv_shlibext=`cat conftest`
-rm -f conftest
-])
-if test -n "$libltdl_cv_shlibext"; then
- AC_DEFINE_UNQUOTED(LTDL_SHLIB_EXT, "$libltdl_cv_shlibext",
- [Define to the extension used for shared libraries, say, ".so". ])
-fi
-
-AC_CACHE_CHECK([which variable specifies run-time library path],
- libltdl_cv_shlibpath_var, [libltdl_cv_shlibpath_var="$shlibpath_var"])
-if test -n "$libltdl_cv_shlibpath_var"; then
- AC_DEFINE_UNQUOTED(LTDL_SHLIBPATH_VAR, "$libltdl_cv_shlibpath_var",
- [Define to the name of the environment variable that determines the dynamic library search path. ])
-fi
-
-AC_CACHE_CHECK([for objdir],
- libltdl_cv_objdir, [libltdl_cv_objdir="$objdir"])
-test -z "$libltdl_cv_objdir" && libltdl_cv_objdir=".libs"
-AC_DEFINE_UNQUOTED(LTDL_OBJDIR, "$libltdl_cv_objdir/",
- [Define to the sub-directory in which libtool stores uninstalled libraries. ])
-
-AC_HEADER_STDC
-AC_CHECK_HEADERS(malloc.h memory.h stdlib.h stdio.h ctype.h dlfcn.h dl.h dld.h)
-AC_CHECK_HEADERS(string.h strings.h, break)
-AC_CHECK_FUNCS(strchr index, break)
-AC_CHECK_FUNCS(strrchr rindex, break)
-
-AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen],
- libltdl_cv_preloaded_symbols, [dnl
- if test -n "$global_symbol_pipe"; then
- libltdl_cv_preloaded_symbols=yes
- else
- libltdl_cv_preloaded_symbols=no
- fi
-])
-if test x"$libltdl_cv_preloaded_symbols" = x"yes"; then
- AC_DEFINE(HAVE_PRELOADED_SYMBOLS, 1,
- [Define if libtool can extract symbol lists from object files. ])
-fi
-
-LIBADD_DL=
-AC_CHECK_LIB(dl, dlopen, [AC_DEFINE(HAVE_LIBDL, 1) LIBADD_DL="-ldl"],
-[AC_CHECK_FUNC(dlopen, [AC_DEFINE(HAVE_LIBDL, 1)])])
-AC_CHECK_FUNC(shl_load, [AC_DEFINE(HAVE_SHL_LOAD, 1)],
-[AC_CHECK_LIB(dld, shl_load, [AC_DEFINE(HAVE_SHL_LOAD, 1) LIBADD_DL="$LIBADD_DL -ldld"])])
-AC_CHECK_LIB(dld, dld_link, [AC_DEFINE(HAVE_DLD, 1)dnl
-test "x$ac_cv_lib_dld_shl_load" = yes || LIBADD_DL="$LIBADD_DL -ldld"])
-AC_SUBST(LIBADD_DL)
-
-if test "x$ac_cv_func_dlopen" = xyes || test "x$ac_cv_lib_dl_dlopen" = xyes; then
- LIBS_SAVE="$LIBS"
- LIBS="$LIBS $LIBADD_DL"
- AC_CHECK_FUNCS(dlerror)
- LIBS="$LIBS_SAVE"
-fi
-
-dnl Check for command to grab the raw symbol name followed
-dnl by C symbol name from nm.
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-AC_REQUIRE([AC_PROG_NM])dnl
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-AC_MSG_CHECKING([command to parse $NM output])
-AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
-[# These are sane defaults that work on at least a few old systems.
-# {They come from Ultrix. What could be older than Ultrix?!! ;)}
-
-changequote(,)dnl
-# Character class describing NM global symbol codes.
-ac_symcode='[BCDEGRST]'
-
-# Regexp to match symbols that can be accessed directly from C.
-ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
-
-# Transform the above into a raw symbol and a C symbol.
-ac_symxfrm='\1 \2\3 \3'
-
-# Transform an extracted symbol line into a proper C declaration
-ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
-
-# Define system-specific variables.
-case "$host_os" in
-aix*)
- ac_symcode='[BCDT]'
- ;;
-cygwin* | mingw*)
- ac_symcode='[ABCDGISTW]'
- ;;
-hpux*)
- ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
- ;;
-irix*)
- ac_symcode='[BCDEGRST]'
- ;;
-solaris*)
- ac_symcode='[BDT]'
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
- ac_symcode='[ABCDGISTW]'
-fi
-changequote([,])dnl
-
-# Try without a prefix undercore, then with it.
-for ac_symprfx in "" "_"; do
-
- ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($ac_symcode\)[ ][ ]*\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
-
- # Check to see that the pipe works correctly.
- ac_pipe_works=no
- rm -f conftest.$ac_ext
- cat > conftest.$ac_ext <<EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func;return 0;}
-EOF
-
- if AC_TRY_EVAL(ac_compile); then
- # Now try to grab the symbols.
- ac_nlist=conftest.nm
-
- if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
-
- # Try sorting and uniquifying the output.
- if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
- mv -f "$ac_nlist"T "$ac_nlist"
- else
- rm -f "$ac_nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
- if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
- cat <<EOF > conftest.c
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-EOF
- # Now generate the symbol file.
- eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
-
- cat <<EOF >> conftest.c
-#if defined (__STDC__) && __STDC__
-# define lt_ptr_t void *
-#else
-# define lt_ptr_t char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- lt_ptr_t address;
-}
-changequote(,)dnl
-lt_preloaded_symbols[] =
-changequote([,])dnl
-{
-EOF
- sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
- cat <<\EOF >> conftest.c
- {0, (lt_ptr_t) 0}
-};
-
-#ifdef __cplusplus
-}
-#endif
-EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- ac_save_LIBS="$LIBS"
- ac_save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$no_builtin_flag"
- if AC_TRY_EVAL(ac_link) && test -s conftest; then
- ac_pipe_works=yes
- else
- echo "configure: failed program was:" >&AC_FD_CC
- cat conftest.c >&AC_FD_CC
- fi
- LIBS="$ac_save_LIBS"
- CFLAGS="$ac_save_CFLAGS"
- else
- echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
- fi
- else
- echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
- fi
- else
- echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
- fi
- else
- echo "$progname: failed program was:" >&AC_FD_CC
- cat conftest.c >&AC_FD_CC
- fi
- rm -rf conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$ac_pipe_works" = yes; then
- if test x"$ac_symprfx" = x"_"; then
- ac_cv_sys_symbol_underscore=yes
- else
- ac_cv_sys_symbol_underscore=no
- fi
- break
- else
- ac_cv_sys_global_symbol_pipe=
- fi
-done
-])
-
-ac_result=yes
-if test -z "$ac_cv_sys_global_symbol_pipe"; then
- ac_result=no
-fi
-AC_MSG_RESULT($ac_result)
-
-dnl does the compiler prefix global symbols with an underscore?
-AC_MSG_CHECKING([for _ prefix in compiled symbols])
-AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
-[ac_cv_sys_symbol_underscore=no
-cat > conftest.$ac_ext <<EOF
-void nm_test_func(){}
-int main(){nm_test_func;return 0;}
-EOF
-if AC_TRY_EVAL(ac_compile); then
- # Now try to grab the symbols.
- ac_nlist=conftest.nm
- if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
- # See whether the symbols have a leading underscore.
- if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
- ac_cv_sys_symbol_underscore=yes
- else
- if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
- :
- else
- echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
- fi
- fi
- else
- echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
- fi
-else
- echo "configure: failed program was:" >&AC_FD_CC
- cat conftest.c >&AC_FD_CC
-fi
-rm -rf conftest*
-])
-AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
-
-if test x"$ac_cv_sys_symbol_underscore" = xyes; then
- if test x"$ac_cv_func_dlopen" = xyes ||
- test x"$ac_cv_lib_dl_dlopen" = xyes ; then
- AC_CACHE_CHECK([whether we have to add an underscore for dlsym],
- libltdl_cv_need_uscore, [dnl
- AC_TRY_RUN([
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LTDL_GLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LTDL_GLOBAL DL_GLOBAL
-# else
-# define LTDL_GLOBAL 0
-# endif
-#endif
-
-/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LTDL_LAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LTDL_LAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LTDL_LAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LTDL_LAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LTDL_LAZY_OR_NOW DL_NOW
-# else
-# define LTDL_LAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-fnord() { int i=42;}
-main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
- if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
- if(ptr1 && !ptr2) { dlclose(self); exit(0); } } exit(1); }
-], libltdl_cv_need_uscore=no, libltdl_cv_need_uscore=yes,
- libltdl_cv_need_uscore=cross
-)])
- fi
-fi
-
-if test x"$libltdl_cv_need_uscore" = xyes; then
- AC_DEFINE(NEED_USCORE, 1,
- [Define if dlsym() requires a leading underscode in symbol names. ])
-fi
+AC_LIB_LTDL
dnl Output the makefile
AC_OUTPUT(Makefile)
/* ltdl.c -- system independent dlopen wrapper
- Copyright (C) 1998-1999 Free Software Foundation, Inc.
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
Originally by Thomas Tanner <tanner@ffii.org>
This file is part of GNU Libtool.
#include "ltdl.h"
+#ifdef DLL_EXPORT
+# define LTDL_GLOBAL_DATA __declspec(dllexport)
+#else
+# define LTDL_GLOBAL_DATA
+#endif
+
/* max. filename length */
#ifndef LTDL_FILENAME_MAX
#define LTDL_FILENAME_MAX 1024
/* This accounts for the _LTX_ separator */
#define LTDL_SYMBOL_OVERHEAD 5
+/* NOTE: typedefed in ltdl.h
+ This structure is used for the list of registered loaders. */
+struct lt_dlloader_t {
+ struct lt_dlloader_t *next;
+ const char *loader_name; /* identifying name for each loader */
+ const char *sym_prefix; /* prefix for symbols */
+ lt_dlloader_exit_t *dlloader_exit;
+ lt_module_open_t *module_open;
+ lt_module_close_t *module_close;
+ lt_find_sym_t *find_sym;
+};
+
+typedef struct lt_dlhandle_t {
+ struct lt_dlhandle_t *next;
+ lt_dlloader_t *loader; /* dlopening interface */
+ lt_dlinfo info;
+ int depcount; /* number of dependencies */
+ lt_dlhandle *deplibs; /* dependencies */
+ lt_module_t module; /* system module handle */
+ lt_ptr_t system; /* system specific data */
+ lt_ptr_t app_private; /* application private data */
+} lt_dlhandle_t;
+
static const char objdir[] = LTDL_OBJDIR;
#ifdef LTDL_SHLIB_EXT
static const char shlib_ext[] = LTDL_SHLIB_EXT;
#endif
+#ifdef LTDL_SYSSEARCHPATH
+static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
+#endif
-static const char unknown_error[] = "unknown error";
-static const char dlopen_not_supported_error[] = "dlopen support not available";
-static const char file_not_found_error[] = "file not found";
-static const char no_symbols_error[] = "no symbols defined";
-static const char cannot_open_error[] = "can't open the module";
-static const char cannot_close_error[] = "can't close the module";
-static const char symbol_error[] = "symbol not found";
-static const char memory_error[] = "not enough memory";
-static const char invalid_handle_error[] = "invalid handle";
-static const char buffer_overflow_error[] = "internal buffer overflow";
-static const char shutdown_error[] = "library already shutdown";
-
-#ifndef HAVE_PRELOADED_SYMBOLS
-/* If libtool won't define it, we'd better do */
-const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
+/* Extract the diagnostic strings from the error table macro in the same
+ order as the enumberated indices in ltdl.h. */
+#define LTDL_ERROR(name, diagnostic) (diagnostic),
+static const char *ltdl_error_strings[] = {
+ ltdl_error_table
+ 0
+};
+#undef LTDL_ERROR
+
+#ifdef __STDC__
+# define LT_DLSTRERROR(name) ltdl_error_strings[LTDL_ERROR_##name]
+#else
+# define LT_DLSTRERROR(name) ltdl_error_strings[LTDL_ERROR_/**/name]
#endif
static const char *last_error = 0;
-lt_ptr_t (*lt_dlmalloc) LTDL_PARAMS((size_t size)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc;
-void (*lt_dlfree) LTDL_PARAMS((lt_ptr_t ptr)) = (void(*)LTDL_PARAMS((lt_ptr_t)))free;
-
-typedef struct lt_dltype_t {
- struct lt_dltype_t *next;
- const char *sym_prefix; /* prefix for symbols */
- int (*mod_init) LTDL_PARAMS((void));
- int (*mod_exit) LTDL_PARAMS((void));
- int (*lib_open) LTDL_PARAMS((lt_dlhandle handle, const char *filename));
- int (*lib_close) LTDL_PARAMS((lt_dlhandle handle));
- lt_ptr_t (*find_sym) LTDL_PARAMS((lt_dlhandle handle, const char *symbol));
-} lt_dltype_t;
-
-#define LTDL_TYPE_TOP 0
-
-typedef struct lt_dlhandle_t {
- struct lt_dlhandle_t *next;
- lt_dltype_t *type; /* dlopening interface */
- char *filename; /* file name */
- char *name; /* module name */
- int usage; /* usage */
- int depcount; /* number of dependencies */
- lt_dlhandle *deplibs; /* dependencies */
- lt_ptr_t handle; /* system handle */
- lt_ptr_t system; /* system specific data */
-} lt_dlhandle_t;
+LTDL_GLOBAL_DATA lt_ptr_t (*lt_dlmalloc) LTDL_PARAMS((size_t size)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc;
+LTDL_GLOBAL_DATA void (*lt_dlfree) LTDL_PARAMS((lt_ptr_t ptr)) = (void(*)LTDL_PARAMS((lt_ptr_t)))free;
#undef strdup
#define strdup xstrdup
return tmp;
}
+#if ! HAVE_STRCMP
+
+#undef strcmp
+#define strcmp xstrcmp
+
+static inline int
+strcmp (str1, str2)
+ const char *str1;
+ const char *str2;
+{
+ if (str1 == str2)
+ return 0;
+ if (str1 == 0)
+ return -1;
+ if (str2 == 0)
+ return 1;
+
+ for (;*str1 && *str2; str1++, str2++)
+ if (*str1 != *str2)
+ break;
+
+ return (int)(*str1 - *str2);
+}
+#endif
+
+
#if ! HAVE_STRCHR
# if HAVE_INDEX
#endif
-#if HAVE_LIBDL
+/* The Cygwin dlopen implementation prints a spurious error message to
+ stderr if its call to LoadLibrary() fails for any reason. We can
+ mitigate this by not using the Cygwin implementation, and falling
+ back to our own LoadLibrary() wrapper. */
+#if HAVE_LIBDL && !defined(__CYGWIN__)
/* dynamic linking with dlopen/dlsym */
# endif
#endif
-static int
-sys_dl_init LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_dl_exit LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_dl_open (handle, filename)
- lt_dlhandle handle;
+static lt_module_t
+sys_dl_open (filename)
const char *filename;
{
- handle->handle = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
- if (!handle->handle) {
+ lt_module_t module = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
+ if (!module) {
#if HAVE_DLERROR
last_error = dlerror();
#else
- last_error = cannot_open_error;
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
#endif
- return 1;
}
- return 0;
+ return module;
}
static int
-sys_dl_close (handle)
- lt_dlhandle handle;
+sys_dl_close (module)
+ lt_module_t module;
{
- if (dlclose(handle->handle) != 0) {
+ if (dlclose(module) != 0) {
#if HAVE_DLERROR
last_error = dlerror();
#else
- last_error = cannot_close_error;
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
#endif
return 1;
}
}
static lt_ptr_t
-sys_dl_sym (handle, symbol)
- lt_dlhandle handle;
+sys_dl_sym (module, symbol)
+ lt_module_t module;
const char *symbol;
{
- lt_ptr_t address = dlsym(handle->handle, symbol);
+ lt_ptr_t address = dlsym(module, symbol);
if (!address)
#if HAVE_DLERROR
last_error = dlerror();
#else
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
#endif
return address;
}
-static
-lt_dltype_t
-#ifdef NEED_USCORE
-sys_dl = { LTDL_TYPE_TOP, "_", sys_dl_init, sys_dl_exit,
- sys_dl_open, sys_dl_close, sys_dl_sym };
-#else
-sys_dl = { LTDL_TYPE_TOP, 0, sys_dl_init, sys_dl_exit,
- sys_dl_open, sys_dl_close, sys_dl_sym };
-#endif
-
-#undef LTDL_TYPE_TOP
-#define LTDL_TYPE_TOP &sys_dl
-
+static struct lt_user_dlloader sys_dl = {
+# ifdef NEED_USCORE
+ "_",
+# else
+ 0,
+# endif
+ sys_dl_open, sys_dl_close, sys_dl_sym, 0 };
#endif
#if HAVE_SHL_LOAD
#define LTDL_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
-static int
-sys_shl_init LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_shl_exit LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_shl_open (handle, filename)
- lt_dlhandle handle;
+static lt_module_t
+sys_shl_open (filename)
const char *filename;
{
- handle->handle = shl_load(filename, LTDL_BIND_FLAGS, 0L);
- if (!handle->handle) {
- last_error = cannot_open_error;
- return 1;
+ lt_module_t module = shl_load(filename, LTDL_BIND_FLAGS, 0L);
+ if (!module) {
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
}
- return 0;
+ return module;
}
static int
-sys_shl_close (handle)
- lt_dlhandle handle;
+sys_shl_close (module)
+ lt_module_t module;
{
- if (shl_unload((shl_t) (handle->handle)) != 0) {
- last_error = cannot_close_error;
+ if (shl_unload((shl_t) (module)) != 0) {
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
return 1;
}
return 0;
}
static lt_ptr_t
-sys_shl_sym (handle, symbol)
- lt_dlhandle handle;
+sys_shl_sym (module, symbol)
+ lt_module_t module;
const char *symbol;
{
lt_ptr_t address;
- if (handle->handle && shl_findsym((shl_t*) &(handle->handle),
+ if (module && shl_findsym((shl_t*) &module,
symbol, TYPE_UNDEFINED, &address) == 0)
if (address)
return address;
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
-static
-lt_dltype_t
-sys_shl = { LTDL_TYPE_TOP, 0, sys_shl_init, sys_shl_exit,
- sys_shl_open, sys_shl_close, sys_shl_sym };
+static struct lt_user_dlloader
+sys_shl = { 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0 };
#undef LTDL_TYPE_TOP
#define LTDL_TYPE_TOP &sys_shl
#endif
-#if HAVE_DLD
-
-/* dynamic linking with dld */
-
-#if HAVE_DLD_H
-#include <dld.h>
-#endif
-
-static int
-sys_dld_init LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_dld_exit LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_dld_open (handle, filename)
- lt_dlhandle handle;
- const char *filename;
-{
- handle->handle = strdup(filename);
- if (!handle->handle) {
- last_error = memory_error;
- return 1;
- }
- if (dld_link(filename) != 0) {
- last_error = cannot_open_error;
- lt_dlfree(handle->handle);
- return 1;
- }
- return 0;
-}
-
-static int
-sys_dld_close (handle)
- lt_dlhandle handle;
-{
- if (dld_unlink_by_file((char*)(handle->handle), 1) != 0) {
- last_error = cannot_close_error;
- return 1;
- }
- lt_dlfree(handle->filename);
- return 0;
-}
-
-static lt_ptr_t
-sys_dld_sym (handle, symbol)
- lt_dlhandle handle;
- const char *symbol;
-{
- lt_ptr_t address = dld_get_func(symbol);
-
- if (!address)
- last_error = symbol_error;
- return address;
-}
-
-static
-lt_dltype_t
-sys_dld = { LTDL_TYPE_TOP, 0, sys_dld_init, sys_dld_exit,
- sys_dld_open, sys_dld_close, sys_dld_sym };
-
-#undef LTDL_TYPE_TOP
-#define LTDL_TYPE_TOP &sys_dld
-
-#endif
-
#ifdef _WIN32
/* dynamic linking for Win32 */
#include <windows.h>
-static int
-sys_wll_init LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_wll_exit LTDL_PARAMS((void))
-{
- return 0;
-}
-
/* Forward declaration; required to implement handle search below. */
static lt_dlhandle handles;
-static int
-sys_wll_open (handle, filename)
- lt_dlhandle handle;
+static lt_module_t
+sys_wll_open (filename)
const char *filename;
{
lt_dlhandle cur;
- char *searchname = NULL;
+ lt_module_t module;
+ char *searchname = 0;
char *ext = strrchr(filename, '.');
if (ext) {
/* Append a `.' to stop Windows from adding an
implicit `.dll' extension. */
searchname = (char*)lt_dlmalloc(2+ strlen(filename));
+ if (!searchname) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return 0;
+ }
strcpy(searchname, filename);
strcat(searchname, ".");
}
-
- handle->handle = LoadLibrary(searchname);
+
+ module = LoadLibrary(searchname);
lt_dlfree(searchname);
/* libltdl expects this function to fail if it is unable
find one. */
cur = handles;
while (cur) {
- if (!cur->handle) {
+ if (!cur->module) {
cur = 0;
break;
}
- if (cur->handle == handle->handle)
+ if (cur->module == module)
break;
cur = cur->next;
}
- if (cur || !handle->handle) {
- last_error = cannot_open_error;
- return 1;
+ if (cur || !module) {
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
+ return 0;
}
- return 0;
+ return module;
}
static int
-sys_wll_close (handle)
- lt_dlhandle handle;
+sys_wll_close (module)
+ lt_module_t module;
{
- if (FreeLibrary(handle->handle) == 0) {
- last_error = cannot_close_error;
+ if (FreeLibrary(module) == 0) {
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
return 1;
}
return 0;
}
static lt_ptr_t
-sys_wll_sym (handle, symbol)
- lt_dlhandle handle;
+sys_wll_sym (module, symbol)
+ lt_module_t module;
const char *symbol;
{
- lt_ptr_t address = GetProcAddress(handle->handle, symbol);
+ lt_ptr_t address = GetProcAddress(module, symbol);
if (!address)
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return address;
}
-static
-lt_dltype_t
-sys_wll = { LTDL_TYPE_TOP, 0, sys_wll_init, sys_wll_exit,
- sys_wll_open, sys_wll_close, sys_wll_sym };
-
-#undef LTDL_TYPE_TOP
-#define LTDL_TYPE_TOP &sys_wll
+static struct lt_user_dlloader
+sys_wll = { 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0 };
#endif
#include <kernel/image.h>
-static int
-sys_bedl_init LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_bedl_exit LTDL_PARAMS((void))
-{
- return 0;
-}
-
-static int
-sys_bedl_open (handle, filename)
- lt_dlhandle handle;
+static lt_module_t
+sys_bedl_open (filename)
const char *filename;
{
image_id image = 0;
image = load_add_on(info.name);
}
if (image <= 0) {
- last_error = cannot_open_error;
- return 1;
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
+ return 0;
}
- handle->handle = (void*) image;
- return 0;
+
+ return (lt_module_t) image;
}
static int
-sys_bedl_close (handle)
- lt_dlhandle handle;
+sys_bedl_close (module)
+ lt_module_t module;
{
- if (unload_add_on((image_id)handle->handle) != B_OK) {
- last_error = cannot_close_error;
+ if (unload_add_on((image_id)module) != B_OK) {
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
return 1;
}
return 0;
}
static lt_ptr_t
-sys_bedl_sym (handle, symbol)
- lt_dlhandle handle;
+sys_bedl_sym (module, symbol)
+ lt_module_t module;
const char *symbol;
{
lt_ptr_t address = 0;
- image_id image = (image_id)handle->handle;
+ image_id image = (image_id)module;
if (get_image_symbol(image, symbol, B_SYMBOL_TYPE_ANY,
&address) != B_OK) {
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
return address;
}
-static
-lt_dltype_t
-sys_bedl = { LTDL_TYPE_TOP, 0, sys_bedl_init, sys_bedl_exit,
- sys_bedl_open, sys_bedl_close, sys_bedl_sym };
+static struct lt_user_dlloader
+sys_bedl = { 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0 };
-#undef LTDL_TYPE_TOP
-#define LTDL_TYPE_TOP &sys_bedl
+#endif
+
+#if HAVE_DLD
+
+/* dynamic linking with dld */
+
+#if HAVE_DLD_H
+#include <dld.h>
+#endif
+
+static lt_module_t
+sys_dld_open (filename)
+ const char *filename;
+{
+ lt_module_t module = strdup(filename);
+ if (!module) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return 0;
+ }
+ if (dld_link(filename) != 0) {
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
+ lt_dlfree(module);
+ return 0;
+ }
+ return module;
+}
+
+static int
+sys_dld_close (module)
+ lt_module_t module;
+{
+ if (dld_unlink_by_file((char*)(module), 1) != 0) {
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
+ return 1;
+ }
+ lt_dlfree(module);
+ return 0;
+}
+
+static lt_ptr_t
+sys_dld_sym (module, symbol)
+ lt_module_t module;
+ const char *symbol;
+{
+ lt_ptr_t address = dld_get_func(symbol);
+
+ if (!address)
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
+ return address;
+}
+
+static struct lt_user_dlloader
+sys_dld = { 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0 };
#endif
tmp = (lt_dlsymlists_t*) lt_dlmalloc(sizeof(lt_dlsymlists_t));
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
tmp->syms = preloaded;
- tmp->next = 0;
- if (!preloaded_symbols)
- preloaded_symbols = tmp;
- else {
- /* append to the end */
- lists = preloaded_symbols;
- while (lists->next)
- lists = lists->next;
- lists->next = tmp;
- }
+ tmp->next = preloaded_symbols;
+ preloaded_symbols = tmp;
return 0;
}
-static int
-presym_open (handle, filename)
- lt_dlhandle handle;
+static lt_module_t
+presym_open (filename)
const char *filename;
{
lt_dlsymlists_t *lists = preloaded_symbols;
if (!lists) {
- last_error = no_symbols_error;
- return 1;
+ last_error = LT_DLSTRERROR(NO_SYMBOLS);
+ return 0;
}
if (!filename)
filename = "@PROGRAM@";
while (syms->name) {
if (!syms->address &&
strcmp(syms->name, filename) == 0) {
- handle->handle = (lt_ptr_t) syms;
- return 0;
+ return (lt_module_t) syms;
}
syms++;
}
lists = lists->next;
}
- last_error = file_not_found_error;
- return 1;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
+ return 0;
}
static int
-presym_close (handle)
- lt_dlhandle handle;
+presym_close (module)
+ lt_module_t module;
{
/* Just to silence gcc -Wall */
- handle = 0;
+ module = 0;
return 0;
}
static lt_ptr_t
-presym_sym (handle, symbol)
- lt_dlhandle handle;
+presym_sym (module, symbol)
+ lt_module_t module;
const char *symbol;
{
- lt_dlsymlist *syms = (lt_dlsymlist*)(handle->handle);
+ lt_dlsymlist *syms = (lt_dlsymlist*)(module);
syms++;
while (syms->address) {
return syms->address;
syms++;
}
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
-static
-lt_dltype_t
-presym = { LTDL_TYPE_TOP, 0, presym_init, presym_exit,
- presym_open, presym_close, presym_sym };
+static struct lt_user_dlloader
+presym = { 0, presym_open, presym_close, presym_sym, presym_exit };
-#undef LTDL_TYPE_TOP
-#define LTDL_TYPE_TOP &presym
static char *user_search_path = 0;
+static lt_dlloader_t *loaders = 0;
static lt_dlhandle handles = 0;
static int initialized = 0;
-static lt_dltype_t *types = LTDL_TYPE_TOP;
-#undef LTDL_TYPE_TOP
-
int
lt_dlinit LTDL_PARAMS((void))
{
/* initialize libltdl */
- lt_dltype_t **type = &types;
- int typecount = 0;
+ lt_dlloader_t **loader = &loaders;
+ int errors = 0;
if (initialized) { /* Initialize only at first call. */
initialized++;
}
handles = 0;
user_search_path = 0; /* empty search path */
-
- while (*type) {
- if ((*type)->mod_init())
- *type = (*type)->next; /* Remove it from the list */
- else {
- type = &(*type)->next; /* Keep it */
- typecount++;
+
+#if HAVE_LIBDL && !defined(__CYGWIN__)
+ errors += lt_add_dlloader (lt_next_dlloader(0), &sys_dl, "dlopen");
+#endif
+#if HAVE_SHL_LOAD
+ errors += lt_add_dlloader (lt_next_dlloader(0), &sys_shl, "dlopen");
+#endif
+#ifdef _WIN32
+ errors += lt_add_dlloader (lt_next_dlloader(0), &sys_wll, "dlopen");
+#endif
+#ifdef __BEOS__
+ errors += lt_add_dlloader (lt_next_dlloader(0), &sys_bedl, "dlopen");
+#endif
+#if HAVE_DLD
+ errors += lt_add_dlloader (lt_next_dlloader(0), &sys_dld, "dld");
+#endif
+ errors += lt_add_dlloader (lt_next_dlloader(0), &presym, "dlpreload");
+ if (presym_init()) {
+ last_error = LT_DLSTRERROR(INIT_LOADER);
+ return 1;
}
- }
- if (typecount == 0) {
- last_error = dlopen_not_supported_error;
+
+ if (errors != 0) {
+ last_error = LT_DLSTRERROR(DLOPEN_NOT_SUPPORTED);
return 1;
}
last_error = 0;
lt_dlexit LTDL_PARAMS((void))
{
/* shut down libltdl */
- lt_dltype_t *type = types;
- int errors;
+ lt_dlloader_t *loader = loaders;
+ int errors, level;
if (!initialized) {
- last_error = shutdown_error;
+ last_error = LT_DLSTRERROR(SHUTDOWN);
return 1;
}
if (initialized != 1) { /* shut down only at last call. */
}
/* close all modules */
errors = 0;
- while (handles) {
- /* FIXME: what if a module depends on another one? */
- if (lt_dlclose(handles))
- errors++;
+ for (level = 1; handles; level++) {
+ lt_dlhandle cur = handles;
+ while (cur) {
+ lt_dlhandle tmp = cur;
+ cur = cur->next;
+ if (tmp->info.ref_count <= level)
+ if (lt_dlclose(tmp))
+ errors++;
+ }
}
- initialized = 0;
- while (type) {
- if (type->mod_exit())
+ /* close all loaders */
+ while (loader) {
+ lt_dlloader_t *next = loader->next;
+ if (loader->dlloader_exit && loader->dlloader_exit())
errors++;
- type = type->next;
+ lt_dlfree (loader);
+ loader = next;
}
+
+ initialized = 0;
return errors;
}
const char *filename;
{
lt_dlhandle cur;
- lt_dltype_t *type = types;
+ lt_dlloader_t *loader = loaders;
const char *saved_error = last_error;
/* check whether the module was already opened */
cur = handles;
while (cur) {
- if (!cur->filename && !filename)
+ /* try to dlopen the program itself? */
+ if (!cur->info.filename && !filename)
break;
- if (cur->filename && filename &&
- strcmp(cur->filename, filename) == 0)
+ if (cur->info.filename && filename &&
+ strcmp(cur->info.filename, filename) == 0)
break;
cur = cur->next;
}
if (cur) {
- cur->usage++;
+ cur->info.ref_count++;
*handle = cur;
return 0;
}
cur = *handle;
if (filename) {
- cur->filename = strdup(filename);
- if (!cur->filename) {
- last_error = memory_error;
+ cur->info.filename = strdup(filename);
+ if (!cur->info.filename) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
} else
- cur->filename = 0;
- while (type) {
- if (type->lib_open(cur, filename) == 0)
+ cur->info.filename = 0;
+ while (loader) {
+ cur->module = loader->module_open(filename);
+ if (cur->module != 0)
break;
- type = type->next;
+ loader = loader->next;
}
- if (!type) {
- if (cur->filename)
- lt_dlfree(cur->filename);
+ if (!loader) {
+ if (cur->info.filename)
+ lt_dlfree(cur->info.filename);
return 1;
}
- cur->type = type;
+ cur->loader = loader;
last_error = saved_error;
return 0;
}
filename = (char*)
lt_dlmalloc(strlen(libdir)+1+strlen(dlname)+1);
if (!filename) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
- strcpy(filename, libdir);
- strcat(filename, "/");
- strcat(filename, dlname);
- error = tryall_dlopen(handle, filename) == 0;
+ sprintf (filename, "%s/%s", libdir, dlname);
+ error = tryall_dlopen(handle, filename) != 0;
lt_dlfree(filename);
- if (error)
+ if (!error)
return 0;
}
/* try to open the not-installed module */
lt_dlmalloc((dir ? strlen(dir) : 0)
+ strlen(objdir) + strlen(dlname) + 1);
if (!filename) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
if (dir)
strcat(filename, objdir);
strcat(filename, dlname);
- error = tryall_dlopen(handle, filename) == 0;
+ error = tryall_dlopen(handle, filename) != 0;
lt_dlfree(filename);
- if (error)
+ if (!error)
return 0;
}
- /* hmm, maybe it was moved to another directory */
+ /* maybe it was moved to another directory */
{
filename = (char*)
lt_dlmalloc((dir ? strlen(dir) : 0)
else
*filename = 0;
strcat(filename, dlname);
- error = tryall_dlopen(handle, filename) == 0;
+ error = tryall_dlopen(handle, filename) != 0;
lt_dlfree(filename);
- if (error)
+ if (!error)
return 0;
}
}
- last_error = file_not_found_error;
return 1;
}
+static char*
+canonicalize_path (path)
+ const char *path;
+{
+ char *canonical = 0;
+
+ if (path && *path) {
+ char *ptr = strdup (path);
+ canonical = ptr;
+#ifdef LTDL_DIRSEP_CHAR
+ /* Avoid this overhead where '/' is the only separator. */
+ while (ptr = strchr (ptr, LTDL_DIRSEP_CHAR))
+ *ptr++ = '/';
+#endif
+ }
+
+ return canonical;
+}
+
static lt_ptr_t
find_file (basename, search_path, pdir, handle)
const char *basename;
/* when handle != NULL search a library, otherwise a file */
/* return NULL on failure, otherwise the file/handle */
+ lt_ptr_t result = 0;
char *filename = 0;
int filenamesize = 0;
- const char *next = search_path;
int lenbase = strlen(basename);
+ char *canonical = 0, *next = 0;
- if (!next || !*next) {
- last_error = file_not_found_error;
+ if (!search_path || !*search_path) {
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
return 0;
}
+ canonical = canonicalize_path (search_path);
+ if (!canonical) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ goto cleanup;
+ }
+ next = canonical;
while (next) {
int lendir;
- const char *cur = next;
+ char *cur = next;
- next = strchr(cur, ':');
+ next = strchr(cur, LTDL_PATHSEP_CHAR);
if (!next)
next = cur + strlen(cur);
lendir = next - cur;
- if (*next == ':')
+ if (*next == LTDL_PATHSEP_CHAR)
++next;
else
next = 0;
filenamesize = lendir + 1 + lenbase + 1;
filename = (char*) lt_dlmalloc(filenamesize);
if (!filename) {
- last_error = memory_error;
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ goto cleanup;
}
}
strncpy(filename, cur, lendir);
strcpy(filename+lendir, basename);
if (handle) {
if (tryall_dlopen(handle, filename) == 0) {
- lt_dlfree(filename);
- return (lt_ptr_t) handle;
+ result = (lt_ptr_t) handle;
+ goto cleanup;
}
} else {
FILE *file = fopen(filename, LTDL_READTEXT_MODE);
strdup, but there would be some
memory overhead. */
*pdir = filename;
- } else
- lt_dlfree(filename);
- return (lt_ptr_t) file;
+ filename = 0;
+ }
+ result = (lt_ptr_t) file;
+ goto cleanup;
}
}
}
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
+cleanup:
if (filename)
lt_dlfree(filename);
- last_error = file_not_found_error;
- return 0;
+ if (canonical)
+ lt_dlfree(canonical);
+ return result;
}
static int
load_deplibs(handle, deplibs)
lt_dlhandle handle;
- const char *deplibs;
+ char *deplibs;
{
- /* FIXME: load deplibs */
+ char *p, *save_search_path;
+ int i;
+ int ret = 1, depcount = 0;
+ char **names = 0;
+ lt_dlhandle *handles = 0;
+
handle->depcount = 0;
- handle->deplibs = 0;
- /* Just to silence gcc -Wall */
- deplibs = 0;
- return 0;
+ if (!deplibs)
+ return 0;
+ save_search_path = strdup(user_search_path);
+ if (user_search_path && !save_search_path) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return 1;
+ }
+ p = deplibs;
+ /* extract search paths and count deplibs */
+ while (*p) {
+ if (!isspace(*p)) {
+ char *end = p+1;
+ while (*end && !isspace(*end)) end++;
+ if (strncmp(p, "-L", 2) == 0 ||
+ strncmp(p, "-R", 2) == 0) {
+ char save = *end;
+ *end = 0; /* set a temporary string terminator */
+ if (lt_dladdsearchdir(p+2))
+ goto cleanup;
+ *end = save;
+ } else
+ depcount++;
+ p = end;
+ } else
+ p++;
+ }
+ if (!depcount) {
+ ret = 0;
+ goto cleanup;
+ }
+ names = lt_dlmalloc(depcount * sizeof(char*));
+ if (!names)
+ goto cleanup;
+ handles = lt_dlmalloc(depcount * sizeof(lt_dlhandle*));
+ if (!handles)
+ goto cleanup;
+ depcount = 0;
+ /* now only extract the actual deplibs */
+ p = deplibs;
+ while (*p) {
+ if (!isspace(*p)) {
+ char *end = p+1;
+ while (*end && !isspace(*end)) end++;
+ if (strncmp(p, "-L", 2) != 0 &&
+ strncmp(p, "-R", 2) != 0) {
+ char *name;
+ char save = *end;
+ *end = 0; /* set a temporary string terminator */
+ if (strncmp(p, "-l", 2) == 0) {
+ name = lt_dlmalloc(3+ /* "lib" */
+ strlen(p+2)+strlen(shlib_ext)+1);
+ if (name)
+ sprintf(name, "lib%s%s", p+2, shlib_ext);
+ } else
+ name = strdup(p);
+ if (name)
+ names[depcount++] = name;
+ else
+ goto cleanup_names;
+ *end = save;
+ }
+ p = end;
+ } else
+ p++;
+ }
+ /* load the deplibs (in reverse order) */
+ for (i = 0; i < depcount; i++) {
+ lt_dlhandle handle = lt_dlopen(names[depcount-1-i]);
+ if (!handle) {
+ int j;
+ for (j = 0; j < i; j++)
+ lt_dlclose(handles[j]);
+ last_error = LT_DLSTRERROR(DEPLIB_NOT_FOUND);
+ goto cleanup_names;
+ }
+ handles[i] = handle;
+ }
+ handle->depcount = depcount;
+ handle->deplibs = handles;
+ handles = 0;
+ ret = 0;
+cleanup_names:
+ for (i = 0; i < depcount; i++)
+ lt_dlfree(names[i]);
+cleanup:
+ if (names)
+ lt_dlfree(names);
+ if (handles)
+ lt_dlfree(handles);
+ /* restore the old search path */
+ if (user_search_path)
+ lt_dlfree(user_search_path);
+ user_search_path = save_search_path;
+ return ret;
}
static int
unload_deplibs(handle)
lt_dlhandle handle;
{
- /* FIXME: unload deplibs */
- /* Just to silence gcc -Wall */
- handle = 0;
- return 0;
+ int i;
+ int errors = 0;
+
+ if (!handle->depcount)
+ return 0;
+ for (i = 0; i < handle->depcount; i++)
+ errors += lt_dlclose(handle->deplibs[i]);
+ return errors;
}
static inline int
if (len > 3 && str[0] == '\'') {
tmp = (char*) lt_dlmalloc(end - str);
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
strncpy(tmp, &str[1], (end - str) - 1);
}
static inline int
-free_vars(dir, name, dlname, oldname, libdir, deplibs)
- char *dir;
- char *name;
+free_vars( dlname, oldname, libdir, deplibs)
char *dlname;
char *oldname;
char *libdir;
char *deplibs;
{
- if (dir)
- lt_dlfree(dir);
- if (name)
- lt_dlfree(name);
if (dlname)
lt_dlfree(dlname);
if (oldname)
lt_dlopen (filename)
const char *filename;
{
- lt_dlhandle handle, newhandle;
- const char *basename, *ext;
+ lt_dlhandle handle = 0, newhandle;
+ const char *ext;
const char *saved_error = last_error;
- char *dir = 0, *name = 0;
+ char *canonical = 0, *basename = 0, *dir = 0, *name = 0;
if (!filename) {
handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
if (!handle) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
- handle->usage = 0;
+ handle->info.ref_count = 0;
handle->depcount = 0;
handle->deplibs = 0;
newhandle = handle;
}
goto register_handle;
}
- basename = strrchr(filename, '/');
+ canonical = canonicalize_path (filename);
+ if (!canonical) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ if (handle)
+ lt_dlfree(handle);
+ return 0;
+ }
+ basename = strrchr(canonical, '/');
if (basename) {
basename++;
- dir = (char*) lt_dlmalloc(basename - filename + 1);
+ dir = (char*) lt_dlmalloc(basename - canonical + 1);
if (!dir) {
- last_error = memory_error;
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ handle = 0;
+ goto cleanup;
}
- strncpy(dir, filename, basename - filename);
- dir[basename - filename] = '\0';
+ strncpy(dir, canonical, basename - canonical);
+ dir[basename - canonical] = '\0';
} else
- basename = filename;
+ basename = canonical;
/* check whether we open a libtool module (.la extension) */
ext = strrchr(basename, '.');
if (ext && strcmp(ext, ".la") == 0) {
/* extract the module name from the file name */
name = (char*) lt_dlmalloc(ext - basename + 1);
if (!name) {
- last_error = memory_error;
- if (dir)
- lt_dlfree(dir);
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ handle = 0;
+ goto cleanup;
}
/* canonicalize the module name */
for (i = 0; i < ext - basename; i++)
/* now try to open the .la file */
file = fopen(filename, LTDL_READTEXT_MODE);
if (!file)
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
if (!file && !dir) {
/* try other directories */
file = (FILE*) find_file(basename,
file = (FILE*) find_file(basename,
getenv(LTDL_SHLIBPATH_VAR),
&dir, 0);
+#endif
+#ifdef LTDL_SYSSEARCHPATH
+ if (!file)
+ file = (FILE*) find_file(basename,
+ sys_search_path,
+ &dir, 0);
#endif
}
if (!file) {
- if (name)
- lt_dlfree(name);
- if (dir)
- lt_dlfree(dir);
- return 0;
+ handle = 0;
+ goto cleanup;
}
line = (char*) lt_dlmalloc(LTDL_FILENAME_MAX);
if (!line) {
fclose(file);
- last_error = memory_error;
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ handle = 0;
+ goto cleanup;
}
/* read the .la file */
while (!feof(file)) {
if (handle)
lt_dlfree(handle);
if (!error)
- last_error = memory_error;
- free_vars(name, dir, dlname, old_name, libdir, deplibs);
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ free_vars(dlname, old_name, libdir, deplibs);
+ /* handle is already set to 0 */
+ goto cleanup;
}
- handle->usage = 0;
+ handle->info.ref_count = 0;
if (load_deplibs(handle, deplibs) == 0) {
newhandle = handle;
/* find_module may replace newhandle */
}
} else
error = 1;
+ free_vars(dlname, old_name, libdir, deplibs);
if (error) {
lt_dlfree(handle);
- free_vars(name, dir, dlname, old_name, libdir, deplibs);
- return 0;
+ handle = 0;
+ goto cleanup;
}
- if (handle != newhandle) {
+ if (handle != newhandle)
unload_deplibs(handle);
- }
} else {
/* not a libtool module */
handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
if (!handle) {
- last_error = memory_error;
- if (dir)
- lt_dlfree(dir);
- return 0;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ /* handle is already set to 0 */
+ goto cleanup;
}
- handle->usage = 0;
+ handle->info.ref_count = 0;
/* non-libtool modules don't have dependencies */
handle->depcount = 0;
handle->deplibs = 0;
&& !find_file(basename,
getenv(LTDL_SHLIBPATH_VAR),
0, &newhandle)
+#endif
+#ifdef LTDL_SYSSEARCHPATH
+ && !find_file(basename, sys_search_path,
+ 0, &newhandle)
#endif
))) {
lt_dlfree(handle);
- if (dir)
- lt_dlfree(dir);
- return 0;
+ handle = 0;
+ goto cleanup;
}
}
register_handle:
lt_dlfree(handle);
handle = newhandle;
}
- if (!handle->usage) {
- handle->usage = 1;
- handle->name = name;
+ if (!handle->info.ref_count) {
+ handle->info.ref_count = 1;
+ handle->info.name = name;
handle->next = handles;
handles = handle;
- } else if (name)
- lt_dlfree(name);
+ name = 0; /* don't free this during `cleanup' */
+ }
+ last_error = saved_error;
+cleanup:
if (dir)
lt_dlfree(dir);
- last_error = saved_error;
+ if (name)
+ lt_dlfree(name);
+ if (canonical)
+ lt_dlfree(canonical);
return handle;
}
return lt_dlopen(filename);
len = strlen(filename);
if (!len) {
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
return 0;
}
/* try the normal file name */
/* try "filename.la" */
tmp = (char*) lt_dlmalloc(len+4);
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
strcpy(tmp, filename);
lt_dlfree(tmp);
tmp = (char*) lt_dlmalloc(len + strlen(shlib_ext) + 1);
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
strcpy(tmp, filename);
return handle;
}
#endif
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
lt_dlfree(tmp);
return 0;
}
cur = cur->next;
}
if (!cur) {
- last_error = invalid_handle_error;
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
return 1;
}
- handle->usage--;
- if (!handle->usage) {
+ handle->info.ref_count--;
+ if (!handle->info.ref_count) {
int error;
if (handle != handles)
last->next = handle->next;
else
handles = handle->next;
- error = handle->type->lib_close(handle);
+ error = handle->loader->module_close(handle->module);
error += unload_deplibs(handle);
- if (handle->filename)
- lt_dlfree(handle->filename);
- if (handle->name)
- lt_dlfree(handle->name);
+ if (handle->info.filename)
+ lt_dlfree(handle->info.filename);
+ if (handle->info.name)
+ lt_dlfree(handle->info.name);
lt_dlfree(handle);
return error;
}
lt_ptr_t address;
if (!handle) {
- last_error = invalid_handle_error;
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
return 0;
}
if (!symbol) {
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
lensym = strlen(symbol);
- if (handle->type->sym_prefix)
- lensym += strlen(handle->type->sym_prefix);
- if (handle->name)
- lensym += strlen(handle->name);
+ if (handle->loader->sym_prefix)
+ lensym += strlen(handle->loader->sym_prefix);
+ if (handle->info.name)
+ lensym += strlen(handle->info.name);
if (lensym + LTDL_SYMBOL_OVERHEAD < LTDL_SYMBOL_LENGTH)
sym = lsym;
else
sym = (char*) lt_dlmalloc(lensym + LTDL_SYMBOL_OVERHEAD + 1);
if (!sym) {
- last_error = buffer_overflow_error;
+ last_error = LT_DLSTRERROR(BUFFER_OVERFLOW);
return 0;
}
- if (handle->name) {
+ if (handle->info.name) {
const char *saved_error = last_error;
/* this is a libtool module */
- if (handle->type->sym_prefix) {
- strcpy(sym, handle->type->sym_prefix);
- strcat(sym, handle->name);
+ if (handle->loader->sym_prefix) {
+ strcpy(sym, handle->loader->sym_prefix);
+ strcat(sym, handle->info.name);
} else
- strcpy(sym, handle->name);
+ strcpy(sym, handle->info.name);
strcat(sym, "_LTX_");
strcat(sym, symbol);
/* try "modulename_LTX_symbol" */
- address = handle->type->find_sym(handle, sym);
+ address = handle->loader->find_sym(handle->module, sym);
if (address) {
if (sym != lsym)
lt_dlfree(sym);
last_error = saved_error;
}
/* otherwise try "symbol" */
- if (handle->type->sym_prefix) {
- strcpy(sym, handle->type->sym_prefix);
+ if (handle->loader->sym_prefix) {
+ strcpy(sym, handle->loader->sym_prefix);
strcat(sym, symbol);
} else
strcpy(sym, symbol);
- address = handle->type->find_sym(handle, sym);
+ address = handle->loader->find_sym(handle->module, sym);
if (sym != lsym)
lt_dlfree(sym);
return address;
if (!user_search_path) {
user_search_path = strdup(search_dir);
if (!user_search_path) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
} else {
lt_dlmalloc(strlen(user_search_path) +
strlen(search_dir) + 2); /* ':' + '\0' == 2 */
if (!new_search_path) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
- strcpy(new_search_path, user_search_path);
- strcat(new_search_path, ":");
- strcat(new_search_path, search_dir);
+ sprintf (new_search_path, "%s%c%s", user_search_path,
+ LTDL_PATHSEP_CHAR, search_dir);
lt_dlfree(user_search_path);
user_search_path = new_search_path;
}
{
return user_search_path;
}
+
+const lt_dlinfo *
+lt_dlgetinfo (handle)
+ lt_dlhandle handle;
+{
+ if (!handle) {
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
+ return 0;
+ }
+ return &(handle->info);
+}
+
+int
+lt_dlforeach (func, data)
+ int (*func) LTDL_PARAMS((lt_dlhandle handle, lt_ptr_t data));
+ lt_ptr_t data;
+{
+ lt_dlhandle cur = handles;
+ while (cur) {
+ lt_dlhandle tmp = cur;
+ cur = cur->next;
+ if (func(tmp, data))
+ return 1;
+ }
+ return 0;
+}
+
+\f
+int
+lt_add_dlloader (place, dlloader, loader_name)
+ lt_dlloader_t *place;
+ const struct lt_user_dlloader *dlloader;
+ const char *loader_name;
+{
+ lt_dlloader_t *node = 0, *ptr = 0;
+
+ if ((dlloader == 0) /* diagnose null parameters */
+ || (dlloader->module_open == 0)
+ || (dlloader->module_close == 0)
+ || (dlloader->find_sym == 0)) {
+ last_error = LT_DLSTRERROR(INVALID_LOADER);
+ return 1;
+ }
+
+ /* Create a new dlloader node with copies of the user callbacks. */
+ node = (lt_dlloader_t *) lt_dlmalloc (sizeof (lt_dlloader_t));
+ if (node == 0) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return 1;
+ }
+ node->next = 0;
+ node->loader_name = loader_name;
+ node->sym_prefix = dlloader->sym_prefix;
+ node->dlloader_exit = dlloader->dlloader_exit;
+ node->module_open = dlloader->module_open;
+ node->module_close = dlloader->module_close;
+ node->find_sym = dlloader->find_sym;
+
+ if (!loaders)
+ /* If there are no loaders, NODE becomes the list! */
+ loaders = node;
+ else if (!place) {
+ /* If PLACE is not set, add NODE to the end of the
+ LOADERS list. */
+ for (ptr = loaders; ptr->next; ptr = ptr->next)
+ /*NOWORK*/;
+ ptr->next = node;
+ } else if (loaders == place) {
+ /* If PLACE is the first loader, NODE goes first. */
+ node->next = place;
+ loaders = node;
+ } else {
+ /* Find the node immediately preceding PLACE. */
+ for (ptr = loaders; ptr->next != place; ptr = ptr->next)
+ /*NOWORK*/;
+
+ if (ptr->next != place) {
+ last_error = LT_DLSTRERROR(INVALID_LOADER);
+ return 1;
+ }
+
+ /* Insert NODE between PTR and PLACE. */
+ node->next = place;
+ ptr->next = node;
+ }
+
+ return 0;
+}
+
+int
+lt_remove_dlloader (loader_name)
+ const char *loader_name;
+{
+ lt_dlloader_t *place = lt_find_dlloader (loader_name);
+ lt_dlhandle handle;
+ int result = 0;
+
+ if (!place) {
+ last_error = LT_DLSTRERROR(INVALID_LOADER);
+ return 1;
+ }
+
+ /* Fail if there are any open modules which use this loader. */
+ for (handle = handles; handle; handle = handle->next)
+ if (handle->loader = place) {
+ last_error = LT_DLSTRERROR(REMOVE_LOADER);
+ return 1;
+ }
+
+ if (place == loaders)
+ /* PLACE is the first loader in the list. */
+ loaders = loaders->next;
+ else {
+ /* Find the loader before the one being removed. */
+ lt_dlloader_t *prev;
+ for (prev = loaders; prev->next; prev = prev->next)
+ if (!strcmp (prev->next->loader_name, loader_name))
+ break;
+
+ place = prev->next;
+ prev->next = prev->next->next;
+ }
+ if (place->dlloader_exit)
+ result = place->dlloader_exit ();
+ lt_dlfree (place);
+
+ return result;
+}
+
+lt_dlloader_t *
+lt_next_dlloader (place)
+ lt_dlloader_t *place;
+{
+ return place ? place->next : loaders;
+}
+
+const char *
+lt_dlloader_name (place)
+ lt_dlloader_t *place;
+{
+ if (!place)
+ last_error = LT_DLSTRERROR(INVALID_LOADER);
+ return place ? place->loader_name : 0;
+}
+
+lt_dlloader_t *
+lt_find_dlloader (loader_name)
+ const char *loader_name;
+{
+ lt_dlloader_t *place = 0;
+
+ for (place = loaders; place; place = place->next)
+ if (strcmp (place->loader_name, loader_name) == 0)
+ break;
+
+ return place;
+}
+
+\f
+static const char **user_error_strings = 0;
+static int errorcode = LTDL_ERROR_MAX;
+
+int
+lt_dladderror (diagnostic)
+ const char *diagnostic;
+{
+ int index = errorcode - LTDL_ERROR_MAX;
+ const char **temp = 0;
+
+ /* realloc is not entirely portable, so simulate it using
+ lt_dlmalloc and lt_dlfree. */
+ temp = (const char **) lt_dlmalloc ((1+index) * sizeof(const char*));
+ if (temp == 0) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return -1;
+ }
+
+ /* Build the new vector in the memory addressed by temp. */
+ temp[index] = diagnostic;
+ while (--index >= 0)
+ temp[index] = user_error_strings[index];
+
+ lt_dlfree (user_error_strings);
+ user_error_strings = temp;
+ return errorcode++;
+}
+
+int
+lt_dlseterror (index)
+ int index;
+{
+ if (index >= errorcode || index < 0) {
+ last_error = LT_DLSTRERROR(INVALID_ERRORCODE);
+ return 1;
+ }
+
+ if (index < LTDL_ERROR_MAX)
+ last_error = ltdl_error_strings[errorcode];
+ else
+ last_error = user_error_strings[errorcode - LTDL_ERROR_MAX];
+
+ return 0;
+}
/* ltdl.h -- generic dlopen functions
- Copyright (C) 1998-1999 Free Software Foundation, Inc.
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
Originally by Thomas Tanner <tanner@ffii.org>
This file is part of GNU Libtool.
#ifndef _LTDL_H_
#define _LTDL_H_ 1
+/* Canonicalise Windows and Cygwin recognition macros. */
+#ifdef __CYGWIN32__
+# ifndef __CYGWIN__
+# define __CYGWIN__ __CYGWIN32__
+# endif
+#endif
+#ifdef _WIN32
+# ifndef WIN32
+# define WIN32 _WIN32
+# endif
+#endif
+
/* __BEGIN_DECLS should be used at the beginning of your declarations,
so that C++ compilers don't mangle their names. Use __END_DECLS at
the end of C declarations. */
# define lt_ptr_t char*
#endif
+/* LTDL_STMT_START/END are used to create macros which expand to a
+ a single compound statement in a portable way. */
+#undef LTDL_STMT_START
+#undef LTDL_STMT_END
+#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
+# define LTDL_STMT_START (void)(
+# define LTDL_STMT_END )
+#else
+# if (defined (sun) || defined (__sun__))
+# define LTDL_STMT_START if (1)
+# define LTDL_STMT_END else (void)0
+# else
+# define LTDL_STMT_START do
+# define LTDL_STMT_END while (0)
+# endif
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__
+/* LTDL_DIRSEP_CHAR is accepted *in addition* to '/' as a directory
+ separator when it is set. */
+# define LTDL_DIRSEP_CHAR '\\'
+# define LTDL_PATHSEP_CHAR ';'
+# endif
+#endif
+#ifndef LTDL_PATHSEP_CHAR
+# define LTDL_PATHSEP_CHAR ':'
+#endif
+
+/* DLL building support on win32 hosts; mostly to workaround their
+ ridiculous implementation of data symbol exporting. */
+#ifndef LTDL_SCOPE
+# ifdef _WIN32
+# ifdef DLL_EXPORT /* defined by libtool (if required) */
+# define LTDL_SCOPE __declspec(dllexport)
+# endif
+# ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */
+# define LTDL_SCOPE extern __declspec(dllimport)
+# endif
+# endif
+# ifndef LTDL_SCOPE /* static linking or !_WIN32 */
+# define LTDL_SCOPE extern
+# endif
+#endif
+
#include <stdlib.h>
+\f
+/* Defining error strings alongside their symbolic names in a macro in
+ this way allows us to expand the macro in different contexts with
+ confidence that the enumeration of symbolic names will map correctly
+ onto the table of error strings. */
+#define ltdl_error_table \
+ LTDL_ERROR(UNKNOWN, "unknown error") \
+ LTDL_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available")\
+ LTDL_ERROR(INVALID_LOADER, "invalid loader") \
+ LTDL_ERROR(INIT_LOADER, "loader initialization failed") \
+ LTDL_ERROR(REMOVE_LOADER, "loader removal failed") \
+ LTDL_ERROR(FILE_NOT_FOUND, "file not found") \
+ LTDL_ERROR(DEPLIB_NOT_FOUND, "dependency library not found") \
+ LTDL_ERROR(NO_SYMBOLS, "no symbols defined") \
+ LTDL_ERROR(CANNOT_OPEN, "can't open the module") \
+ LTDL_ERROR(CANNOT_CLOSE, "can't close the module") \
+ LTDL_ERROR(SYMBOL_NOT_FOUND, "symbol not found") \
+ LTDL_ERROR(NO_MEMORY, "not enough memory") \
+ LTDL_ERROR(INVALID_HANDLE, "invalid module handle") \
+ LTDL_ERROR(BUFFER_OVERFLOW, "internal buffer overflow") \
+ LTDL_ERROR(INVALID_ERRORCODE, "invalid errorcode") \
+ LTDL_ERROR(SHUTDOWN, "library already shutdown")
+
+/* Enumerate the symbolic error names. */
+#ifdef __STDC__
+# define LTDL_ERROR(name, diagnostic) LTDL_ERROR_##name,
+#else
+# define LTDL_ERROR(name, diagnostic) LTDL_ERROR_/**/name,
+#endif
+enum {
+ ltdl_error_table
+ LTDL_ERROR_MAX
+};
+#undef LTDL_ERROR
+
+\f
+/* An opaque handle for a successfully lt_dlopened module instance. */
#ifdef _LTDL_COMPILE_
typedef struct lt_dlhandle_t *lt_dlhandle;
#else
typedef lt_ptr_t lt_dlhandle;
#endif
+/* A preopened symbol. Arrays of this type comprise the exported
+ symbols for a dlpreopened module. */
typedef struct {
const char *name;
lt_ptr_t address;
} lt_dlsymlist;
+/* Read only information pertaining to a loaded module. */
+typedef struct {
+ char *filename; /* file name */
+ char *name; /* module name */
+ int ref_count; /* number of times lt_dlopened minus
+ number of times lt_dlclosed. */
+} lt_dlinfo;
+
+/* An opaque handle for a module loaded by a system call. This is only
+ used internally by ltdl loaders, and by user module loaders. */
+typedef lt_ptr_t lt_module_t;
+
+/* An opaque handle for a module loader. */
+#ifdef _LTDL_COMPILE_
+typedef struct lt_dlloader_t lt_dlloader_t;
+#else
+typedef lt_ptr_t lt_dlloader_t;
+#endif
+
+/* Function pointer types for creating user defined module loaders. */
+typedef lt_module_t lt_module_open_t LTDL_PARAMS((const char *filename));
+typedef int lt_module_close_t LTDL_PARAMS((lt_module_t handle));
+typedef lt_ptr_t lt_find_sym_t LTDL_PARAMS((lt_module_t handle, const char *symbol));
+typedef int lt_dlloader_exit_t LTDL_PARAMS((void));
+
__BEGIN_DECLS
+/* Initialisation and finalisation functions for libltdl. */
extern int lt_dlinit LTDL_PARAMS((void));
-extern int lt_dlpreload LTDL_PARAMS((const lt_dlsymlist *preloaded));
-extern int lt_dlpreload_default LTDL_PARAMS((const lt_dlsymlist *preloaded));
extern int lt_dlexit LTDL_PARAMS((void));
+
+/* Module search path manipultation. */
+extern int lt_dladdsearchdir LTDL_PARAMS((const char *search_dir));
+extern int lt_dlsetsearchpath LTDL_PARAMS((const char *search_path));
+extern const char *lt_dlgetsearchpath LTDL_PARAMS((void));
+
+/* Portable libltdl versions of the system dlopen() API. */
extern lt_dlhandle lt_dlopen LTDL_PARAMS((const char *filename));
extern lt_dlhandle lt_dlopenext LTDL_PARAMS((const char *filename));
-extern int lt_dlclose LTDL_PARAMS((lt_dlhandle handle));
extern lt_ptr_t lt_dlsym LTDL_PARAMS((lt_dlhandle handle, const char *name));
extern const char *lt_dlerror LTDL_PARAMS((void));
-extern int lt_dladdsearchdir LTDL_PARAMS((const char *search_dir));
-extern int lt_dlsetsearchpath LTDL_PARAMS((const char *search_path));
-extern const char *lt_dlgetsearchpath LTDL_PARAMS((void));
+extern int lt_dlclose LTDL_PARAMS((lt_dlhandle handle));
+
+/* Support for preloaded modules through lt_dlopen() API. */
+extern int lt_dlpreload LTDL_PARAMS((const lt_dlsymlist *preloaded));
+extern int lt_dlpreload_default LTDL_PARAMS((const lt_dlsymlist *preloaded));
+
+#define LTDL_SET_PRELOADED_SYMBOLS() LTDL_STMT_START{ \
+ extern const lt_dlsymlist lt_preloaded_symbols[]; \
+ lt_dlpreload_default(lt_preloaded_symbols); \
+ }LTDL_STMT_END
+
+/* Managing user data associated with a loaded modules. */
+extern const lt_dlinfo *lt_dlgetinfo LTDL_PARAMS((lt_dlhandle handle));
+extern int lt_dlforeach LTDL_PARAMS((
+ int (*func)(lt_dlhandle handle, lt_ptr_t data), lt_ptr_t data));
+
+\f
+/* User module loader API. */
+struct lt_user_dlloader {
+ const char *sym_prefix;
+ lt_module_open_t *module_open;
+ lt_module_close_t *module_close;
+ lt_find_sym_t *find_sym;
+ lt_dlloader_exit_t *dlloader_exit;
+};
+
+extern lt_dlloader_t *lt_next_dlloader LTDL_PARAMS((lt_dlloader_t *place));
+extern const char *lt_dlloader_name LTDL_PARAMS((lt_dlloader_t *place));
+extern lt_dlloader_t *lt_find_dlloader LTDL_PARAMS((const char *loader_name));
+extern int lt_add_dlloader LTDL_PARAMS((lt_dlloader_t *place, const struct lt_user_dlloader *dlloader, const char *loader_name));
-extern const lt_dlsymlist lt_preloaded_symbols[];
-#define LTDL_SET_PRELOADED_SYMBOLS() lt_dlpreload_default(lt_preloaded_symbols)
+/* Integrated lt_dlerror() messages for user loaders. */
+extern int lt_dladderror LTDL_PARAMS((const char *diagnostic));
+extern int lt_dlseterror LTDL_PARAMS((int errorcode));
-extern lt_ptr_t (*lt_dlmalloc)LTDL_PARAMS((size_t size));
-extern void (*lt_dlfree)LTDL_PARAMS((lt_ptr_t ptr));
+/* Pointers to memory management functions to be used by libltdl. */
+LTDL_SCOPE lt_ptr_t (*lt_dlmalloc)LTDL_PARAMS((size_t size));
+LTDL_SCOPE void (*lt_dlfree)LTDL_PARAMS((lt_ptr_t ptr));
__END_DECLS
# dependencies.
output_verbose_link_cmds='templist=`$CC $CFLAGS -v conftest.$objext 2>&1 | egrep "\-R|\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
- AR="$CXX"
- old_archive_cmds='$AR -xar -o $oldlib $oldobjs'
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds='$CC -xar -o $oldlib $oldobjs'
;;
gcx)
# Green Hills C++ Compiler
archive_cmds='$CC -shared $libobjs $deplibs $linker_flags ${wl}-h $wl$soname -o $lib'
- AR="$CXX $LDFLAGS"
- old_archive_cmds='$AR -archive -o $oldlib $oldobjs'
+ # The C++ compiler must be used to create the archive.
+ old_archive_cmds='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
;;
*)
# GNU C++ compiler
for p in `eval $output_verbose_link_cmds`; do
case $p in
*.$objext | -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" \
+ || test $p = "-R"; then
+ prev=$p
+ continue
+ else
+ prev=
+ fi
+
# This assumes that the test object file only shows up
# once in the compiler output.
if test "$p" != "conftest.$objext"; then
if test "$pre_object_deps_done" = no; then
- predeps="$predeps $p"
+ predeps="${predeps} ${prev}${p}"
else
- postdeps="$postdeps $p"
+ postdeps="${postdeps} ${prev}${p}"
fi
else
pre_object_deps_done=yes
need_version=$need_version
# Whether dlopen is supported.
-dlopen=$enable_dlopen
+dlopen_support=$enable_dlopen
# Whether dlopen of programs is supported.
dlopen_self=$enable_dlopen_self
*.la)
# A libtool-controlled library.
- dlname=
- libdir=
- library_names=
- old_library=
-
- # Check to see that this really is a libtool archive.
- if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
- else
- $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
- exit 1
- fi
-
- # If the library was installed with an old release of libtool,
- # it will not redefine variable installed.
- installed=yes
-
- # Read the .la file
- # If there is no directory component, then add one.
- case "$arg" in
- */* | *\\*) . $arg ;;
- *) . ./$arg ;;
- esac
-
- # Get the name of the library we link against.
- linklib=
- for l in $old_library $library_names; do
- linklib="$l"
- done
-
- if test -z "$linklib"; then
- $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
- exit 1
- fi
-
- if test "X$installed" = Xyes; then
- dir="$libdir"
- else
- dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
- if test "X$dir" = "X$arg"; then
- dir="$objdir"
- else
- dir="$dir/$objdir"
- fi
- fi
-
- # This library was specified with -dlopen.
if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
dlfiles="$dlfiles $arg"
- if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
- # If there is no dlname, no dlopen support or we're linking statically,
- # we need to preload.
- prev=dlprefiles
- else
- # We should not create a dependency on this library
- prev=
- continue
- fi
- fi
-
- # The library was specified with -dlpreopen.
- if test "$prev" = dlprefiles; then
- # Prefer using a static library (so that no silly _DYNAMIC symbols
- # are required to link).
- if test -n "$old_library"; then
- dlprefiles="$dlprefiles $dir/$old_library"
- else
- dlprefiles="$dlprefiles $dir/$linklib"
- fi
prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ dlprefiles="$dlprefiles $arg"
+ prev=
+ else
+ deplibs="$deplibs $arg"
fi
-
- deplibs="$deplibs $arg"
continue
;;
linkmode=prog ;;
esac
- save_deplibs="$deplibs"
+ libs="$deplibs"
deplibs=
newdependency_libs=
uninst_path= # paths that contain uninstalled libtool libraries
case $linkmode in
lib)
passes="link"
+ for file in $dlfiles $dlprefiles; do
+ case "$file" in
+ *.la) ;;
+ *)
+ $echo "$modename: libraries can \`-dlopen' only libtool libraries" 1>&2
+ exit 1
+ ;;
+ esac
+ done
;;
prog)
alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
link_against_libtool_libs=
- passes="scan link"
+ passes="scan dlopen dlpreopen link"
;;
*) passes="link"
;;
esac
for pass in $passes; do
- if test "$linkmode,$pass" = "prog,link"; then
- save_deplibs="$deplibs %DEPLIBS% $dependency_libs"
+ if test $linkmode = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
fi
- for deplib in $predeps $postdeps $save_deplibs; do
+ for deplib in $predeps $postdeps $libs; do
lib=
found=no
case "$deplib" in
continue
fi
;;
+ *.la) lib="$deplib" ;;
*.$libext)
- if test $linkmode = prog; then
- if test $pass = scan; then
- deplibs="$deplibs $deplib"
- else
- compile_command="$compile_command $deplib"
- finalize_command="$finalize_command $deplib"
- fi
- continue
- elif test $linkmode = lib; then
+ case $linkmode in
+ lib)
if test "$deplibs_check_method" != pass_all; then
echo
echo "*** Warning: This library needs some functionality provided by $deplib."
deplibs="$deplibs $deplib"
fi
continue
- fi
+ ;;
+ prog)
+ if test $pass = scan; then
+ deplibs="$deplibs $deplib"
+ else
+ compile_command="$compile_command $deplib"
+ finalize_command="$finalize_command $deplib"
+ fi
+ continue
+ ;;
+ esac
;;
+ *.lo | *.$objext) continue ;;
%DEPLIBS%)
alldeplibs=yes
continue
;;
- *.$objext)
- # Ignore object files found by ltconfig
- continue
- ;;
- *)
- lib="$deplib"
- ;;
esac
if test $found = yes || test -f "$lib"; then :
else
ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
test "X$ladir" = "X$lib" && ladir="."
+ dlname=
+ dlopen=
+ dlpreopen=
libdir=
library_names=
old_library=
*) . ./$lib ;;
esac
+ if test $linkmode = lib || test "$linkmode,$pass" = "prog,scan"; then
+ test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+ test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+ fi
+
if test $linkmode != lib && test $linkmode != prog; then
# only check for convenience libraries
if test -z "$old_library"; then
exit 1
fi
- if test "$linkmode,$pass" = "prog,scan"; then
- new_lib_search_path="$new_lib_search_path $ladir"
- deplibs="$deplibs $lib"
-
- for deplib in $dependency_libs; do
- case "$deplib" in
- -L*) new_lib_search_path="$new_lib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
- esac
-
- if test "$link_all_deplibs" != no || \
- test "$fast_install" != no || \
- test "$build_libtool_libs" = no || \
- test -z "$library_names"; then
- # Need to link against all dependency_libs
- deplibs="$deplibs $deplib"
- else
- # Need to hardcode shared library paths
- # or/and link against static libraries
- newdependency_libs="$newdependency_libs $deplib"
- fi
- done
+ # This library was specified with -dlopen.
+ if test $pass = dlopen; then
+ if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking statically,
+ # we need to preload.
+ dlprefiles="$dlprefiles $lib"
+ else
+ newdlfiles="$newdlfiles $lib"
+ fi
continue
fi
fi
name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ # This library was specified with -dlpreopen.
+ if test $pass = dlpreopen; then
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ newdlprefiles="$newdlprefiles $dir/$old_library"
+ else
+ newdlprefiles="$newdlprefiles $dir/$linklib"
+ fi
+ fi
+
+ if test $linkmode = prog && test $pass != link; then
+ new_lib_search_path="$new_lib_search_path $ladir"
+ deplibs="$deplibs $lib"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test "$fast_install" != no || \
+ test "$build_libtool_libs" = no || test -z "$library_names"; then
+ linkalldeplibs=yes
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$newdependency_libs $dependeny_libs"
+ fi
+
+ for deplib in $dependency_libs; do
+ case "$deplib" in
+ -L*) new_lib_search_path="$new_lib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+ esac
+ # Need to link against all dependency_libs?
+ test $linkalldeplibs = yes && deplibs="$deplibs $deplib"
+ done
+ continue
+ fi
+
if test -z "$libdir"; then
# It is a libtool convenience library, so add in its objects.
- convenience="$convenience $ladir/$objdir/$old_library"
- old_convenience="$old_convenience $ladir/$objdir/$old_library"
+ convenience="$convenience $dir/$old_library"
+ old_convenience="$old_convenience $dir/$old_library"
if test $linkmode = lib; then
- deplibs="$deplibs $ladir/$objdir/$old_library"
+ deplibs="$deplibs $dir/$old_library"
newdependency_libs="$newdependency_libs $dependency_libs"
elif test "$linkmode,$pass" = "prog,link"; then
compile_command="$compile_command $dir/$old_library"
fi
if test "$linkmode,$pass" = "prog,link"; then
- hardcode=yes
- test "$hardcode_into_libs" = all && test "$alldeplibs" = yes && hardcode=no
- if test "$hardcode" = yes && test -n "$library_names" &&
+ if test -n "$library_names" &&
+ { test "$hardcode_into_libs" != all || test "$alldeplibs" != yes; } &&
{ test "$prefer_static_libs" = no || test -z "$old_library"; }; then
# We need to hardcode the library path
if test -n "$shlibpath_var"; then
linklib=$newlib
fi
- if test $linkmode = lib; then
-
- add_dir=
- add_shlibpath=
- add_name=no
- if test "$mode" != relink; then
+ if test $linkmode = prog || test "$mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
lib_linked=yes
case "$hardcode_action" in
immediate | unsupported)
if test "$hardcode_direct" = no; then
- deplibs="$deplibs $dir/$linklib"
+ add="$dir/$linklib"
elif test "$hardcode_minus_L" = no; then
case "$host" in
*-*-sunos*) add_shlibpath="$dir" ;;
esac
add_dir="-L$dir"
- add_name=yes
+ add="-l$name"
elif test "$hardcode_shlibpath_var" = no; then
add_shlibpath="$dir"
- add_name=yes
+ add="-l$name"
else
lib_linked=no
fi
;;
relink)
if test "$hardcode_direct" = yes; then
- deplibs="$deplibs $dir/$linklib"
+ add="$dir/$linklib"
elif test "$hardcode_minus_L" = yes; then
add_dir="-L$dir"
- add_name=yes
+ add="-l$name"
elif test "$hardcode_shlibpath_var" = yes; then
add_shlibpath="$dir"
- add_name=yes
+ add="-l$name"
else
lib_linked=no
fi
*) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
esac
fi
- else
- # Install command for both is simple: just hardcode it.
+ if test $linkmode = prog; then
+ if test -n "$add_dir"; then
+ case "$compile_command " in
+ *" $add_dir "*) ;;
+ *) compile_command="$compile_command $add_dir" ;;
+ esac
+ fi
+ test -n "$add" && compile_command="$compile_command $add"
+ else
+ if test -n "$add_dir"; then
+ case "$deplibs " in
+ *" $add_dir "*) ;;
+ *) deplibs="$deplibs $add_dir" ;;
+ esac
+ fi
+ test -n "$add" && deplibs="$deplibs $add"
+ if test "$hardcode_direct" != yes && \
+ test "$hardcode_minus_L" != yes && \
+ test "$hardcode_shlibpath_var" = yes; then
+ case ":$finalize_shlibpath:" in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test $linkmode = prog || test "$mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
if test "$hardcode_direct" = yes; then
- deplibs="$deplibs $libdir/$linklib"
+ add="$libdir/$linklib"
elif test "$hardcode_minus_L" = yes; then
add_dir="-L$libdir"
- add_name=yes
+ add="-l$name"
elif test "$hardcode_shlibpath_var" = yes; then
- add_name=yes
- else
- # We cannot seem to hardcode it, guess we'll fake it.
- add_dir="-L$libdir"
- add_name=yes
- fi
- fi
- if test "$hardcode_direct" != yes && \
- test "$hardcode_minus_L" != yes && \
- test "$hardcode_shlibpath_var" = yes; then
case ":$finalize_shlibpath:" in
*":$libdir:"*) ;;
*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
esac
- fi
- if test -n "$add_dir"; then
- case "$deplibs " in
- *" $add_dir "*) ;;
- *) deplibs="$deplibs $add_dir" ;;
- esac
- fi
- test "$add_name" = yes && deplibs="$deplibs -l$name"
-
- else
-
- lib_linked=yes
- add_dir=
- add_shlibpath=
- add_name=no
- case "$hardcode_action" in
- immediate | unsupported)
- if test "$hardcode_direct" = no; then
- compile_command="$compile_command $dir/$linklib"
- elif test "$hardcode_minus_L" = no; then
- case "$host" in
- *-*-sunos*) add_shlibpath="$dir" ;;
- esac
- add_dir="-L$dir"
- add_name=yes
- elif test "$hardcode_shlibpath_var" = no; then
- add_shlibpath="$dir"
- add_name=yes
+ add="-l$name"
else
- lib_linked=no
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ add="-l$name"
fi
- ;;
- relink)
- if test "$hardcode_direct" = yes; then
- compile_command="$compile_command $absdir/$linklib"
- elif test "$hardcode_minus_L" = yes; then
- add_dir="-L$absdir"
- add_name=yes
- elif test "$hardcode_shlibpath_var" = yes; then
- add_shlibpath="$absdir"
- add_name=yes
+ if test $linkmode = prog; then
+ if test -n "$add_dir"; then
+ case "$finalize_command " in
+ *" $add_dir "*) ;;
+ *) finalize_command="$finalize_command $add_dir" ;;
+ esac
+ fi
+ test -n "$add" && finalize_command="$finalize_command $add"
else
- lib_linked=no
+ if test -n "$add_dir"; then
+ case "$deplibs " in
+ *" $add_dir "*) ;;
+ *) deplibs="$deplibs $add_dir" ;;
+ esac
+ fi
+ test -n "$add" && deplibs="$deplibs $add"
fi
- ;;
-
- *) lib_linked=no ;;
- esac
-
- if test "$lib_linked" != yes; then
- $echo "$modename: configuration error: unsupported hardcode properties"
- exit 1
- fi
- if test -n "$add_dir"; then
- case "$compile_command " in
- *" $add_dir "*) ;;
- *) compile_command="$compile_command $add_dir" ;;
- esac
- fi
- if test -n "$add_shlibpath"; then
- case ":$compile_shlibpath:" in
- *":$add_shlibpath:"*) ;;
- *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
- esac
- fi
- test "$add_name" = yes && compile_command="$compile_command -l$name"
-
- add_dir=
- add_name=no
- # Finalize command for both is simple: just hardcode it.
- if test "$hardcode_direct" = yes; then
- finalize_command="$finalize_command $libdir/$linklib"
- elif test "$hardcode_minus_L" = yes; then
- add_dir="-L$libdir"
- add_name=yes
- elif test "$hardcode_shlibpath_var" = yes; then
- case ":$finalize_shlibpath:" in
- *":$libdir:"*) ;;
- *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
- esac
- add_name=yes
- else
- # We cannot seem to hardcode it, guess we'll fake it.
- add_dir="-L$libdir"
- add_name=yes
- fi
- if test -n "$add_dir"; then
- case "$finalize_command " in
- *" $add_dir "*) ;;
- *) finalize_command="$finalize_command $add_dir" ;;
- esac
- fi
- test "$add_name" = yes && finalize_command="$finalize_command -l$name"
-
fi
elif test $linkmode = prog; then
# Here we assume that one of hardcode_direct or hardcode_minus_L
fi
fi
- if test "$linkmode" = "lib"; then
+ if test $linkmode = lib; then
if test -n "$dependency_libs" &&
{ test "$hardcode_into_libs" = no || test $build_old_libs = yes ||
test $link_static = yes; }; then
case "$deplib" in
-L*) path="$deplib" ;;
*.la)
+ dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$deplib" && dir="."
+ # We need an absolute path.
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ absdir="$dir"
+ fi
+ ;;
+ esac
if grep "^installed=no" $deplib > /dev/null; then
- dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
- test "X$dir" = "X$deplib" && dir="."
- # We need an absolute path.
- case "$dir" in
- [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
- *)
- absdir=`cd "$dir" && pwd`
- if test -z "$absdir"; then
- $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
- absdir="$dir"
- fi
- ;;
- esac
path="-L$absdir/$objdir"
else
eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
$echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
exit 1
fi
- path="-L$libdir"
+ if test "$absdir" != "$libdir"; then
+ $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+ fi
+ path="-L$absdir"
fi
;;
- *)
- continue
- ;;
+ *) continue ;;
esac
case "$deplibs " in
*" $path "*) ;;
done
lib_search_path="$lib_search_path $sys_lib_search_path"
done
+ if test $linkmode = prog; then
+ dlfiles="$newdlfiles"
+ dlprefiles="$newdlprefiles"
+ fi
- case "$linkmode" in
+ case $linkmode in
oldlib)
if test -n "$deplibs"; then
$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
fi
fi
- if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
- $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+ if test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
fi
set dummy $rpath
if test -z "$rpath"; then
if test "$build_libtool_libs" = yes; then
# Building a libtool convenience library.
- libext=al
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
oldlibs="$output_objdir/$libname.$libext $oldlibs"
build_libtool_libs=convenience
build_old_libs=yes
oldlibs="$oldlibs $output_objdir/$libname.$libext"
# Transform .lo files to .o files.
- oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
fi
# Eliminate all temporary directories.
fi
fi
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) dlfiles="$dlfiles $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) dlprefiles="$dlprefiles $lib" ;;
+ esac
+ done
+
if test "$build_libtool_libs" = yes; then
if test -n "$rpath"; then
case "$host" in
esac
done
dependency_libs="$newdependency_libs"
+ newdlfiles=
+ for lib in $dlfiles; do
+ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdlfiles="$newdlfiles $libdir/$name"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdlprefiles="$newdlprefiles $libdir/$name"
+ done
+ dlprefiles="$newdlprefiles"
fi
$rm $output
$echo > $output "\
# Is this an already installed library?
installed=$installed
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
# Directory that this library needs to be installed in:
libdir='$install_libdir'"
if test "$installed" = no; then
*.lo)
staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
;;
- *.o | *.obj)
+ *.$objext)
staticdest="$destfile"
destfile=
;;