Committed to master after testing on MinGW native and GNU/Linux native. Cheers, Ralf
2010-06-12 Peter Rosin <p...@lysator.liu.se> Ralf Wildenhues <ralf.wildenh...@gmx.de> Improve libdir usage from within ltdl on MinGW. * libltdl/ltdl.c (parse_dotla_file) [__WINDOWS__]: Read the libdir entry in the .la file, but accept it only if it is not a unix-style absolute name. * tests/ltdl-libdir.at: New test that checks if ltdl finds an installed module via the libdir variable in the .la file. On MinGW, use a Windows-style libdir name including drive spec. * Makefile.am: Add above. diff --git a/Makefile.am b/Makefile.am index 7c7f571..c3f74e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -486,6 +486,7 @@ TESTSUITE_AT = tests/testsuite.at \ tests/lt_dlopen.at \ tests/lt_dlopen_a.at \ tests/lt_dlopenext.at \ + tests/ltdl-libdir.at \ tests/ltdl-api.at \ tests/dlloader-api.at \ tests/loadlibrary.at \ diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index e1b4e2f..1213f0d 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -1079,14 +1079,17 @@ parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs, /* Windows native tools do not understand the POSIX paths we store in libdir. */ -#ifndef __WINDOWS__ #undef STR_LIBDIR #define STR_LIBDIR "libdir=" else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) { errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]); - } +#ifdef __WINDOWS__ + /* Disallow following unix-style paths on MinGW. */ + if (*libdir && (**libdir == '/' || **libdir == '\\')) + **libdir = '\0'; #endif + } #undef STR_DL_DEPLIBS #define STR_DL_DEPLIBS "dependency_libs=" diff --git a/tests/ltdl-libdir.at b/tests/ltdl-libdir.at new file mode 100644 index 0000000..432d18e --- /dev/null +++ b/tests/ltdl-libdir.at @@ -0,0 +1,119 @@ +# ltdl-libdir.at -- test libltdl functionality -*- Autotest -*- +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# 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([libdir of installed modules]) +AT_KEYWORDS([libltdl]) + +# This test requires shared library support. +AT_CHECK([$LIBTOOL --features | grep 'enable shared libraries' || exit 77], + [], [ignore]) + +# With MinGW, try Windows-style paths only. +if pwd -W >/dev/null 2>&1; then + prefix=`pwd -W`/inst +else + prefix=`pwd`/inst +fi +libdir=$prefix/lib +bindir=$prefix/bin +mkdir $prefix $libdir $bindir + +AT_DATA([a.c], +[[ +int f (void) +{ + return 42; +} +]]) + +AT_DATA([m.c], +[[ +#include <stdio.h> +#include <ltdl.h> + +typedef int func_f(void); + +int +main (int argc, const char *argv[]) +{ + lt_dlhandle module = NULL; + func_f *f = NULL; + + if (lt_dlinit()) { + fprintf(stderr, "lt_dlinit failed '%s'\n", lt_dlerror()); + return 1; + } + + module = lt_dlopen("./a.la"); + + if (!module) { + fprintf(stderr, "lt_dlopen failed '%s'\n", lt_dlerror()); + return 1; + } + + f = (func_f *)lt_dlsym(module, "f"); + + if (!f) { + fprintf(stderr, "lt_dlsym failed '%s'\n", lt_dlerror()); + return 1; + } + + if (f() != 42) { + fprintf(stderr, "f did not return 42\n"); + return 1; + } + + lt_dlclose(module); + lt_dlexit(); + return 0; +} +]]) + +: ${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 a.c], + [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o a.la ]dnl + [a.lo -rpath $libdir -module -shared -avoid-version], + [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c m.c], + [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m$EXEEXT ]dnl + [m.$OBJEXT $LIBLTDL], + [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=install cp a.la $libdir/a.la], + [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=install cp m$EXEEXT $bindir/m$EXEEXT], + [], [ignore], [ignore]) + +# Try finding the module via the libdir entry in a misplaced .la file. + +mv $libdir/a.la $bindir/a.la +cd $bindir +LT_AT_EXEC_CHECK([./m], + [], [ignore], [ignore]) + +AT_CLEANUP