On Mac OS X try .dylib as well as .so with lt_dlopenext

* libltdl/m4/ltdl.m4: Define extra extension if module extension
differs from shared lib extension.
* libltdl/ltdl.c: Use it.
* tests/darwin.at: Test it.
* NEWS: Announce it.
Reported by Hans Aberg, Michael Ellis, and others.
This commit is contained in:
Peter O'Gorman 2011-03-04 14:35:14 -06:00
parent c44468e0ec
commit 6a6de36e4c
5 changed files with 257 additions and 2 deletions

View File

@ -1,3 +1,13 @@
2011-03-04 Peter O'Gorman <peter@pogma.com>
On Mac OS X try .dylib as well as .so with lt_dlopenext
* libltdl/m4/ltdl.m4: Define extra extension if module extension
differs from shared lib extension.
* libltdl/ltdl.c: Use it.
* tests/darwin.at: Test it.
* NEWS: Announce it.
Reported by Hans Aberg, Michael Ellis, and others.
2011-02-12 Peter O'Gorman <peter@pogma.com>
Install ltmain.sh without execute bit set.

3
NEWS
View File

@ -10,6 +10,9 @@ New in 2.4.2 2011-??-??: git version 2.4.1a, Libtool team:
- Initial support for Go, using the gccgo compiler.
- On Mac OS X .dylib is now tried as well as .so with
lt_dlopenext().
* Bug fixes:
- The generic approximation of the command line length limit (when getconf is

View File

@ -1,7 +1,7 @@
/* ltdl.c -- system independent dlopen wrapper
Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
2007, 2008 Free Software Foundation, Inc.
2007, 2008, 2011 Free Software Foundation, Inc.
Written by Thomas Tanner, 1998
NOTE: The canonical source of this file is maintained with the
@ -80,6 +80,11 @@ static const char libprefix[] = LT_LIBPREFIX;
#if defined(LT_MODULE_EXT)
static const char shlib_ext[] = LT_MODULE_EXT;
#endif
/* If the loadable module suffix is not the same as the linkable
* shared library suffix, this will be defined. */
#if defined(LT_SHARED_EXT)
static const char shared_ext[] = LT_SHARED_EXT;
#endif
#if defined(LT_DLSEARCH_PATH)
static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH;
#endif
@ -1536,6 +1541,9 @@ has_library_ext (const char *filename)
if (ext && ((streq (ext, archive_ext))
#if defined(LT_MODULE_EXT)
|| (streq (ext, shlib_ext))
#endif
#if defined(LT_SHARED_EXT)
|| (streq (ext, shared_ext))
#endif
))
{
@ -1682,6 +1690,17 @@ lt_dlopenadvise (const char *filename, lt_dladvise advise)
if (handle || ((errors > 0) && !file_not_found ()))
return handle;
#endif
#if defined(LT_SHARED_EXT)
/* Try appending SHARED_EXT. */
LT__SETERRORSTR (saved_error);
errors = try_dlopen (&handle, filename, shared_ext, advise);
/* As before, if the file was found but loading failed, return now
with the current error message. */
if (handle || ((errors > 0) && !file_not_found ()))
return handle;
#endif
}
/* Still here? Then we really did fail to locate any of the file

View File

@ -1,6 +1,6 @@
# ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*-
#
# Copyright (C) 1999-2006, 2007, 2008 Free Software Foundation, Inc.
# Copyright (C) 1999-2006, 2007, 2008, 2011 Free Software Foundation, Inc.
# Written by Thomas Tanner, 1999
#
# This file is free software; the Free Software Foundation gives
@ -553,12 +553,19 @@ AC_CACHE_CHECK([which extension is used for runtime loadable modules],
[
module=yes
eval libltdl_cv_shlibext=$shrext_cmds
module=no
eval libltdl_cv_shrext=$shrext_cmds
])
if test -n "$libltdl_cv_shlibext"; then
m4_pattern_allow([LT_MODULE_EXT])dnl
AC_DEFINE_UNQUOTED([LT_MODULE_EXT], ["$libltdl_cv_shlibext"],
[Define to the extension used for runtime loadable modules, say, ".so".])
fi
if test "$libltdl_cv_shrext" != "$libltdl_cv_shlibext"; then
m4_pattern_allow([LT_SHARED_EXT])dnl
AC_DEFINE_UNQUOTED([LT_SHARED_EXT], ["$libltdl_cv_shrext"],
[Define to the shared library suffix, say, ".dylib".])
fi
])# LT_SYS_MODULE_EXT
# Old name:

View File

@ -228,3 +228,219 @@ mv stdout expout
LT_AT_CONFIGURE([LDFLAGS=-L/there/is/no/dir/here])
AT_CHECK([./libtool --config],[ignore],[expout],[ignore])
AT_CLEANUP
AT_SETUP([darwin can lt_dlopen .dylib and .so files])
AT_KEYWORDS([libltdl dylib])
# This test requires shared library support.
AT_CHECK([$LIBTOOL --features | grep 'enable shared libraries' || exit 77],
[], [ignore])
eval `$LIBTOOL --config | $EGREP '^shrext_cmds='`
module=no
eval shared_ext=\"$shrext_cmds\"
module=yes
eval module_ext=\"$shrext_cmds\"
# Only bother with this test if module extension is different from
# shared extension
AT_CHECK([test "$shared_ext" != "$module_ext" || exit 77])
# Skip this test when called from:
# make distcheck DISTCHECK_CONFIGURE_FLAGS=--disable-ltdl-install
AT_CHECK([case $LIBLTDL in #(
*/_inst/lib/*) test -f $LIBLTDL || (exit 77) ;;
esac], [], [ignore])
prefix=`pwd`/inst
libdir=$prefix/lib
bindir=$prefix/bin
mkdir $prefix $libdir $bindir
# This code is copied from the Autobook:
# <http://sources.redhat.com/autobook/autobook/autobook_169.html>
# so if it needs changes, be sure to notify the Autobook authors
# about them.
AT_DATA([simple-module.c],
[[
#include <stdio.h>
#ifdef __cplusplus
extern "C"
#endif
int
run (const char *argument)
{
printf ("Hello, %s!\n", argument);
return 0;
}
]])
AT_DATA([ltdl-loader.c],
[[
#include <stdio.h>
#include <stdlib.h>
#ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
# define EXIT_SUCCESS 0
#endif
#include <limits.h>
#ifndef PATH_MAX
# define PATH_MAX 255
#endif
#include <string.h>
#include <ltdl.h>
#ifndef MODULE_PATH_ENV
# define MODULE_PATH_ENV "MODULE_PATH"
#endif
typedef int entrypoint (const char *argument);
/* Save and return a copy of the dlerror() error message,
since the next API call may overwrite the original. */
static char *dlerrordup (char *errormsg);
int
main (int argc, const char *argv[])
{
char *errormsg = NULL;
lt_dlhandle module = NULL;
entrypoint *run = NULL;
int errors = 0;
if (argc != 3)
{
fprintf (stderr, "USAGE: main MODULENAME ARGUMENT\n");
exit (EXIT_FAILURE);
}
/* Initialise libltdl. */
errors = lt_dlinit ();
/* Set the module search path. */
if (!errors)
{
const char *path = getenv (MODULE_PATH_ENV);
if (path != NULL)
errors = lt_dlsetsearchpath (path);
}
/* Load the module. */
if (!errors)
module = lt_dlopenext (argv[1]);
/* Find the entry point. */
if (module)
{
run = (entrypoint *) lt_dlsym (module, "run");
/* In principle, run might legitimately be NULL, so
I don't use run == NULL as an error indicator
in general. */
errormsg = dlerrordup (errormsg);
if (errormsg != NULL)
{
errors = lt_dlclose (module);
module = NULL;
}
}
else
errors = 1;
/* Call the entry point function. */
if (!errors)
{
int result = (*run) (argv[2]);
if (result < 0)
errormsg = strdup ("module entry point execution failed");
else
printf ("\t=> %d\n", result);
}
/* Unload the module, now that we are done with it. */
if (!errors)
errors = lt_dlclose (module);
if (errors)
{
/* Diagnose the encountered error. */
errormsg = dlerrordup (errormsg);
if (!errormsg)
{
fprintf (stderr, "%s: dlerror() failed.\n", argv[0]);
return EXIT_FAILURE;
}
}
/* Finished with ltdl now. */
if (!errors)
if (lt_dlexit () != 0)
errormsg = dlerrordup (errormsg);
if (errormsg)
{
fprintf (stderr, "%s: %s.\n", argv[0], errormsg);
free (errormsg);
exit (EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
/* Be careful to save a copy of the error message,
since the next API call may overwrite the original. */
static char *
dlerrordup (char *errormsg)
{
char *error = (char *) lt_dlerror ();
if (error && !errormsg)
errormsg = strdup (error);
return errormsg;
}
]])
: ${LTDLINCL="-I$abs_top_srcdir/libltdl"}
: ${LIBLTDL="$abs_builddir/../libltdl/libltdlc.la"}
CPPFLAGS="$LTDLINCL $CPPFLAGS"
LDFLAGS="$LDFLAGS -no-undefined"
AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c simple-module.c],
[], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o simple-module.la ]dnl
[simple-module.lo -rpath $libdir -module -avoid-version],
[], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o libsimple-dylib.la ]dnl
[simple-module.lo -rpath $libdir -avoid-version],
[], [ignore], [ignore])
AT_CHECK([$CC $CPPFLAGS $CFLAGS -c ltdl-loader.c],
[], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o ltdl-loader$EXEEXT ]dnl
[ltdl-loader.$OBJEXT -dlopen self $LIBLTDL],
[], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=install cp simple-module.la $libdir/simple-module.la], [], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=install cp libsimple-dylib.la $libdir/libsimple-dylib.la], [], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=clean rm -f simple-module.la], [], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=clean rm -f libsimple-dylib.la], [], [ignore], [ignore])
rm $libdir/simple-module.la
rm $libdir/libsimple-dylib.la
for dir in inst/lib "$libdir"; do
LT_AT_EXEC_CHECK([./ltdl-loader], [], [stdout], [ignore],
[$dir/simple-module World])
AT_CHECK([grep "Hello, World" stdout], [], [ignore])
LT_AT_EXEC_CHECK([./ltdl-loader], [], [stdout], [ignore],
[$dir/libsimple-dylib World])
AT_CHECK([grep "Hello, World" stdout], [], [ignore])
done
AT_CLEANUP