Resolves bug#13414. Problem reported by Erik van Pienbroek and Martin Doucha.
build-aux/ltmain.in (func_mode_link): Factor out the test if a given symbol file is a module-definition (.def) file into... (func_dll_def_p): ...this function, which also improves the check. m4/libtool.m4 (_LT_LINKER_SHLIBS, _LT_LANG_CXX_CONFIG) <cygwin, mingw, pw32, cegcc>: Similarly, factor out the test if a given symbol file is a module-definition (.def) file into... (_LT_DLL_DEF_P): ...this macro, which also improves the check. tests/export-def.at: New test. Makefile.am (TESTSUITE_AT): Add above test. NEWS: Update. THANKS: Update. Signed-off-by: Peter Rosin <p...@lysator.liu.se> # Conflicts: # # m4/libtool.m4 --- Makefile.am | 1 + NEWS | 3 + THANKS | 2 + build-aux/ltmain.in | 19 +++++++- m4/libtool.m4 | 31 ++++++++--- tests/export-def.at | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 186 insertions(+), 9 deletions(-) create mode 100755 tests/export-def.at diff --git a/Makefile.am b/Makefile.am index a3e3c7d..e5f3805 100644 --- a/Makefile.am +++ b/Makefile.am @@ -627,6 +627,7 @@ TESTSUITE_AT = tests/testsuite.at \ tests/runpath-in-lalib.at \ tests/static.at \ tests/export.at \ + tests/export-def.at \ tests/search-path.at \ tests/indirect_deps.at \ tests/archive-in-archive.at \ diff --git a/NEWS b/NEWS index c202c43..514768b 100644 --- a/NEWS +++ b/NEWS @@ -66,6 +66,9 @@ NEWS - list of user-visible changes between releases of GNU Libtool the Microsoft Visual C/C++ linker via the -export-symbols argument to the libtool script, thus matching how .def files are handled when using GNU tools. + - Recognize more variants (e.g. those starting with a LIBRARY statement) + of module-definitions (.def) files when using them instead of a raw + list of symbols to export. ** Important incompatible changes: diff --git a/THANKS b/THANKS index d4c1f1b..92e6dff 100644 --- a/THANKS +++ b/THANKS @@ -98,6 +98,7 @@ Edouard G. Parmelan edouard.parme...@france.ncr.com Erez Zadok e...@shekel.mcl.cs.columbia.edu Eric Estievenart e...@via.ecp.fr + Erik van Pienbroek erik-...@vanpienbroek.nl Ethan Mallove ethan.mall...@sun.com Frank Ch. Eigler f...@cygnus.com Fred Cox sailorf...@yahoo.com @@ -140,6 +141,7 @@ Marcel Loose lo...@astron.nl Mark Kettenis kette...@phys.uva.nl Markus Duft markus.d...@salomon.at + Martin Doucha dou...@integri.cz Matthijs Kooijman matth...@stdin.nl Micheal E. Faenza mfae...@mitre.org Michael Haubenwallner michael.haubenwall...@salomon.at diff --git a/build-aux/ltmain.in b/build-aux/ltmain.in index eb224e3..f0168da 100644 --- a/build-aux/ltmain.in +++ b/build-aux/ltmain.in @@ -1316,6 +1316,23 @@ func_convert_path_nix_to_cygwin () # end func_convert_path_nix_to_cygwin +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + # func_mode_compile arg... func_mode_compile () { @@ -7572,7 +7589,7 @@ EOF cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile - if test EXPORTS != "`$SED 1q $export_symbols`"; then + if ! func_dll_def_p "$export_symbols"; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. diff --git a/m4/libtool.m4 b/m4/libtool.m4 index 4bc9e98..0a6c334 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -3530,6 +3530,21 @@ _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + # LT_LIB_M # -------- # check for math library @@ -4782,9 +4797,9 @@ _LT_EOF if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test EXPORTS = "`$SED 1q $export_symbols`"; then + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; @@ -5162,7 +5177,7 @@ _LT_EOF shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test EXPORTS = "`$SED 1q $export_symbols`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else @@ -6154,7 +6169,7 @@ if test yes != "$_lt_caught_CXX_error"; then shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test EXPORTS = "`$SED 1q $export_symbols`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else @@ -6194,9 +6209,9 @@ if test yes != "$_lt_caught_CXX_error"; then if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test EXPORTS = "`$SED 1q $export_symbols`"; then + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; diff --git a/tests/export-def.at b/tests/export-def.at new file mode 100755 index 0000000..b8dfa55 --- /dev/null +++ b/tests/export-def.at @@ -0,0 +1,139 @@ +# export-def.at -- test module-definition files -*- Autotest -*- + +# Copyright (C) 2007-2008, 2011-2013 Free Software Foundation, Inc. +# Written by Peter Rosin, 2013 +# +# 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([export from a DLL with a .def file]) +AT_KEYWORDS([libtool]) + +AT_CHECK([$LIBTOOL --features | grep 'disable shared libraries' && (exit 77)], + [1], [ignore]) +eval `$LIBTOOL --config | $EGREP '^(shrext_cmds|libname_spec|soname_spec)='` + +eval shared_ext=\"$shrext_cmds\" + +# skip if not building a .dll +AT_CHECK([test .dll = "$shared_ext" || (exit 77)]) + +LDFLAGS="$LDFLAGS -no-undefined" +libdir=`pwd`/inst/lib +mkdir inst inst/lib + +AT_DATA([a.c], +[[/* a */ +#ifdef __cplusplus +extern "C" { +#endif + +int v1 = -1; +int v2 (void) { return -2; } + +#ifdef __cplusplus +} +#endif +]]) + +AT_DATA([syms], +[[v1 +v2 +]]) + +AT_DATA([def1], +[[EXPORTS +v1 DATA +v2 +]]) + +AT_DATA([def2], +[[; Def file + ; with some very important comments +EXPORTS +v1 DATA +v2 +]]) + +AT_DATA([def3], +[[ + EXPORTS v1 DATA + v2 +]]) + +AT_DATA([def4], +[[ LIBRARY %soname% +EXPORTS +v1 DATA +v2 +]]) + +AT_DATA([main.c], +[[ +/* w32 fun. With GCC, you can have auto-import, which will work for + * functions and non-const variables. With MSVC, you have to explicitly + * import all variables. + * + * For users, it's best to realize that they should not provide any + * non-function API at all. + */ +#if defined LIBA_DLL_IMPORT +# if defined _WIN32 && defined _MSC_VER +# define LIBA_SCOPE_VAR extern __declspec(dllimport) +# endif +#endif +#if !defined LIBA_SCOPE_VAR +# define LIBA_SCOPE_VAR extern +#endif +#ifdef __cplusplus +extern "C" { +#endif +LIBA_SCOPE_VAR int v1; +extern int v2(void); +#ifdef __cplusplus +} +#endif + +int main (void) +{ + return v1 + v2() + 3; +} +]]) + +name=a +eval libname=\"$libname_spec\" +major=0 +versuffix=-$major +eval soname=\"$soname_spec\" + +AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c a.c],[0],[ignore],[ignore]) +AT_CHECK([$CC $CPPFLAGS -DLIBA_DLL_IMPORT $CFLAGS -c main.c],[0],[ignore],[ignore]) + +for exportsyms in syms def1 def2 def3 def4 +do + $SED "s/%soname%/$soname/" -i $exportsyms + + LT_AT_CHECK([eval '$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la a.lo \ + -rpath $libdir' -export-symbols $exportsyms], [], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main$EXEEXT main.$OBJEXT liba.la], + [], [ignore], [ignore]) + LT_AT_EXEC_CHECK([./main]) +done + +AT_CLEANUP -- 1.7.9