libtool-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cygwin] eliminate wrapper script from '.' for win32


From: Charles Wilson
Subject: [cygwin] eliminate wrapper script from '.' for win32
Date: Mon, 23 Apr 2007 00:34:18 -0400
User-agent: Thunderbird 1.5.0.10 (Windows/20070221)

This patch depends on
  http://lists.gnu.org/archive/html/libtool-patches/2007-04/msg00048.html

http://lists.gnu.org/archive/html/libtool-patches/2007-04/msg00047.html
  http://lists.gnu.org/archive/html/libtool-patches/2007-04/msg00050.html


Theory:
  on cygwin/mingw, a wrapper executable is used which should invoke
  a wrapper script that is the typical libtool wrapper script as used
  on other platforms.  However, on win32 it should be hidden inside
  $objdir, and given a name distinct from its target.  I chose:
    .libs/foo_ltshwrapper
  The exectuable wrapper generates this file, on the fly, every time
  it is invoked.  Therefore, this wrapper script *does not exist*
  until the target executable is invoked.  These changes were
  implemented in the patches listed above.

  In general, libtool ALSO uses the wrapper script to "save"
  information about the target, and often sources it.  On mingw/cygwin,
  /this/ patch insures that a suitable wrapper script is generated
  at the same time the wrapper executable is created -- in fact, we
  use the wrapper executable to generate it.  However, we choose
  a *different* name than the one above:
    .libs/foo_ltshwrapperTMP
  Of course, other platforms continue to create a wrapper script as
  ./foo and do not use the executable wrapper at all.

  Thus, with this patch, on cygwin/mingw the '.' directory will contain
  only wrapper executables, and no wrapper scripts -- eliminating
  "foo.exe" vs "foo" confusion.  In $objdir, there will exist
    .libs/foo.exe
    .libs/foo_ltshwrapperTMP
    .libs/foo_ltshwrapper [ recreated on-demand ]
  (okay, maybe the names are backwards and/or silly, but that's a two
  line cosmetic patch)

Now, it is possible that we could use the *same* .libs/foo_ltshwrapper
file for both "execute" and "func_source" purposes. However:
  (a) I never want the executable wrapper to fail because the
      wrapper script is missing
  (b) I don't want the timestamp of the func_source()'ed wrapper
      script to depend on whether/when the target was executed
  (c) It is possible that, in the future, we will need to store
      different state in one of these two: for instance, the
      wrapper executable may eventually take another cmdline arg
      like "-ltrelinkcmd='.....'".  By using separate files,
      one "invisible" (created on the fly by the executable wrapper
      as a transparent part of its execv()-the-target proess), and
      one "visible" that is timestamped at the same time as the
      executable wrapper, we retain enough flexibility for the
      future. [* see mingw test results, below -- although I believe
      we should not be relinking on any win32 flavor, so I expect
      we will not need this flexibility in the immediate future,
      because the mingw regressions can/should be fixed via a mechanism
      other than the possibility described here *]

I'd like to be able to delete the "invisible" wrapper script
after use, but that's hard to arrange since we're using execv():
there is no execv(target)-and-tell-target-to-delete-itself-afterwards.

On mingw, this patch introduces a regression in the two -relink
tests.  However, there is no matching regression in cygwin.  So,
I think that whatever mechanism is allowing cygwin to PASS these
tests should be re-used on mingw if possible: because we shouldn't
be relinking on ANY flavor of win32.  If not, then something
along the lines of (c) above would be useful.

In any event, I'd like to request that this patch be applied
to HEAD even with the mingw regressions, so I can sort those
issues out later without being stuck with four patches in limbo...
   (1) argz
   (2) functionalize wrappers
   (3) cwrapper-emits-shwrapper
   (4) this
Or, if we can somehow break the logjam on (1)-(3), I can revise (4)
independently.

PORTABILITY ISSUE:
Implementation of func_ltwrapper_executable_p() greps $1 for
the expanded form of $magic.  This works because the wrapper
executable contains the wrapper script contents verbatim, and
the wrapper script tests $libtool_install_magic against the
expanded $magic.  HOWEVER, grepping a binary file?  Works on
cygwin and mingw without any problems, but I don't know if it's
kosher.

However, we're doing it already: even without this patch,
func_ltwrapper_p() can (and often is) called with a binary
as $1.  However, it delegates to func_lalib_p(), which does:
    $SED -e 4q "$1" 2>/dev/null \
      | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
