On 6/26/2010 2:51 PM, Ralf Wildenhues wrote:
> * Charles Wilson wrote on Fri, Jun 25, 2010 at 04:57:15AM CEST:
>> However, with this patch, helldl.exeS.c has:
> 
> IOW, all the spurious declarations are gone?  That'd be cool.

Correct.

>> (*) Note that you only need to determine the dll name for an import
>> lib using dlltool --identify or the fallback, IF and ONLY IF you are
>> linking to a library WITHOUT a corresponding .la file.

After trying unsuccesfully for hours to convince modern libtool to
actually allow me to DO this -- for testing purposes -- I wonder if
   -dlpreopen /usr/lib/somelib
where somelib is an .so or .a or .dll.a is ALLOWED at all.  I'm pretty
sure it USED to work -- like five or six years ago.  But it doesn't
appear to be documented to work that way, and I certainly can't figure
out how to get the libtool to even let me do it. It simply adds the
specified library to the link command, but never extracts a symbol table
for it.

If this is NOT actually supported, then I can simplify this patch quite
a bit I think. We'd no longer need ANY of the "figure out the .dll name
from the .dll.a" functions.

OTOH, if this mode IS supposed to be supported...then I think I've found
yet another bug, not covered by the test suite.  There's also this hint
that 1.5 years ago, I didn't explore this modality (-dlpreopen
not-an-la-file) very much:

http://lists.gnu.org/archive/html/libtool-patches/2009-01/msg00056.html
> Limitation: although I have beat this sed-fu

sed-fu: refers to the giant sed script in
func_cygming_dll_for_implib_fallback_core

> 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.

e.g. ".la" files

> 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.


So...can I get a verdict?  Is -dlpreopen not-an-la-file supposed to work?

>> If you DO have
>> a .la file for the library you're linking to, then the "save the .la
>> file using a magic shell variable" approach is used.
>
> OK.  Here's my take on this: if you fix all nits I noted inline below,
> post the updated and tested patch (you decide what testing is needed),
> then you are OK to commit after 72 hours of waiting.  FWIW, I'm likely
> not available most of next week; if we find issues later, then I guess
> they'll just have to be fixed afterwards.

OK.

> I'll note though that this patch makes me cringe: it introduces more
> system-specific code in ltmain that is just bloat on other systems,
> rather than in libtool.m4 where it belongs. 

Well, I did manage to come up with a mechanism to move most of

func_cygming_dll_for_implib
func_cygming_dll_for_implib_fallback
func_cygming_dll_for_implib_fallback_core
func_cygming_gnu_implib_p
func_cygming_ms_implib_p

into libtool.m4 (attached; only lightly tested pending Q above).
However, I can't see how to move the other mods in func_generate_dlsyms
and func_mode_link there.

I tried to use Gary's _LT_PROG_XSI_REPLACE function, but using a sed
script to create a sed script and all the quoting nightmares just made
my head hurt.  So, I have _LT_PROG_FUNCTION_REPLACE that uses the old
'copy half the script, emit the new function content, copy the rest of
the script' algorithm.

> It has the potential to
> regress non-cygwin non-mingw w32 systems, and since we effectively have
> no cegcc maintainer that is a problem for cegcc (dunno if for us).
> The patch doesn't introduce a new test, so I assume it either fixes a
> current testsuite failure in either the default setup or in the
>   ./configure --disable-static

It fixed an OLD failure in demo-shared/demo-make/demo-exec.  However,
this patch originally addressed 4 separate issues that were clustered
together -- but the demo-shared test failure actually exposed only one
of them.  In the interim, that particular issue was been, well, not
fixed I don't think, but rather avoided.  So, NOW, there is no actual
failure that this patch fixes.  The symbol list in demo-shared's .exe is
really ugly, but the test doesn't FAIL because of that.

> setup of Libtool.  If not, or if only the latter, then a testsuite
> addition in a followup patch would be nice.

OK, I'll look into that for a followup.

> Does this patch have any relation to Pierre Ossman's "Preloading without
> .la" patch?  http://thread.gmane.org/gmane.comp.gnu.libtool.general/7071
> His copyright papers are through now, so we can look at that patch.

