[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] [cygwin|mingw] fix dlpreopen with --disable-static take 3
From: |
Charles Wilson |
Subject: |
[PATCH] [cygwin|mingw] fix dlpreopen with --disable-static take 3 |
Date: |
Thu, 15 Jan 2009 23:25:25 -0500 |
* libltdl/m4/libtool.m4 (_LT_CHECK_SHAREDLIB_FROM_LINKLIB):
New macro sets sharedlib_from_linklib_cmd variable.
(_LT_DECL_DLLTOOL): New macro ensures DLLTOOL is always set.
* libltdl/config/ltmain.m4sh (func_generate_dlsyms): Use
$sharedlib_from_linklib_cmd instead of directly invoking
func_win32_dllname_for_implib when
libfile_$(transliterated implib name) does not exist.
(func_win32_libid): Accomodate pei-i386 import libs
as well as pe-i386.
(func_dlltool_identify): Removed.
(func_win32_dllname_for_implib): Removed. Replaced by...
(func_cygming_dll_for_implib): this,
(func_cygming_dll_for_implib_fallback): this,
(func_cygming_dll_for_implib_core): ...and this.
(func_cygming_implib_p): New function.
(func_cygming_ms_implib_p): New function.
---
This is a follow-on to:
http://lists.gnu.org/archive/html/libtool-patches/2009-01/msg00002.html
If the end result of these two patches is acceptable, I'll squash it
before merging to master. But, here's the rationale for the changes
here:
1) Try to make it easier for Peter to add MSVC-specific versions
of this functionality, by invoking the IMPLIB-to-DLL function
via a libtool variable (*)
2) Set that variable during configure
3) While we're at it, even on cygwin/mingw, decide whether to
use dlltool --identify or the nm/objdump-based shell script
"fallback" also at configure time
4) Since Danny Smith reports that even on mingw, ld can link
against MS-style import libraries, then ensure that both
versions of the IMPLIB-to-DLL function can perform properly
whether the implib is binutils- or ms- style.
a) dlltool (two patches, both already accepted):
http://sourceware.org/ml/binutils/2009-01/msg00120.html
http://sourceware.org/ml/binutils/2009-01/msg00179.html
b) improved sed-fu in func_cygming_dll_for_implib_core
with wrapper func_cygming_dll_for_implib_fallback.
Wrapper determines `style' of the implib, and invokes
the *_core() function with the appropriate arguments.
(*) Peter could implement two functions for msvc, as well: one
that directly invokes the new dllname application, and the other
which uses different, msvc-specific sed-fu on the output of
$NM (which in this case is actually `dumpbin --symbols'?). Then
in _LT_CHECK_SHAREDLIB_FROM_LINKLIB the determination could be
make as to which one to use, when $host is mingw and $CC is msvc.
Of course, if dllname does not become an official part of msys,
then Peter's additions to _LT_CHECK_SHAREDLIB_FROM_LINKLIB
would just set $sharedlib_from_linklib_cmd to the function
containing the msvc-sed-fu.
Limitation: although I have beat this sed-fu to death *outside*
of libtool, and am pretty confident it works well, there is no
actual test of that code in the testsuite. This is because well-
behaved libtool clients -- and our tests are actually well-behaved
in this regard -- will only -dlpreopen *libtool*-built libraries.
In that case, Ralf's suggested libfile_$(transliterated implib name)
is used, because we have the .la file available which allows that
shortcut. The only time we need `dlltool --identify' is when
dlpreopening a non-libtool implib, where we have no .la file.
And the sed-fu is a fallback to THAT fallback.
Also: is there someplace that libtool variables like
$sharedlib_from_linklib_cmd should be documented?
I did run configure and the demo-shared/demo-make/demo-exec tests
with (a) "old" --identify-less dlltool and (b) "new" --identify
dlltool. In each case, configure "picked" the correct function
for $sharedlib_from_linklib_cmd, and those tests passed.
Full test suite on cygwin in progress. Assuming it passes,
ok for squash and push?
Next step: make an actual "package" out of impgen2/dllname,
upload to mingw/sourceforge, and see if I can't convince Cesar
and Keith that it should be included in the 'base' MSYS for
release 1.0.11.
--
Chuck
libltdl/config/ltmain.m4sh | 200 +++++++++++++++++++++++++-------------------
libltdl/m4/libtool.m4 | 50 +++++++++++
2 files changed, 165 insertions(+), 85 deletions(-)
diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh
index 503457c..d701436 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -2016,8 +2016,8 @@ extern \"C\" {
dlprefile_dlbasename="$func_basename_result"
else
# no lafile. user explicitly requested -dlpreopen <import
library>.
- func_win32_dllname_for_implib "$dlprefile"
- dlprefile_dlbasename=$func_win32_dllname_for_implib_result
+ eval '$sharedlib_from_linklib "$dlprefile"'
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
fi
fi
$opt_dry_run || {
@@ -2217,7 +2217,7 @@ func_win32_libid ()
;;
*ar\ archive*) # could be an import, or static
if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
- $EGREP 'file format (pe-i386(.*architecture:
i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ $EGREP 'file format (pei?-i386(.*architecture:
i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
win32_nmres=`eval $NM -f posix -A $1 |
$SED -n -e '
1,100{
@@ -2247,99 +2247,129 @@ func_win32_libid ()
$ECHO "$win32_libid_type"
}
-# func_dlltool_identify
-# Determine if $DLLTOOL supports the --identify option
-func_dlltool_identify ()
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
{
$opt_debug
- if test -z "$func_dlltool_identify_result"; then
- case `$DLLTOOL --help` in
- *--identify*) func_dlltool_identify_result=: ;;
- *) func_dlltool_identify_result=false ;;
- esac
- fi
- $func_dlltool_identify_result
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
}
-# func_win32_dllname_for_implib implib
-# Obtain the name of the DLL associated with the
-# specified import library. Result is available
-# in $func_win32_dllname_for_implib_result.
+# func_cygming_dll_for_implib_core SECTION_NAME LIBNAMEs
#
-func_win32_dllname_for_implib ()
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
{
$opt_debug
- func_win32_dllname_for_implib_result=""
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ sed '/^Contents of section '"$1"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ \t]*file format pe[i]\{,1\}-i386$/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remoaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ sed -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p
+ ' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive which possess that section. Heuristic: eliminate
+ # all those which have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ sed -e '/^\./d' -e '/^.\./d' | sed -n -e '1p'
+}
- if func_dlltool_identify ; then
- func_win32_dllname_for_implib_result=`$DLLTOOL --identify "$1" 2>/dev/null`
- # if this fails, the fallback code is unlikely to succeed, so
- # we don't bother...
- else
- # use fallback dlltool does not have the --identify option.
- # make sure argument is actually an import library
- if func_win32_import_lib_p "$1"; then
- func_warn "Using fallback code to determine dllname for $1; consider
updating binutils to version 2.20 (2.19.50.20081115), or newer."
- # gcc puts dllname in the .idata$7 section of ONE member
- # of the import library -- but the name of that member is
- # random. No other member contains an .idata$7 section.
- # So, use objdump to print the contents. We get something
- # like the following (blank lines elided):
- #
- # |In archive /usr/lib/libncurses++.dll.a:
- # |d000253.o: file format pe-i386
- # |Contents of section .idata$7:
- # | 0000 6379676e 63757273 65732b2b 2d382e64 cygncurses++-8.d
- # | 0010 6c6c0000 ll..____________
- # |d000006.o: file format pe-i386
- # |d000252.o: file format pe-i386
- # |Contents of section .idata$7:
- # | 0000 00000000 ....____________
- #
- # where '_' represents a space character. So, we delete all
- # lines that have less than 43 characters, and chomp the
- # first 43 characters of the remaining lines. This gives us
- #
- # |cygncurses++-8.d
- # |ll..____________
- # |....____________
- #
- # We are not guaranteed that the name we want is first. So,
- # remove all newlines, then remove all sequences of two
- # or more . characters, then remove all sequences of two
- # or more whitespace characters. Finally, remove leading and
- # trailing whitespace. This would be simpler if we could
- # assume that the dllname does not contain whitespace, but we
- # DO assume the dllname doesn't contain *multiple* adjacent
- # whitespace, nor *multiple* adjacent . characters.
-
- func_win32_dllname_for_implib_result=`$OBJDUMP -s --section '.idata$7'
"$1" |
- $SED '/^[^ ]*\.o:/{
- s/.*//
- p
- d
- }
- /^.\{43\}/!d
- s/^.\{43\}//' |
- $SED -n '
- :more
- N
- /\n$/b work
- $!b more
- :work
- s/\n//g
- s/\.\.\.*//g
- s/[ ][ ][ ]*//g; s/^[ ]*//; s/[ ]*$//
- /./{
- p
- q
- }
- '`
- fi
- fi
+# func_cygming_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_implib_p ()
+{
+ $opt_debug
+ func_cygming_implib_tmp=`eval "\$NM \$1 | \$global_symbol_pipe | \$EGREP '
(_head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname)\\\$'"`
+ test -n "$func_cygming_implib_tmp"
}
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $opt_debug
+ func_cygming_ms_implib_tmp=`eval "\$NM \$1 | \$global_symbol_pipe | grep
'_NULL_IMPORT_DESCRIPTOR'"`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $opt_debug
+ if func_cygming_implib_p "$1" ; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core
'.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1" ; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core
'.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=""
+ fi
+}
# func_extract_an_archive dir oldlib
diff --git a/libltdl/m4/libtool.m4 b/libltdl/m4/libtool.m4
index 3f658ac..bf76bbe 100644
--- a/libltdl/m4/libtool.m4
+++ b/libltdl/m4/libtool.m4
@@ -168,6 +168,7 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_CHECK_SHELL_FEATURES])dnl
m4_require([_LT_CMD_RELOAD])dnl
m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
m4_require([_LT_CMD_OLD_ARCHIVE])dnl
m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
@@ -3190,6 +3191,45 @@ dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_PROG_NM], [])
dnl AC_DEFUN([AC_PROG_NM], [])
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# ----------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
# LT_LIB_M
# --------
@@ -6970,6 +7010,16 @@ _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
AC_SUBST([OBJDUMP])
])
+# _LT_DECL_DLLTOOL
+# --------------
+# If we don't have a new enough Autoconf to choose the best dlltool
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
# _LT_DECL_SED
# ------------
--
1.6.0.4
- [PATCH] [cygwin|mingw] fix dlpreopen with --disable-static take 3,
Charles Wilson <=