So...I reckon grepping a binary file isn't an issue.


TEST RESULTS:
=================================================

cygwin: (full testsuite)
  old tests: no regressions
  new tests: no regressions (still fails 14 16 49)

mingw: (old tests only), have regressions:
  FAIL: tests/demo-relink.test
  FAIL: tests/depdemo-relink.test

linux: (full testsuite)
  old tests: no regressions
  new tests: no regressions (still fails 37 38 39 40 41 42)
             recall: I believe these are false failures,
             related to using a different version of the
             autotools to bootstrap vs. running the tests.

ChangeLog:

2007-04-22  Charles Wilson  <address@hidden>

        * libltdl/config/ltmain.m4sh (func_ltwrapper_script_p):
        new function detects if $1 is a libtool sh wrapper
        (func_ltwrapper_executable_p): new function detects
        if $1 is a libtool executable wrapper
        (func_ltwrapper_p): modified to detect is $1 is ANY
        sort of libtool wrapper
        (func_ltwrapper_temp_scriptname): new function generates
        appropriate pathname for temporary libtool wrapper script
        if libtool executable wrappers are in use.  This temporary
        script is suitable for use with func_source().
        (func_mode_execute): handle $file that is a libtool wrapper
        script and $file that is a libtool wrapper executable
        differently.
        (func_mode_install) [cygwin|mingw]: if $file is a libtool
        wrapper executable, use func_ltwrapper_temp_scriptname()
        to determine wrapper script name.  After determining name
        of wrapper script, use func_ltwrapper_script_p() instead
        of func_ltwrapper_p().
        (func_mode_link) [cygwin|mingw]: don't call dirname and
        basename directly; use func_dirname() and func_basename()
        when computing cwrapper names.  Use cwrapper to generate
        wrapper script, and use pathname returned by
        func_ltwrapper_temp_scriptname() instead of $output.
        (func_mode_link) [NOT cygwin|mingw]: move wrapper script
        generation for non-win32 inside case statement, as default
        case.
        (func_mode_uninstall) [$name's extension != .lo|.la]:
        'clean' mode must handle $file differently if it is a libtool
        wrapper script, or if it is a libtool wrapper executable.

--
Chuck

Index: libltdl/config/ltmain.m4sh
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/config/ltmain.m4sh,v
retrieving revision 1.72
diff -u -r1.72 ltmain.m4sh
--- libltdl/config/ltmain.m4sh  2007-04-22 19:17:05.437500000 -0400
+++ libltdl/config/ltmain.m4sh  2007-04-22 22:04:50.657250000 -0400
@@ -661,13 +661,61 @@
     test "$lalib_p" = yes
 }
 
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_executable_p_result=no
+    if ! func_ltwrapper_script_p "$1" ; then
+      case "$1" in
+        *.exe ) if grep "$magic" "$1" >/dev/null ; then
+                    func_ltwrapper_executable_p_result=yes
+                fi ;;
+        * )     if grep "$magic" "${1}.exe" >/dev/null ; then
+                    func_ltwrapper_executable_p_result=yes
+                fi ;;
+      esac
+    fi
+    test "$func_ltwrapper_executable_p_result" = "yes"
+}
+
+# func_ltwrapper_temp_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_temp_scriptname ()
+{
+    func_ltwrapper_temp_scriptname_result=""
+    if func_ltwrapper_executable_p "$1"; then
+        func_dirname "$1"
+        func_basename "$1"
+        func_stripname '' '.exe' "$func_basename_result"
+       if test -z "$func_dirname_result"; then
+          
func_ltwrapper_temp_scriptname_result="./$objdir/${func_stripname_result}_ltshwrapperTMP"
+        else
+          
func_ltwrapper_temp_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapperTMP"
+        fi
+    fi     
+}
+
 # func_ltwrapper_p file
-# True iff FILE is a libtool wrapper script.
+# True iff FILE is a libtool wrapper script or wrapper executable
 # This function is only a basic sanity check; it will hardly flush out
 # determined imposters.
 func_ltwrapper_p ()
 {
-    func_lalib_p "$1"
+    func_ltwrapper_script_p "$1" || func_ltwrapper_execuable_p "$1"
 }
 
 