Well, I *think* Pierre's patch would break cygwin -- but that'd be true
with or without this patch.  (The following statement in libltdl is not
true, for cygwin when -dlpreload and --disable-static):

/* Preloaded modules are always named according to their old
   archive name. */

because at least currently, the second entry in the
LTX_preloaded_symbols array is "cygfoo-N.dll" in those circumstances,
not "libfoo.a".

The title of Pierre's thread is a bit confusing (at least to me). What
he is talking about is using libltdl at runtime, with a variety of names
refering to the same library (module, module.la, module.a, etc).  That's
why HE means by "Preloading without .la". My Question above is about
*build* time, when you're trying to specify -dlpreopen not-a-.la.

>> --- a/libltdl/config/general.m4sh
>> +++ b/libltdl/config/general.m4sh
>> @@ -559,4 +559,21 @@ func_show_eval_locale ()
>>        fi
>>      fi
>>  }
>> +
>> +# func_tr_sh
>> +# Turn $1 into a string suitable for a shell variable name.
>> +# Result is stored in $func_tr_sh_result.  All characters
>> +# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
>> +# if $1 begins with a digit, a '_' is prepended as well.
>> +func_tr_sh ()
>> +{
>> +  case "$1" in
> 
> No double-quotes needed here.

Even if $1 might have spaces?   It's a pathname:

  func_tr_sh "$dlprefile"

But, I guess, since dlprefile obtained as a member of a space-separated
list, it BETTER not have any spaces in it. OK.

>> +                eval '$sharedlib_from_linklib "$dlprefile"'
> 
> redundant eval: remove eval and single quotes.

OBE in the new version.

>> +                eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
>> +                eval '$ECHO ": $name " >> "$nlist"'
> 
> Likewise.

Those are (copies, adaptations of) pre-existing code:

-         $opt_dry_run || {
-           eval '$ECHO ": $name " >> "$nlist"'
-           eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >>
'$nlist'"

I don't feel comfortable folding in a change like that as part of this
patch, but I'd be happy to supply a separate follow-on patch to change
them all at once.

>> +              fi
>> +              eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe |
>> +                $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> 
>> '$nlist'"
> 
> This can probably have the outer double quotes removed, eval moved to
> $global_symbol_pipe, and quotes around $nlist removed.  Actually, don't
> change this, because it might be the eval isn't needed at all; I will
> check this and change all uses in libtool then.

Again, this is a copy of pre-existing code, so...I'll leave this to you.

>> +              eval '$ECHO ": $name " >> "$nlist"'
> 
> Likewise eval and single quotes redundant.
>> +            eval '$ECHO ": $name " >> "$nlist"'
> 
> Likewise.

See above.

>> +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
>> +#
>> +# 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.
> 
> You'd save a fork if this function stores its result in a variable.
> I'd just use sharedlib_from_linklib_result for that.

I can't actually do this.  The problem is that the function is simply a
big pipeline:

  objdump $1 | sed | sed

So, the caller (func_cygming_dll_for_implib_fallback) invokes as

sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core
...`

which is a fork, it is true.  But for
func_cygming_dll_for_implib_fallback_core to put the result in a
variable, IT would have to do:

   sharedlib_from_linklib_result=`objdump $1 | sed | sed`

which is...an extra fork.  So it's six of one, a half-dozen of the
other.  (And, I found that I had difficulty trying to express it as
`objdump $1 | sed |sed` with such a complicated sed expression. sh was
not happy.

That's actually the REASON I split this operation into a main function
and a _core function.

>> +func_cygming_dll_for_implib_fallback_core ()
>> +{
>> +  $opt_debug
>> +  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
>> +    sed '/^Contents of section '"$1"':/{
> 
> Can $1 contain slash, dollar, ^, characters?

Yes.  In fact, it only ever has one of two values: '.idata$6' and
'.idata$7'.

>> +      # 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
> 
> What about x86-64, cegcc?  Look at func_win32_libid.
> \t is not portable sed, please use literal TAB then space.

Changed to /:[ \t]*file format pe[i]\{,1\}-$/d

which should match all of those variants.  I can't reuse the
func_win32_libid egrep expression, because this is sed.

>> +    /^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
> 
> typo remaining

Fixed.

>> +    # Of those that remain, print the first one.
>> +    sed -e '/^\./d' -e '/^.\./d' | sed -n -e '1p'
> 
> Can't you join the last three sed scripts?  Replace the last commmand /./p
> of the third-to-last script with
>   /^\./d
>   /^.\./d
>   p
>   q
> 
> and be done with it.  Right?

No, it doesn't work. The best I can do is consolidate them into a single
separate expression:

sed -e '/^\./d;/^.\./d;q'

>> +}
>> +
>> +# func_cygming_gnu_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_gnu_implib_p ()
>> +{
>> +  $opt_debug
>> +  func_cygming_gnu_implib_tmp=`eval "\$NM \$1 | \$global_symbol_pipe | 
>> \$EGREP ' (_head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname)\\\$'"`
> 
> What is the eval for here?  If it is needed, it should probably be
> before the assignment, a la
>   eval "func_cygming_gnu_implib_tmp=..."
> 
> or, if just for the symbol pipe, then just inside there, but the
> backslash before $global_symbol_pipe really makes no sense to me.
...
>> +  func_cygming_ms_implib_tmp=`eval "\$NM \$1 | \$global_symbol_pipe | grep 
>> '_NULL_IMPORT_DESCRIPTOR'"`
> 
> Likewise.
> 

It's only needed for $global_symbol_pipe.


>> +# _LT_DECL_DLLTOOL
>> +# --------------
> 
> Please align underline with title.

Ack.

>> +# If we don't have a new enough Autoconf to choose the best dlltool
>> +# available, choose the one first in the user's PATH.
> 
> What does this comment mean?  Copy and pasto garbage?

Yep. That's what _LT_DECL_OBJDUMP and _LT_DECL_EGREP say. I've removed
it from _LT_DECL_DLLTOOL, but I've left the other two alone.

> I'll note that _LT_DECL_DLLTOOL and _LT_DECL_OBJDUMP duplicate code from
> the win32-dll option setting in ltoptions.m4.  That is wrong.  I'll let
> it go through now because the problem isn't new.

Ack.

No changelog or in-depth testing on this version of the patch yet; if we
can dispense with all the dllname-from-implib stuff it'll be simplified
considerably, so it's not worth the effort until my Q is answered.

I did test it minimally on cygwin, mingw, and linux and it does work; I
just didn't do the whole regression suite.

--
Chuck

diff --git a/libltdl/config/general.m4sh b/libltdl/config/general.m4sh
index ab79f05..615c37f 100644
--- a/libltdl/config/general.m4sh
+++ b/libltdl/config/general.m4sh
@@ -594,4 +594,21 @@ func_show_eval_locale ()
       fi
     fi
 }
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case "$1" in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
 ]])
diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh
index 0262322..8226de3 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -1985,10 +1985,49 @@ extern \"C\" {
 	  func_verbose "extracting global C symbols from \`$dlprefile'"
 	  func_basename "$dlprefile"
 	  name="$func_basename_result"
-	  $opt_dry_run || {
-	    eval '$ECHO ": $name " >> "$nlist"'
-	    eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
-	  }
+          case $host in
+	    *cygwin* | *mingw* | *pw32* | *cegcc* )
+	      # if an import library, we need to obtain dlname
+	      if func_win32_import_lib_p "$dlprefile"; then
+	        func_tr_sh "$dlprefile"
+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
+	        dlprefile_dlbasename=""
+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+	          # Use subshell, to avoid clobbering current variable values
+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+	          if test -n "$dlprefile_dlname" ; then
+	            func_basename "$dlprefile_dlname"
+	            dlprefile_dlbasename="$func_basename_result"
+	          else
+	            # no lafile. user explicitly requested -dlpreopen <import library>.
+	            func_cmd_dll_for_implib "$dlprefile"
+	            dlprefile_dlbasename=$sharedlib_from_linklib_result
+	          fi
+	        fi
+	        $opt_dry_run || {
+	          if test -n "$dlprefile_dlbasename" ; then
+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+	          else
+	            func_warning "Could not compute DLL name from $name"
+	            eval '$ECHO ": $name " >> "$nlist"'
+	          fi
+	          eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe |
+	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+	        }
+	      else # not an import lib
+	        $opt_dry_run || {
+	          eval '$ECHO ": $name " >> "$nlist"'
+	          eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	        }
+	      fi
+	    ;;
+	    *)
+	      $opt_dry_run || {
+	        eval '$ECHO ": $name " >> "$nlist"'
+	        eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	      }
+	    ;;
+          esac
 	done
 
 	$opt_dry_run || {
@@ -2193,7 +2232,40 @@ func_win32_libid ()
   $ECHO "$win32_libid_type"
 }
 
