mirror of
git://git.savannah.gnu.org/libtool.git
synced 2024-11-27 06:09:57 +08:00
Add a test to simulate a failure visible on systems which
need a library prefix like 'lib', such as BeOS. Fix a number of bugs exposed by this test in order for it to pass. Currently the prefix is hardcoded as 'lib', as I am not aware of systems that require a different prefix: * libltdl/loaders/preopen.c (lt_dlpreload_open): Move error condition out of test loop to be sure that each originator is tried, instead of erroring out if the first doesn't match. Support passing NULL as the originator to load all preloaded modules originating in the program itself. * libltdl/lt_dlloader.c (lt_dlloader_dump): New debug function. * libltdl/libltdl/lt_dlloader.h (lt_dlloader_dump): Declare it when LT_DEBUG_LOADERS is defined at compile time. * libltdl/ltdl.c (lt_dlinit): Dump loader list after successful initialisation. (tryall_dlopen): Add a new VTABLE parameter to force use of a specific loader in preference to trying every loader in turn. Adjust all callers. (try_dlopen): Always see whether a module was preloaded for module names with no directory component before searching the filesystem for a match. * libltdl/m4/libtool.m4 (_LT_CMD_GLOBAL_SYMBOLS): Declare a new global_symbol_to_c_name_address_lib_prefix variable. (global_symbol_to_c_name_address_lib_prefix): The sed expressions to use when a lib prefix is enforced need to be slightly different to work with preloaded modules. * libltdl/config/ltmain.m4sh (func_generate_dlsyms): In order to name preloaded symbols correctly for the lookup algorithm to work when the loaded module file must be prefixed with lib. Use global_symbol_to_c_name_address_lib_prefix when need_lib_prefix is other than no. * tests/need_lib_prefix.at: New test to check for breakage on hosts where need_lib_prefix is unknown. * Makefile.am (TESTSUITE_AT): Add new test. * tests/TODO: Note missing tests that would have caught some of the latent bugs fixed by this patch. * HACKING: Document libltdl keyword. * NEWS: Updated.
This commit is contained in:
parent
e6e96742ef
commit
a894e3baee
42
ChangeLog
42
ChangeLog
@ -1,3 +1,45 @@
|
||||
2007-06-24 Gary V. Vaughan <gary@gnu.org>
|
||||
|
||||
Add a test to simulate a failure visible on systems which
|
||||
need a library prefix like 'lib', such as BeOS. Fix a number
|
||||
of bugs exposed by this test in order for it to pass.
|
||||
Currently the prefix is hardcoded as 'lib', as I am not aware
|
||||
of systems that require a different prefix:
|
||||
|
||||
* libltdl/loaders/preopen.c (lt_dlpreload_open): Move error
|
||||
condition out of test loop to be sure that each originator is
|
||||
tried, instead of erroring out if the first doesn't match.
|
||||
Support passing NULL as the originator to load all preloaded
|
||||
modules originating in the program itself.
|
||||
* libltdl/lt_dlloader.c (lt_dlloader_dump): New debug function.
|
||||
* libltdl/libltdl/lt_dlloader.h (lt_dlloader_dump): Declare it
|
||||
when LT_DEBUG_LOADERS is defined at compile time.
|
||||
* libltdl/ltdl.c (lt_dlinit): Dump loader list after successful
|
||||
initialisation.
|
||||
(tryall_dlopen): Add a new VTABLE parameter to force use of a
|
||||
specific loader in preference to trying every loader in turn.
|
||||
Adjust all callers.
|
||||
(try_dlopen): Always see whether a module was preloaded for
|
||||
module names with no directory component before searching the
|
||||
filesystem for a match.
|
||||
* libltdl/m4/libtool.m4 (_LT_CMD_GLOBAL_SYMBOLS): Declare
|
||||
a new global_symbol_to_c_name_address_lib_prefix variable.
|
||||
(global_symbol_to_c_name_address_lib_prefix): The sed
|
||||
expressions to use when a lib prefix is enforced need to be
|
||||
slightly different to work with preloaded modules.
|
||||
* libltdl/config/ltmain.m4sh (func_generate_dlsyms): In order
|
||||
to name preloaded symbols correctly for the lookup algorithm
|
||||
to work when the loaded module file must be prefixed with lib.
|
||||
Use global_symbol_to_c_name_address_lib_prefix when
|
||||
need_lib_prefix is other than no.
|
||||
* tests/need_lib_prefix.at: New test to check for breakage on
|
||||
hosts where need_lib_prefix is unknown.
|
||||
* Makefile.am (TESTSUITE_AT): Add new test.
|
||||
* tests/TODO: Note missing tests that would have caught some
|
||||
of the latent bugs fixed by this patch.
|
||||
* HACKING: Document libltdl keyword.
|
||||
* NEWS: Updated.
|
||||
|
||||
2007-06-24 Gary V. Vaughan <gary@gnu.org>
|
||||
|
||||
Reenable compilation of libltdl with C++:
|
||||
|
5
HACKING
5
HACKING
@ -51,6 +51,10 @@ and is not part of a release distribution.
|
||||
3. Test Suite
|
||||
=============
|
||||
|
||||
* When writing tests, make sure the link invocation (first argument to
|
||||
AT_CHECK) is on a single line so that 'testsuite -x' displays the
|
||||
whole thing.
|
||||
|
||||
* Use
|
||||
make check TESTSUITEFLAGS=-V
|
||||
make check-local
|
||||
@ -60,6 +64,7 @@ and is not part of a release distribution.
|
||||
* The new Autotest testsuite uses keywords to denote test features:
|
||||
autoconf needs Autoconf
|
||||
automake needs Automake
|
||||
libltdl exercises the `libltdl' library
|
||||
libtool exercises the `libtool' script
|
||||
libtoolize exercises the `libtoolize' script
|
||||
recursive runs the suite recursively, with a modified
|
||||
|
@ -447,6 +447,7 @@ TESTSUITE_AT = tests/testsuite.at \
|
||||
tests/am-subdir.at \
|
||||
tests/lt_dlexit.at \
|
||||
tests/lt_dladvise.at \
|
||||
tests/need_lib_prefix.at \
|
||||
tests/standalone.at \
|
||||
tests/subproject.at \
|
||||
tests/nonrecursive.at \
|
||||
|
6
NEWS
6
NEWS
@ -2,12 +2,6 @@ NEWS - list of user-visible changes between releases of GNU Libtool
|
||||
|
||||
New in 2.1a: 2007-??-??; CVS version 2.1a, Libtool team:
|
||||
|
||||
* Regressions over 1.5.x that may be fixed later:
|
||||
|
||||
- On systems which need a library prefix like `lib', such as BeOS,
|
||||
libltdl currently does not build. The new structure of libltdl with
|
||||
preopened modules exposes some long-lived bugs here.
|
||||
|
||||
* Important incompatible changes and obsoleted features:
|
||||
|
||||
- Removed deprecated APIs from libltdl: lt_dlcaller_register,
|
||||
|
@ -1020,8 +1020,14 @@ lt_${my_prefix}_LTX_preloaded_symbols[] =
|
||||
{\
|
||||
{ \"$my_originator\", (void *) 0 },"
|
||||
|
||||
eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
|
||||
|
||||
case $need_lib_prefix in
|
||||
no)
|
||||
eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
|
||||
;;
|
||||
*)
|
||||
eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
|
||||
;;
|
||||
esac
|
||||
$ECHO >> "$output_objdir/$my_dlsyms" "\
|
||||
{0, (void *) 0}
|
||||
};
|
||||
|
@ -81,6 +81,10 @@ LT_SCOPE const lt_dlvtable *lt_dlloader_get (lt_dlloader loader);
|
||||
/* Type of a function to get a loader's vtable: */
|
||||
typedef const lt_dlvtable *lt_get_vtable (lt_user_data data);
|
||||
|
||||
#ifdef LT_DEBUG_LOADERS
|
||||
LT_SCOPE void lt_dlloader_dump (void);
|
||||
#endif
|
||||
|
||||
LT_END_C_DECLS
|
||||
|
||||
#endif /*!defined(LT_DLLOADER_H)*/
|
||||
|
@ -322,7 +322,8 @@ lt_dlpreload (const lt_dlsymlist *preloaded)
|
||||
|
||||
|
||||
/* Open all the preloaded modules from the named originator, executing
|
||||
a callback for each one. */
|
||||
a callback for each one. If ORIGINATOR is NULL, then call FUNC for
|
||||
each preloaded module from the program itself. */
|
||||
int
|
||||
lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func)
|
||||
{
|
||||
@ -334,7 +335,8 @@ lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func)
|
||||
for (list = preloaded_symlists; list; list = list->next)
|
||||
{
|
||||
/* ...that was preloaded by the requesting ORIGINATOR... */
|
||||
if (streq (list->symlist->name, originator))
|
||||
if ((originator && streq (list->symlist->name, originator))
|
||||
|| (!originator && streq (list->symlist->name, "@PROGRAM@")))
|
||||
{
|
||||
const lt_dlsymlist *symbol;
|
||||
unsigned int idx = 0;
|
||||
@ -360,12 +362,12 @@ lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
LT__SETERROR(CANNOT_OPEN);
|
||||
++errors;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
LT__SETERROR(CANNOT_OPEN);
|
||||
++errors;
|
||||
}
|
||||
|
||||
return errors;
|
||||
|
@ -97,6 +97,33 @@ lt_dlloader_add (const lt_dlvtable *vtable)
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef LT_DEBUG_LOADERS
|
||||
static void *
|
||||
loader_dump_callback (SList *item, void *userdata)
|
||||
{
|
||||
const lt_dlvtable *vtable = (const lt_dlvtable *) item->userdata;
|
||||
fprintf (stderr, ", %s", (vtable && vtable->name) ? vtable->name : "(null)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
lt_dlloader_dump (void)
|
||||
{
|
||||
fprintf (stderr, "loaders: ");
|
||||
if (!loaders)
|
||||
{
|
||||
fprintf (stderr, "(empty)");
|
||||
}
|
||||
else
|
||||
{
|
||||
const lt_dlvtable *head = (const lt_dlvtable *) loaders->userdata;
|
||||
fprintf (stderr, "%s", (head && head->name) ? head->name : "(null)");
|
||||
if (slist_tail (loaders))
|
||||
slist_foreach (slist_tail (loaders), loader_dump_callback, NULL);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* An iterator for the global loader list: if LOADER is NULL, then
|
||||
return the first element, otherwise the following element. */
|
||||
|
170
libltdl/ltdl.c
170
libltdl/ltdl.c
@ -1,7 +1,7 @@
|
||||
/* ltdl.c -- system independent dlopen wrapper
|
||||
|
||||
Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
|
||||
2007 Free Software Foundation, Inc.
|
||||
2007 Free Software Foundation, Inc.
|
||||
Written by Thomas Tanner, 1998
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the
|
||||
@ -120,7 +120,8 @@ static int try_dlopen (lt_dlhandle *handle,
|
||||
lt_dladvise advise);
|
||||
static int tryall_dlopen (lt_dlhandle *handle,
|
||||
const char *filename,
|
||||
lt_dladvise advise);
|
||||
lt_dladvise advise,
|
||||
const lt_dlvtable *vtable);
|
||||
static int unload_deplibs (lt_dlhandle handle);
|
||||
static lt__advise *advise_dup (lt__advise *advise);
|
||||
static int lt_argz_insert (char **pargz, size_t *pargz_len,
|
||||
@ -239,6 +240,10 @@ lt_dlinit (void)
|
||||
#endif /* HAVE_LIBDLLOADER */
|
||||
}
|
||||
|
||||
#ifdef LT_DEBUG_LOADERS
|
||||
lt_dlloader_dump();
|
||||
#endif
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
@ -332,17 +337,23 @@ lt_dlexit (void)
|
||||
}
|
||||
|
||||
|
||||
/* Try all dlloaders for FILENAME. If the library is not successfully
|
||||
loaded, return non-zero. Otherwise, the dlhandle is stored at the
|
||||
address given in PHANDLE. */
|
||||
/* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME.
|
||||
If the library is not successfully loaded, return non-zero. Otherwise,
|
||||
the dlhandle is stored at the address given in PHANDLE. */
|
||||
static int
|
||||
tryall_dlopen (lt_dlhandle *phandle, const char *filename,
|
||||
lt_dladvise advise)
|
||||
lt_dladvise advise, const lt_dlvtable *vtable)
|
||||
{
|
||||
lt__handle * handle = (lt__handle *) handles;
|
||||
const char * saved_error = 0;
|
||||
int errors = 0;
|
||||
|
||||
#ifdef LT_DEBUG_LOADERS
|
||||
fprintf (stderr, "tryall_dlopen (%s, %s)\n",
|
||||
filename ? filename : "(null)",
|
||||
vtable ? vtable->name : "(ALL)");
|
||||
#endif
|
||||
|
||||
LT__GETERROR (saved_error);
|
||||
|
||||
/* check whether the module was already opened */
|
||||
@ -391,42 +402,60 @@ tryall_dlopen (lt_dlhandle *phandle, const char *filename,
|
||||
}
|
||||
|
||||
{
|
||||
const lt_dlvtable *vtable = 0;
|
||||
lt_dlloader *loader = 0;
|
||||
lt_dlloader loader = lt_dlloader_next (0);
|
||||
const lt_dlvtable *loader_vtable;
|
||||
|
||||
while ((loader = (lt_dlloader *) lt_dlloader_next (loader)))
|
||||
do
|
||||
{
|
||||
lt__advise *advise_taken = 0;
|
||||
|
||||
if (advise)
|
||||
advise_taken = advise_dup ((lt__advise *) advise);
|
||||
|
||||
vtable = lt_dlloader_get (loader);
|
||||
handle->module = (*vtable->module_open) (vtable->dlloader_data,
|
||||
filename, advise_taken);
|
||||
if (vtable)
|
||||
loader_vtable = vtable;
|
||||
else
|
||||
loader_vtable = lt_dlloader_get (loader);
|
||||
|
||||
#ifdef LT_DEBUG_LOADERS
|
||||
fprintf (stderr, "Calling %s->module_open (%s)\n",
|
||||
(loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)",
|
||||
filename ? filename : "(null)");
|
||||
#endif
|
||||
handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data,
|
||||
filename, advise_taken);
|
||||
#ifdef LT_DEBUG_LOADERS
|
||||
fprintf (stderr, " Result: %s\n",
|
||||
handle->module ? "Success" : "Failed");
|
||||
#endif
|
||||
|
||||
if (handle->module != 0)
|
||||
{
|
||||
if (advise_taken)
|
||||
{
|
||||
handle->info.is_resident = advise_taken->is_resident;
|
||||
handle->info.is_symglobal = advise_taken->is_symglobal;
|
||||
handle->info.is_symlocal = advise_taken->is_symlocal;
|
||||
handle->info.is_resident = advise_taken->is_resident;
|
||||
handle->info.is_symglobal = advise_taken->is_symglobal;
|
||||
handle->info.is_symlocal = advise_taken->is_symlocal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
FREE (advise_taken);
|
||||
}
|
||||
while (!vtable && (loader = lt_dlloader_next (loader)));
|
||||
|
||||
if (!loader)
|
||||
/* If VTABLE was given but couldn't open the module, or VTABLE wasn't
|
||||
given but we exhausted all loaders without opening the module, bail
|
||||
out! */
|
||||
if ((vtable && !handle->module)
|
||||
|| (!vtable && !loader))
|
||||
{
|
||||
FREE (handle->info.filename);
|
||||
++errors;
|
||||
goto done;
|
||||
}
|
||||
|
||||
handle->vtable = vtable;
|
||||
handle->vtable = loader_vtable;
|
||||
}
|
||||
|
||||
LT__SETERRORSTR (saved_error);
|
||||
@ -474,9 +503,9 @@ tryall_dlopen_module (lt_dlhandle *handle, const char *prefix,
|
||||
if (prefix)
|
||||
{
|
||||
error += tryall_dlopen_module (handle, (const char *) 0,
|
||||
prefix, filename, advise);
|
||||
prefix, filename, advise);
|
||||
}
|
||||
else if (tryall_dlopen (handle, filename, advise) != 0)
|
||||
else if (tryall_dlopen (handle, filename, advise, 0) != 0)
|
||||
{
|
||||
++error;
|
||||
}
|
||||
@ -493,7 +522,7 @@ find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
|
||||
/* Try to open the old library first; if it was dlpreopened,
|
||||
we want the preopened version of it, even if a dlopenable
|
||||
module is available. */
|
||||
if (old_name && tryall_dlopen (handle, old_name, advise) == 0)
|
||||
if (old_name && tryall_dlopen (handle, old_name, advise, 0) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -513,14 +542,14 @@ find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
|
||||
if (!installed)
|
||||
{
|
||||
if (tryall_dlopen_module (handle, dir, objdir,
|
||||
dlname, advise) == 0)
|
||||
dlname, advise) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* maybe it was moved to another directory */
|
||||
{
|
||||
if (dir && (tryall_dlopen_module (handle, (const char *) 0,
|
||||
dir, dlname, advise) == 0))
|
||||
dir, dlname, advise) == 0))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -737,7 +766,7 @@ find_handle_callback (char *filename, void *data, void *data2)
|
||||
|
||||
/* Try to dlopen the file, but do not continue searching in any
|
||||
case. */
|
||||
if (tryall_dlopen (handle, filename, advise) != 0)
|
||||
if (tryall_dlopen (handle, filename, advise, 0) != 0)
|
||||
*handle = 0;
|
||||
|
||||
return 1;
|
||||
@ -1093,7 +1122,7 @@ cleanup:
|
||||
/* Try to open FILENAME as a module. */
|
||||
static int
|
||||
try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
|
||||
lt_dladvise advise)
|
||||
lt_dladvise advise)
|
||||
{
|
||||
const char * saved_error = 0;
|
||||
char * canonical = 0;
|
||||
@ -1107,6 +1136,12 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
|
||||
assert (phandle);
|
||||
assert (*phandle == 0);
|
||||
|
||||
#ifdef LT_DEBUG_LOADERS
|
||||
fprintf (stderr, "try_dlopen (%s, %s)\n",
|
||||
filename ? filename : "(null)",
|
||||
ext ? ext : "(null)");
|
||||
#endif
|
||||
|
||||
LT__GETERROR (saved_error);
|
||||
|
||||
/* dlopen self? */
|
||||
@ -1121,7 +1156,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
|
||||
/* lt_dlclose()ing yourself is very bad! Disallow it. */
|
||||
((lt__handle *) newhandle)->info.is_resident = 1;
|
||||
|
||||
if (tryall_dlopen (&newhandle, 0, advise) != 0)
|
||||
if (tryall_dlopen (&newhandle, 0, advise, 0) != 0)
|
||||
{
|
||||
FREE (*phandle);
|
||||
return 1;
|
||||
@ -1210,6 +1245,35 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
|
||||
name[ext - base_name] = LT_EOS_CHAR;
|
||||
}
|
||||
|
||||
/* Before trawling through the filesystem in search of a module,
|
||||
check whether we are opening a preloaded module. */
|
||||
if (!dir)
|
||||
{
|
||||
const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen");
|
||||
|
||||
if (vtable)
|
||||
{
|
||||
*phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle));
|
||||
|
||||
if (*phandle == NULL)
|
||||
{
|
||||
++errors;
|
||||
goto cleanup;
|
||||
}
|
||||
newhandle = *phandle;
|
||||
|
||||
if (tryall_dlopen (&newhandle, filename, advise, vtable) == 0)
|
||||
{
|
||||
goto register_handle;
|
||||
}
|
||||
|
||||
/* If we're still here, there was no matching preloaded module,
|
||||
so put things back as we found them, and continue searching. */
|
||||
FREE (*phandle);
|
||||
newhandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether we are opening a libtool module (.la extension). */
|
||||
if (ext && streq (ext, archive_ext))
|
||||
{
|
||||
@ -1225,16 +1289,14 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
|
||||
of libtool */
|
||||
int installed = 1;
|
||||
|
||||
|
||||
/* Now try to open the .la file. If there is no directory name
|
||||
component, try to find it first in user_search_path and then other
|
||||
prescribed paths. Otherwise (or in any case if the module was not
|
||||
yet found) try opening just the module name as passed. */
|
||||
component, try to find it first in user_search_path and then other
|
||||
prescribed paths. Otherwise (or in any case if the module was not
|
||||
yet found) try opening just the module name as passed. */
|
||||
if (!dir)
|
||||
{
|
||||
const char *search_path;
|
||||
const char *search_path = user_search_path;
|
||||
|
||||
search_path = user_search_path;
|
||||
if (search_path)
|
||||
file = find_file (user_search_path, base_name, &dir);
|
||||
|
||||
@ -1277,7 +1339,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
|
||||
/* read the .la file */
|
||||
if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
|
||||
&old_name, &installed) != 0)
|
||||
errors++;
|
||||
++errors;
|
||||
|
||||
fclose (file);
|
||||
|
||||
@ -1303,7 +1365,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
|
||||
newhandle = *phandle;
|
||||
/* find_module may replace newhandle */
|
||||
if (find_module (&newhandle, dir, libdir, dlname, old_name,
|
||||
installed, advise))
|
||||
installed, advise))
|
||||
{
|
||||
unload_deplibs (*phandle);
|
||||
++errors;
|
||||
@ -1347,7 +1409,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
|
||||
Otherwise (or in any case if the module was not yet found) try
|
||||
opening just the module name as passed. */
|
||||
if ((dir || (!find_handle (user_search_path, base_name,
|
||||
&newhandle, advise)
|
||||
&newhandle, advise)
|
||||
&& !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
|
||||
&newhandle, advise)
|
||||
#if defined(LT_MODULE_PATH_VAR)
|
||||
@ -1356,14 +1418,14 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
|
||||
#endif
|
||||
#if defined(LT_DLSEARCH_PATH)
|
||||
&& !find_handle (sys_dlsearch_path, base_name,
|
||||
&newhandle, advise)
|
||||
&newhandle, advise)
|
||||
#endif
|
||||
)))
|
||||
{
|
||||
if (tryall_dlopen (&newhandle, filename, advise) != 0)
|
||||
{
|
||||
newhandle = NULL;
|
||||
}
|
||||
if (tryall_dlopen (&newhandle, filename, advise, 0) != 0)
|
||||
{
|
||||
newhandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!newhandle)
|
||||
@ -1420,8 +1482,8 @@ file_not_found (void)
|
||||
static int
|
||||
has_library_ext (const char *filename)
|
||||
{
|
||||
char * ext = 0;
|
||||
size_t len;
|
||||
char * ext = 0;
|
||||
size_t len;
|
||||
|
||||
assert (filename);
|
||||
|
||||
@ -1430,7 +1492,7 @@ has_library_ext (const char *filename)
|
||||
|
||||
if (ext && ((streq (ext, archive_ext))
|
||||
#if defined(LT_MODULE_EXT)
|
||||
|| (streq (ext, shlib_ext))
|
||||
|| (streq (ext, shlib_ext))
|
||||
#endif
|
||||
))
|
||||
{
|
||||
@ -1528,7 +1590,7 @@ lt_dlhandle
|
||||
lt_dlopenadvise (const char *filename, lt_dladvise advise)
|
||||
{
|
||||
lt_dlhandle handle = 0;
|
||||
int errors = 0;
|
||||
int errors = 0;
|
||||
|
||||
/* Can't have symbols hidden and visible at the same time! */
|
||||
if (advise
|
||||
@ -1545,9 +1607,9 @@ lt_dlopenadvise (const char *filename, lt_dladvise advise)
|
||||
|| has_library_ext (filename))
|
||||
{
|
||||
/* Just incase we missed a code path in try_dlopen() that reports
|
||||
an error, but forgot to reset handle... */
|
||||
an error, but forgot to reset handle... */
|
||||
if (try_dlopen (&handle, filename, NULL, advise) != 0)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
return handle;
|
||||
}
|
||||
@ -1559,21 +1621,21 @@ lt_dlopenadvise (const char *filename, lt_dladvise advise)
|
||||
errors += try_dlopen (&handle, filename, archive_ext, advise);
|
||||
|
||||
/* If we found FILENAME, stop searching -- whether we were able to
|
||||
load the file as a module or not. If the file exists but loading
|
||||
failed, it is better to return an error message here than to
|
||||
report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
|
||||
in the module search path. */
|
||||
load the file as a module or not. If the file exists but loading
|
||||
failed, it is better to return an error message here than to
|
||||
report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
|
||||
in the module search path. */
|
||||
if (handle || ((errors > 0) && !file_not_found ()))
|
||||
return handle;
|
||||
return handle;
|
||||
|
||||
#if defined(LT_MODULE_EXT)
|
||||
/* Try appending SHLIB_EXT. */
|
||||
errors = try_dlopen (&handle, filename, shlib_ext, advise);
|
||||
|
||||
/* As before, if the file was found but loading failed, return now
|
||||
with the current error message. */
|
||||
with the current error message. */
|
||||
if (handle || ((errors > 0) && !file_not_found ()))
|
||||
return handle;
|
||||
return handle;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2170,9 +2232,9 @@ lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
|
||||
{
|
||||
interface_id->id_string = lt__strdup (id_string);
|
||||
if (!interface_id->id_string)
|
||||
FREE (interface_id);
|
||||
FREE (interface_id);
|
||||
else
|
||||
interface_id->iface = iface;
|
||||
interface_id->iface = iface;
|
||||
}
|
||||
|
||||
return (lt_dlinterface_id) interface_id;
|
||||
|
4
libltdl/m4/libtool.m4
vendored
4
libltdl/m4/libtool.m4
vendored
@ -3222,6 +3222,7 @@ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p'
|
||||
|
||||
# Transform an extracted symbol line into symbol name and symbol address
|
||||
lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
|
||||
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
|
||||
|
||||
# Handle CRLF in mingw tool chain
|
||||
opt_cr=
|
||||
@ -3375,6 +3376,9 @@ _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
|
||||
_LT_DECL([global_symbol_to_c_name_address],
|
||||
[lt_cv_sys_global_symbol_to_c_name_address], [1],
|
||||
[Transform the output of nm in a C name address pair])
|
||||
_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
|
||||
[lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
|
||||
[Transform the output of nm in a C name address pair when lib prefix is needed])
|
||||
]) # _LT_CMD_GLOBAL_SYMBOLS
|
||||
|
||||
|
||||
|
7
tests/TODO
Normal file
7
tests/TODO
Normal file
@ -0,0 +1,7 @@
|
||||
Please write the following testcases and submit to libtool-patches@gnu.org:
|
||||
|
||||
- ensure each libtool library 'originator' is tried.
|
||||
- check that passing NULL as the 'originator' correctly loads all
|
||||
preloaded modules originating from "self" (program itself).
|
||||
- test whether a preloaded library will open without the matching
|
||||
.la file.
|
179
tests/need_lib_prefix.at
Normal file
179
tests/need_lib_prefix.at
Normal file
@ -0,0 +1,179 @@
|
||||
# need-lib-prefix.at -- test libltdl functionality -*- Autotest -*-
|
||||
#
|
||||
# Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2007
|
||||
#
|
||||
# This file is part of GNU Libtool.
|
||||
#
|
||||
# GNU Libtool is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# GNU Libtool is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU Libtool; see the file COPYING. If not, a copy
|
||||
# can be downloaded from http://www.gnu.org/licenses/gpl.html,
|
||||
# or obtained by writing to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
####
|
||||
|
||||
AT_SETUP([enforced lib prefix])
|
||||
AT_KEYWORDS([libltdl libtool])
|
||||
|
||||
AT_DATA([main.c],
|
||||
[[#include <ltdl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef int fun (int);
|
||||
|
||||
static int errors = 0;
|
||||
|
||||
static void
|
||||
complain (const char *msg)
|
||||
{
|
||||
const char *errmsg = lt_dlerror ();
|
||||
fprintf (stderr, "%s", msg);
|
||||
if (errmsg)
|
||||
fprintf (stderr, ": %s\n", errmsg);
|
||||
else
|
||||
fprintf (stderr, ".\n");
|
||||
++errors;
|
||||
}
|
||||
|
||||
static lt_dlhandle
|
||||
moduleopen (const char *filename)
|
||||
{
|
||||
lt_dlhandle handle;
|
||||
|
||||
handle = lt_dlopen (filename);
|
||||
if (!handle)
|
||||
{
|
||||
fprintf (stderr, "can't open the module %s!\n", filename);
|
||||
complain ("error was");
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static int
|
||||
moduletest (lt_dlhandle handle)
|
||||
{
|
||||
const lt_dlinfo *info = lt_dlgetinfo (handle);
|
||||
fun *f = (fun *) lt_dlsym (handle, "f");
|
||||
int *v = (int *) lt_dlsym (handle, "i");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
complain ("function `f' not found");
|
||||
return 1;
|
||||
}
|
||||
if (!v)
|
||||
{
|
||||
complain ("variable `i' not found");
|
||||
return 1;
|
||||
}
|
||||
printf ("%s: %d\n", info->name, f (*v));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
lt_dlhandle handle;
|
||||
|
||||
LTDL_SET_PRELOADED_SYMBOLS();
|
||||
|
||||
if (lt_dlinit() != 0)
|
||||
{
|
||||
fprintf (stderr, "error during initialization: %s\n", lt_dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lt_dlpreload_open (0, moduletest) != 0)
|
||||
complain ("error during preloading");
|
||||
|
||||
if (lt_dlexit () != 0)
|
||||
complain ("error during exit");
|
||||
|
||||
return (errors != 0);
|
||||
}
|
||||
]])
|
||||
|
||||
AT_DATA([foo1.c],
|
||||
[[#define f foo1_LTX_f
|
||||
#define i foo1_LTX_i
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int f (int x) { return x / 3; }
|
||||
int i = 7;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
]])
|
||||
|
||||
AT_DATA([foo2.c],
|
||||
[[#define f libfoo2_LTX_f
|
||||
#define i libfoo2_LTX_i
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int f (int x) { return (x * x) / 10; }
|
||||
int i = 6;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
]])
|
||||
|
||||
AT_DATA([expout],
|
||||
[[libfoo1: 2
|
||||
libfoo2: 3
|
||||
]])
|
||||
|
||||
: ${LTDLINCL="-I$abs_top_srcdir/libltdl"}
|
||||
: ${LIBLTDL="$abs_builddir/../libltdl/libltdlc.la"}
|
||||
|
||||
CPPFLAGS="$CPPFLAGS $LTDLINCL"
|
||||
LDFLAGS="$LDFLAGS"
|
||||
|
||||
# Create our own libtool, forcing need_lib_prefix setting
|
||||
sed 's,^\(need_lib_prefix\)=.*$,\1=unknown,' $LIBTOOL > ./libtool
|
||||
LIBTOOL="$SHELL ./libtool"
|
||||
|
||||
# Installation directory:
|
||||
instdir=`pwd`/_inst
|
||||
|
||||
$CC $CPPFLAGS $CFLAGS -c main.c
|
||||
for file in foo1 foo2; do
|
||||
$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c $file.c
|
||||
done
|
||||
|
||||
AT_CHECK([$LIBTOOL --mode=link $CC -module -avoid-version $CFLAGS $LDFLAGS -o foo1.la foo1.lo -rpath $instdir/lib],
|
||||
[], [ignore], [ignore])
|
||||
AT_CHECK([$LIBTOOL --mode=link $CC -module -avoid-version $CFLAGS $LDFLAGS -o libfoo2.la foo2.lo -rpath $instdir/lib],
|
||||
[], [ignore], [ignore])
|
||||
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main main.$OBJEXT -dlpreopen foo1.la -dlpreopen libfoo2.la $LIBLTDL],
|
||||
[], [ignore], [ignore])
|
||||
|
||||
LT_AT_NOINST_EXEC_CHECK([./main], [-dlopen foo1.la -dlopen libfoo2.la],
|
||||
[], [expout], [])
|
||||
|
||||
# Install the libraries.
|
||||
mkdir $instdir
|
||||
mkdir $instdir/lib
|
||||
$LIBTOOL --mode=install cp foo1.la $instdir/lib/foo1.la
|
||||
$LIBTOOL --mode=install cp libfoo2.la $instdir/lib/libfoo2.la
|
||||
|
||||
# Install the binary
|
||||
mkdir $instdir/bin
|
||||
$LIBTOOL --mode=install cp main $instdir/bin/main
|
||||
|
||||
LT_AT_EXEC_CHECK([$instdir/bin/main], [], [expout], [])
|
||||
|
||||
AT_CLEANUP
|
Loading…
Reference in New Issue
Block a user