1999-01-21 Alexandre Oliva <oliva@dcc.unicamp.br>
+ * libltdl/configure.in: reintroduce code to detect native library
+ extension
+ * libltdl/ltdl.c (lt_dlopen): if a .la file name is given, that's
+ all. Otherwise, lt_dlopen now tries to append .la first. If this
+ fails, it tries the given filename, and, at last, tries to append
+ the native library extension to the given filename.
+ * doc/libtool.texi (lt_dlopen): explain new lookup strategy
+
* libltdl/ltdl.c: major rewrite to avoid almost all fixed-size
buffers; only `tmp' in lt_dlopen remained. But the code got ugly
:-(
@end deftypefun
@deftypefun lt_dlhandle lt_dlopen (const char *@var{filename})
-Open the module with the file name @var{filename} and
-return a handle for it.
-The module can be either a libtool module
-(the file name has a ".la" extension and the module was linked
-using the @code{-module} flag) or a native dynamic library.
-
+Open the module whose name is derived from @var{filename} and return a
+handle for it. @code{lt_dlopen} is able to open libtool dynamic
+modules, preloaded static modules and native dynamic libraries.
+
Unresolved symbols in the module are resolved using its dependency
-libraries and previously dlopened modules.
-If the executable using this module was linked with the @code{-export-dynamic}
-flag, then the global symbols in the executable will also be used to
-resolve references in the module.
-Libltdl tries to resolve the symbols immediately and returns NULL
-if that fails.
+libraries and previously dlopened modules. If the executable using this
+module was linked with the @code{-export-dynamic} flag, then the global
+symbols in the executable will also be used to resolve references in the
+module. Libltdl tries to resolve the symbols immediately and returns
+@code{NULL} if that fails.
-If libltdl cannot find the library and the file name @var{filename} does not
-have a directory component it will additionally search in the following
-search paths for the module (in the order as follows):
+If libltdl cannot find the library and the file name @var{filename} does
+not have a directory component it will additionally search in the
+following search paths for the module (in the order as follows):
@enumerate 1
@item user-defined search path:
If the same module is loaded several times, the same handle is returned.
If @code{lt_dlopen} fails for any reason, it returns NULL.
+
+@code{lt_dlopen} will preferentially open libtool modules. Therefore,
+if the @var{filename} does not end with the libtool archive extension,
+@samp{".la"}, @code{lt_dlopen} will automatically search for a libtool
+module by appending @samp{".la"} to the @var{filename}. If this fails,
+it assumes the @var{filename} refers to a native dynamic library, so
+tries to locate a library with the given name. If even this fails,
+@code{lt_dlopen} will try to append to @var{filename} the extension used
+for native dynamic libraries in the host platform, e.g., @samp{".so"},
+@samp{".sl"}, etc.
+
+This lookup strategy was designed to allow programs that have knowledge
+about native dynamic libraries naming conventions to be able to dlopen
+such libraries directly, and to allow programs that don't have this
+knowledge to let libltdl take care of this for them.
@end deftypefun
@deftypefun int lt_dlclose (lt_dlhandle @var{handle})
AM_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
+AC_CACHE_CHECK([which extension is used for shared libraries],
+ libltdl_cv_shlibext, [dnl
+(
+ rm -f conftest
+ ./libtool --config > conftest
+ . ./conftest
+ last=
+ for spec in $library_names_spec; do
+ last="$spec"
+ done
+ rm -f conftest
+changequote(, )
+ echo "$last" | sed '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")
+fi
+
AC_CACHE_CHECK([which variable specifies run-time library path],
libltdl_cv_shlibpath_var, [dnl
(
if (!handle)
goto clean_up_name;
} else {
+ /* try to append libtool library extension */
+ char *newfilename = malloc(strlen(filename)+4);
+ if (!newfilename) {
+ last_error = memory_error;
+ goto clean_up_dir;
+ }
+ strcpy(newfilename, filename);
+ strcat(newfilename, ".la");
+ handle = lt_dlopen(newfilename);
+ free(newfilename);
+ if (handle)
+ goto restore_error;
+
/* not a libtool module */
handle = (lt_dlhandle) malloc(sizeof(lt_dlhandle_t));
if (!handle) {
getenv(LTDL_SHLIBPATH_VAR))
#endif
))) {
- free(handle);
- handle = 0;
- goto clean_up_dir;
+#ifdef LTDL_SHLIB_EXT
+ newfilename = malloc(strlen(filename) +
+ strlen(LTDL_SHLIB_EXT) + 1);
+ if (!newfilename) {
+ last_error = memory_error;
+ goto clean_up_hand;
+ }
+ strcpy(newfilename, filename);
+ strcat(newfilename, LTDL_SHLIB_EXT);
+ basename = newfilename + (basename - filename);
+ if (tryall_dlopen(&handle, newfilename)
+ && (dir
+ || (find_library(&handle, basename, usr_search_path)
+ && find_library(&handle, basename,
+ getenv("LTDL_LIBRARY_PATH"))
+#ifdef LTDL_SHLIBPATH_VAR
+ && find_library(&handle, basename,
+ getenv(LTDL_SHLIBPATH_VAR))
+#endif
+ ))) {
+#endif
+ clean_up_hand:
+ free(handle);
+ handle = 0;
+ goto clean_up_dir;
+#ifdef LTDL_SHLIB_EXT
+ }
+#endif
}
handle->name = 0;
}
handle->usage = 1;
handle->next = handles;
handles = handle;
+ restore_error:
last_error = saved_error;
clean_up_dir:
if (dir)