-
+# func_cmd_dll_for_implib ARG
+# Default implementation for most platforms; replaced by
+# libtool.m4 with platform specific version if applicable.
+func_cmd_dll_for_implib ()
+{
+  sharedlib_from_linklib_result=$1
+} # func_cmd_dll_for_implib
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+# Default (empty) implementation for most platforms, and never
+# called on those systems.  Implementation is replaced by
+# libtool.m4 with platform specific version if applicable.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  func_fatal_error "func_cygming_dll_for_implib_fallback_core called inappropriately"
+} # func_cygming_dll_for_implib_fallback_core
+
+# func_cygming_gnu_implib_p ARG
+# Default (empty) implementation for most platforms, and never
+# called on those systems.  Implementation is replaced by
+# libtool.m4 with platform specific version if applicable.
+func_cygming_gnu_implib_p ()
+{
+  func_fatal_error "func_cygming_gnu_implib_p called inappropriately"
+} # func_cygming_gnu_implib_p
+
+# func_cygming_ms_implib_p ARG
+# Default (empty) implementation for most platforms, and never
+# called on those systems.  Implementation is replaced by
+# libtool.m4 with platform specific version if applicable.
+func_cygming_ms_implib_p ()
+{
+  func_fatal_error "func_cygming_ms_implib_p called inappropriately"
+} # func_cygming_ms_implib_p
 
 # func_extract_an_archive dir oldlib
 func_extract_an_archive ()
@@ -5140,20 +5212,46 @@ func_mode_link ()
 	  if test -z "$libdir" && test "$linkmode" = prog; then
 	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
 	  fi
-	  # Prefer using a static library (so that no silly _DYNAMIC symbols
-	  # are required to link).
-	  if test -n "$old_library"; then
-	    newdlprefiles="$newdlprefiles $dir/$old_library"
-	    # Keep a list of preopened convenience libraries to check
-	    # that they are being used correctly in the link pass.
-	    test -z "$libdir" && \
-		dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
-	  # Otherwise, use the dlname, so that lt_dlopen finds it.
-	  elif test -n "$dlname"; then
-	    newdlprefiles="$newdlprefiles $dir/$dlname"
-	  else
-	    newdlprefiles="$newdlprefiles $dir/$linklib"
-	  fi
+	  case "$host" in
+	    # special handling for platforms with PE-DLLs.
+	    *cygwin* | *mingw* | *cegcc* )
+	      # Linker will automatically link against shared library if both
+	      # static and shared are present.  Therefore, ensure we extract
+	      # symbols from the import library if a shared library is present
+	      # (otherwise, the dlopen module name will be incorrect).  We do
+	      # this by putting the import library name into $newdlprefiles.
+	      # We recover the dlopen module name by 'saving' the la file
+	      # name in a special purpose variable, and (later) extracting the
+	      # dlname from the la file.
+	      if test -n "$dlname"; then
+	        func_tr_sh "$dir/$linklib"
+	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+	        newdlprefiles="$newdlprefiles $dir/$linklib"
+	      else
+	        newdlprefiles="$newdlprefiles $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
+	      fi
+	    ;;
+	    * )
+	      # Prefer using a static library (so that no silly _DYNAMIC symbols
+	      # are required to link).
+	      if test -n "$old_library"; then
+	        newdlprefiles="$newdlprefiles $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
+	      # Otherwise, use the dlname, so that lt_dlopen finds it.
+	      elif test -n "$dlname"; then
+	        newdlprefiles="$newdlprefiles $dir/$dlname"
+	      else
+	        newdlprefiles="$newdlprefiles $dir/$linklib"
+	      fi
+	    ;;
+	  esac
 	fi # $pass = dlpreopen
 
 	if test -z "$libdir"; then