@@ -1649,11 +1697,17 @@
       -*) ;;
       *)
        # Do a test to see if this is really a libtool program.
-       if func_ltwrapper_p "$file"; then
-         func_source "$file"
-
+       if func_ltwrapper_script_p "$file"; then
+          func_source "$file"
          # Transform arg to wrapped name.
          file="$progdir/$program"
+        else
+          if func_ltwrapper_executable_p "$file"; then
+            func_ltwrapper_temp_scriptname "$file"
+           func_source "$func_ltwrapper_temp_scriptname_result"
+           # Transform arg to wrapped name.
+           file="$progdir/$program"
+          fi
        fi
        ;;
       esac
@@ -2085,14 +2139,19 @@
        # Do a test to see if this is really a libtool program.
        case $host in
        *cygwin*|*mingw*)
-           func_stripname '' '.exe' "$file"
-           wrapper=$func_stripname_result
+            if func_ltwrapper_executable_p "$file"; then
+             func_ltwrapper_temp_scriptname "$file"
+             wrapper="$func_ltwrapper_temp_scriptname_result"
+            else
+              func_stripname '' '.exe' "$file"
+              wrapper="$func_stripname_result"
+            fi
            ;;
        *)
            wrapper=$file
            ;;
        esac
-       if func_ltwrapper_p "$wrapper"; then
+       if func_ltwrapper_script_p "$wrapper"; then
          notinst_deplibs=
          relink_command=
 
@@ -6699,8 +6758,13 @@
        esac
        case $host in
          *cygwin* | *mingw* )
-           output_name=`basename $output`
-           output_path=`dirname $output`
+           func_basename "$output"
+           output_name="$func_basename_result"
+           func_dirname "$output"
+           output_path="$func_dirname_result"
+           if test -z "$output_path"; then
+             output_path=.
+           fi
            cwrappersource="$output_path/$objdir/lt-$output_name.c"
            cwrapper="$output_path/$output_name.exe"
            $RM $cwrappersource $cwrapper
@@ -6708,19 +6772,30 @@
 
            func_emit_libtool_cwrapperexe_source > $cwrappersource
 
-         # we should really use a build-platform specific compiler
-         # here, but OTOH, the wrappers (shell script and this C one)
-         # are only useful if you want to execute the "real" binary.
-         # Since the "real" binary is built for $host, then this
-         # wrapper might as well be built for $host, too.
-         $opt_dry_run || $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
+           # we should really use a build-platform specific compiler
+           # here, but OTOH, the wrappers (shell script and this C one)
+           # are only useful if you want to execute the "real" binary.
+           # Since the "real" binary is built for $host, then this
+           # wrapper might as well be built for $host, too.
+           $opt_dry_run || $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
+
+           # Now, create the wrapper script for func_source use:
+           func_ltwrapper_temp_scriptname $cwrapper
+           $RM $func_ltwrapper_temp_scriptname_result
+           trap "$RM $func_ltwrapper_temp_scriptname_result; exit 
$EXIT_FAILURE" 1 2 15
+           $opt_dry_run || {
+             $cwrapper -ltdumpscript > $func_ltwrapper_temp_scriptname_result
+           }
+           chmod +x $func_ltwrapper_temp_scriptname_result
          ;;
-       esac
-       $RM $output
-       trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+         * )
+           $RM $output
+           trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
 
-       func_emit_libtool_wrapper_script > $output
-       chmod +x $output
+           func_emit_libtool_wrapper_script > $output
+           chmod +x $output
+         ;;
+       esac
       }
       exit $EXIT_SUCCESS
       ;;
@@ -7170,8 +7245,15 @@
          esac
          # Do a test to see if this is a libtool program.
          if func_ltwrapper_p "$file"; then
-           relink_command=
-           func_source $dir/$noexename
+            if func_ltwrapper_executable_p "$file"; then
+              func_ltwrapper_temp_scriptname "$file"
+              relink_command=
+              func_source $func_ltwrapper_temp_scriptname_result
+              rmfiles="$rmfiles $func_ltwrapper_temp_scriptname_result"
+            else
+             relink_command=
+             func_source $dir/$noexename
+            fi
 
            # note $name still contains .exe if it was in $file originally
            # as does the version of $file that was added into $rmfiles

reply via email to

[Prev in Thread] Current Thread [Next in Thread]