diff --git a/libltdl/m4/libtool.m4 b/libltdl/m4/libtool.m4
index 0b8a00e..b937841 100644
--- a/libltdl/m4/libtool.m4
+++ b/libltdl/m4/libtool.m4
@@ -168,6 +168,7 @@ _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
 dnl
 m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
 m4_require([_LT_CMD_RELOAD])dnl
 m4_require([_LT_CHECK_MAGIC_METHOD])dnl
 m4_require([_LT_CMD_OLD_ARCHIVE])dnl
@@ -752,6 +753,7 @@ _LT_EOF
      || (rm -f "$cfgfile"; exit 1)
 
   _LT_PROG_XSI_SHELLFNS
+  _LT_SHAREDLIB_FROM_LINKLIB_FNS
 
    mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
@@ -3289,6 +3291,158 @@ 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.
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_SED])
+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=default
+# The variable lt_cv_sharedlib_from_linklib_cmd is used to indicate;
+# to _LT_SHAREDLIB_FROM_LINKLIB_FNS which implementation to emit
+# into libtool.
+
+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=cygming_with_new_dlltool
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=cygming_with_old_dlltool
+    ;;
+  esac
+  ;;
+*)
+  lt_cv_sharedlib_from_linklib_cmd=default
+  ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=default
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+    [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+# _LT_SHAREDLIB_FROM_LINKLIB_FNS
+# ------------------------------
+# Emit the desired function bodies appropriate for this
+# platform, to be used to determine the name of the DLL
+# associated with a specific link library.
+m4_defun([_LT_SHAREDLIB_FROM_LINKLIB_FNS],
+[m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])
+case $sharedlib_from_linklib_cmd in
+cygming_with_new_dlltool )
+  _LT_PROG_FUNCTION_REPLACE([$cfgfile], [func_cmd_dll_for_implib],[dnl
+  # Platform-specific function implementation to extract the
+  # name of the DLL associated with the specified import library ARG.
+  # This implementation is specific for cygwin/mingw platforms whose
+  # dlltool application supports the --identify-strict option. The
+  # result is available in the variable
+  #    $sharedlib_from_linklib_result
+  $opt_debug
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$[]1"`])
+  ;;
+cygming_with_old_dlltool )
+  _LT_PROG_FUNCTION_REPLACE([$cfgfile], [func_cmd_dll_for_implib],[dnl
+  # Platform-specific function implementation to extract the
+  # name of the DLL associated with the specified import library ARG.
+  # This implementation is specific for cygwin/mingw platforms whose
+  # dlltool application does NOT supprt the --identify-strict option.
+  # The result is available in the variable
+  #    $sharedlib_from_linklib_result
+  $opt_debug
+  if func_cygming_gnu_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])
+  _LT_PROG_FUNCTION_REPLACE([$cfgfile], [func_cygming_dll_for_implib_fallback_core],[dnl
+  # The is the core of a platform-specific implementation of a
+  # function to extract the name of the DLL associated with the
+  # specified import library LIBNAME, for platforms whose dlltool
+  # application does NOT support the --identify-strict option.
+  #
+  # 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.
+  $opt_debug
+  $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
+    /:[[	 ]]*file format pe[[i]]\{,1\}-/d
+    /^In archive [[^:]]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining 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/[[\.	 ]]*$//
+      /./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;/^.\./d;q'])
+  _LT_PROG_FUNCTION_REPLACE([$cfgfile], [func_cygming_ms_implib_p],[dnl
+  # This predicate returns with zero status (TRUE) if
+  # ARG is an MS-style import library. Returns
+  # with nonzero status (FALSE) otherwise.
+  $opt_debug
+  func_cygming_ms_implib_tmp=`$NM $[]1 | eval "$global_symbol_pipe" | grep '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"])
+  _LT_PROG_FUNCTION_REPLACE([$cfgfile], [func_cygming_gnu_implib_p],[dnl
+  # This predicate returns with zero status (TRUE) if
+  # ARG is a GNU/binutils-style import library. Returns
+  # with nonzero status (FALSE) otherwise.
+  $opt_debug
+  func_cygming_gnu_implib_tmp=`$NM $[]1 | eval "$global_symbol_pipe" | $EGREP ' (_head_[[A-Za-z0-9_]]+_[[ad]]l*|[[A-Za-z0-9_]]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"])
+  ;;
+esac
+])# _LT_SHAREDLIB_FROM_LINKLIB_FNS
+
 
 # LT_LIB_M
 # --------
@@ -3415,8 +3569,8 @@ esac
 lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \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'"
+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=
@@ -4234,6 +4388,7 @@ m4_require([_LT_TAG_COMPILER])dnl
 AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
 m4_if([$1], [CXX], [
   _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
   case $host_os in
   aix[[4-9]]*)
     # If we're using GNU nm, then we don't want the "-C" option.
@@ -4250,13 +4405,13 @@ m4_if([$1], [CXX], [
     _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
   ;;
   cygwin* | mingw* | cegcc*)
-    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+    _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
   ;;
   *)
     _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
   ;;
   esac
-  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
 ], [
   runpath_var=
   _LT_TAGVAR(allow_undefined_flag, $1)=
@@ -4424,7 +4579,8 @@ _LT_EOF
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
       _LT_TAGVAR(always_export_symbols, $1)=no
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
 
       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'
@@ -7118,6 +7274,15 @@ _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
 AC_SUBST([OBJDUMP])
 ])
 
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+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
 # ------------
@@ -7251,19 +7416,41 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
 ])# _LT_CHECK_SHELL_FEATURES
 
 
+# _LT_PROG_FUNCTION_REPLACE (FILENAME, FUNCNAME, REPLACEMENT-BODY)
+# ----------------------------------------------------------------
+# In FILENAME, look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+_lt_func_repl_fail=0
+$SED -e '/^$2 ()$/,/^} # $2/c\
+## INSERT $2 HERE ##' < "$1" > "$1".tmp || _lt_func_repl_fail=1
+$SED '/^## INSERT $2 HERE ##$/q' < "$1".tmp | $SED '$d' > "$1".tmp2 || _lt_func_repl_fail=1
+$ECHO "$2 ()" >> "$1".tmp2 || _lt_func_repl_fail=1
+$ECHO "{" >> "$1".tmp2 || _lt_func_repl_fail=1
+cat >>"$1".tmp2 <<\_LT_EOF || _lt_func_repl_fail=1
+$3
+_LT_EOF
+$ECHO "} # custom $2 implementation" >> "$1".tmp2 || _lt_func_repl_fail=1
+$SED -n '/^## INSERT $2 HERE ##$/,$p' < "$1".tmp | $SED 1d >> "$1".tmp2 || _lt_func_repl_fail=1
+if test $_lt_func_repl_fail = 0; then
+  mv "$1".tmp2 "$1" || _lt_func_repl_fail=1
+fi
+rm -f "$1".tmp "$1".tmp2
+test $_lt_func_repl_fail = 0 || exit 1])
+
 # _LT_PROG_XSI_REPLACE (FUNCNAME, REPLACEMENT-BODY)
 # -------------------------------------------------
 # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
 # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
 m4_defun([_LT_PROG_XSI_REPLACE],
 [dnl {
-sed -i .tmp -e '/^$1 ()$/,/^} # $1 /c\
+sed -e '/^$1 ()$/,/^} # $1 /c\
 $1 ()\
 {\
 m4_bpatsubst([$2], [$], [\\])
-} # XSI $1 implementation' "$cfgfile" \
-  || (mv -f "$cfgfile.tmp" "$cfgfile"; exit 1)
-rm -f "$cfgfile.tmp"])
+} # XSI $1 implementation' < "$cfgfile" > "$cfgfile".tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" || exit 1])
 
 
 # _LT_PROG_XSI_SHELLFNS

Reply via email to