Hi Ralf!

Den 2010-06-14 22:40 skrev Ralf Wildenhues:
[ adding automake-patches; this is
   http://thread.gmane.org/gmane.comp.gnu.libtool.general/10927/focus=10954 ]

* Peter Rosin wrote on Mon, Jun 14, 2010 at 09:35:45AM CEST:
Den 2010-06-12 10:05 skrev Ralf Wildenhues:
Well, I sort of figured that the 'compile' script could end up absorbing
quite a bit of the cccl functionality so to make it unneeded.  But hey,
let's be honest, somebody would have to do this work, because I don't
have the resources to do it.

Do you think something along these lines would be acceptable? It would
remove the need of some patches on the pr-msvc-support branch...

The patch looks pretty good to me already, but is lacking additions for
ChangeLog, NEWS, and maybe doc/ and tests/ too.

Right.

[snip useful advice]

Running the tests are still an outright pain though, but I will try it.
But it might take some time, I'm not used to running them and msys
is...cumbersome. Meanwhile, I have attached the current version of the
patch in case there are further things to fix.

Some nits and questions:

+      case $path_conv in
+       mingw)
+         path=`cmd //C echo "$path " | sed -e 's/"\(.*\) " *\$/\1/'`

I fail to understand what this sed script is for.  Help?

It was the easiest I could come up with after experimenting a lot. That
wasn't yesterday though, but IIRC if you want to convert paths with
spaces, you need to quote the $path for cmd, hence the quotes in the
echo "$path " construct. The space before the end quote will make the
argument always contain a space which forces MSYS to add quotes when the
path is fed to the Windows process (cmd in this case). The quotes are
added by MSYS after converting the path to windows form. Without that
space, the string is only quoted if it happens to contain a space, so
view it as a canonicalizer. The sed script is there to remove those
quotes (and the space before the end quote). Also, something seem to
mysteriously add a space at the end, so I'm removing that too while at
it, but only if it's really there (it felt like a bug that might be
fixed at some point). It might be possible to use eval to remove the
quotes, but since the path will typically contain backslashes I didn't
want to go there.

+       cygwin)
+         path=`cygpath -w "$path"`

IIUC cygpath is pretty much required to be present on Cygwin
installations, right?  Can it fail though?  Should $path retain its old
value if it does?  Don't we want -m rather than -w for forward slashes
(which IIUC even MSVC programs should support) to avoid quoting issues?
   path=`cygpath -m "$path" || echo "$path"`

The mingw case and the wine case have backlashes, so in that case those
too have to be turned into forward slashes. But since this is the end of
the line (isn't it?), I don't really see the need to use forward slashes.
The only consumer of those paths is cl.exe (and friends).

+       wine)
+         path=`winepath -w "$path"`

winepath OTOH may not be present, so this should definitely fall back to
the unconverted path I think.  And maybe the path_conv-setting code
check for presence of winepath.

I added the wine stuff more as an afterthought, but adding that fallback
is easy enough. Done.

+       -L*)
+         func_path_conv "${1#-L}"
+         export LINK="$LINK -LIBPATH:$path"

Is LINK a predefined variable?  Does it come from libtool?  Or from the
user or the system?

There are three ways to get options through to the linker, IIUC. By
1) using the LINK environment variable. The user might have put
   stuff in it, so therefore preserve that and add any further
   options at the end.
2) using "-link <opt> ..." on the command line, but that has the
   disadvantage that *all* options after -link are fed to the
   linker. Hmmm, but here we have control over that, so using
   that approach is feasible.
3) using a response file, then you can feed options to the
   compiler and the linker in whatever order you like, but with
   the disadvantage that you need to clean up the (temporary)
   response file (costs a fork).

My libtool patches used #1, that is the only relation to libtool.
This new version uses #2 instead. I think that might be clearer?

+         ;;
+       -Wl,*)
+         arg=${1#-Wl,}
+         save_ifs="$IFS"; IFS=','
+         for flag in $arg; do
+           IFS="$save_ifs"
+           export LINK="$LINK $flag"
+         done
+         IFS="$save_ifs"

For this, IFS needs to be initialized to default near the beginning of
the script (there is an embedded TAB in the last line):

nl='
'
IFS=" "" "$nl"

Wasn't aware of that, thanks! But you have five quotes, that's wrong
I suppose, so I removed the one before $nl.

Is the nl variable needed though? I thought this looked good:
IFS=' ''        ''
'

+    shift
+  done
+  exec "$@"

There needs to be an 'exit 1' here, in case exec fails.

Good call, and thanks for the review!

Cheers,
Peter
commit ddfb842637997554b16d6a427bb77fd679050c1c
Author: Peter Rosin <p...@lysator.liu.se>
Date:   Wed Jun 16 14:13:43 2010 +0200

    Wrap some MSVC options in the compile script.
    
    * lib/compile: MSVC supports naming the output file, the option
    is just not called -o, so transform -o into the appropriate form
    for MSVC. Also wrap some other options while at it (-L, -l, -Wl,
    -Xlinker and -I) and convert paths to windows form where needed
    for those options to make MSVC more usable in an autotooled
    environment.
    * doc/automake.texi (Auxiliary Programs): Document the above
    extension of the compile script.
    * NEWS: Updated.

diff --git a/ChangeLog b/ChangeLog
index b5f1433..bc61105 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2010-06-16  Peter Rosin  <p...@lysator.liu.se>
+
+       Wrap some MSVC options in the compile script.
+       * lib/compile: MSVC supports naming the output file, the option
+       is just not called -o, so transform -o into the appropriate form
+       for MSVC. Also wrap some other options while at it (-L, -l, -Wl,
+       -Xlinker and -I) and convert paths to windows form where needed
+       for those options to make MSVC more usable in an autotooled
+       environment.
+       * doc/automake.texi (Auxiliary Programs): Document the above
+       extension of the compile script.
+       * NEWS: Updated.
+
 2010-06-13  Stefano Lattarini  <stefano.lattar...@gmail.com>
 
        Add useful comment in test script obsolete.test.
diff --git a/NEWS b/NEWS
index 13b28c0..fa26c88 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,9 @@ New in 1.11a:
 
   - automake now generates silenced rules for texinfo outputs.
 
+  - The `compile' script now converts some options for MSVC to make the
+    user experience better.
+
 * New targets:
 
   - New `cscope' target to build a cscope database for the source tree.
diff --git a/doc/automake.texi b/doc/automake.texi
index f5ccca1..c24a9eb 100644
--- a/doc/automake.texi
+++ b/doc/automake.texi
@@ -2169,7 +2169,11 @@ These two files are used for de-ANSI-fication support 
(obsolete
 @item compile
 This is a wrapper for compilers that do not accept options @option{-c}
 and @option{-o} at the same time.  It is only used when absolutely
-required.  Such compilers are rare.
+required.  Such compilers are rare, with the Microsoft C/C++ Compiler
+as the most notable exception. This wrapper also makes the following
+common options available for that compiler, while performing path
+translation where needed: @option{-I}, @option{-L}, @option{-l},
+...@option{-wl,} and @option{-Xlinker}.
 
 @item config.guess
 @itemx config.sub
diff --git a/lib/compile b/lib/compile
index c0096a7..1c79ce3 100755
--- a/lib/compile
+++ b/lib/compile
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Wrapper for compilers which do not understand `-c -o'.
 
-scriptversion=2009-10-06.20; # UTC
+scriptversion=2010-06-16.12; # UTC
 
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009  Free Software
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010  Free Software
 # Foundation, Inc.
 # Written by Tom Tromey <tro...@cygnus.com>.
 #
@@ -29,6 +29,120 @@ scriptversion=2009-10-06.20; # UTC
 # bugs to <bug-autom...@gnu.org> or send patches to
 # <automake-patc...@gnu.org>.
 
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""       $nl"
+
+path_conv=
+
+# func_path_conf build_path
+# Convert a $build path to $host form and store it in $path
+func_path_conv ()
+{
+  path=$1
+  case $path in
+    / | /[^/]*) # absolute path, and no UNC path
+      if test -z "$path_conv"; then
+       # lazily determine how to convert abs paths
+       case `uname -s` in
+         MINGW*)
+           path_conv=mingw
+           ;;
+         CYGWIN*)
+           path_conv=cygwin
+           ;;
+         *)
+           path_conv=wine
+           ;;
+       esac
+      fi
+      case $path_conv in
+       mingw)
+         path=`cmd //C echo "$path " | sed -e 's/"\(.*\) " *\$/\1/'`
+         ;;
+       cygwin)
+         path=`cygpath -w "$path" || echo "$path"`
+         ;;
+       wine)
+         path=`winepath -w "$path" || echo "$path"`
+         ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suite cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+       -o)
+         # configure might choose to run compile as `compile cc -o foo foo.c'.
+         eat=1
+         case $2 in
+           *.o | *.[oO][bB][jJ])
+             func_path_conv "$2"
+             set x "$@" -Fo"$path"
+             shift
+             ;;
+           *)
+             func_path_conv "$2"
+             set x "$@" -Fe"$path"
+             shift
+             ;;
+         esac
+         ;;
+       -I*)
+         func_path_conv "${1#-I}"
+         set x "$@" -I"$path"
+         shift
+         ;;
+       -l*)
+         set x "$@" "${1#-l}.lib"
+         shift
+         ;;
+       -L*)
+         func_path_conv "${1#-L}"
+         linker_opts="$linker_opts -LIBPATH:$path"
+         ;;
+       -Wl,*)
+         arg=${1#-Wl,}
+         save_ifs="$IFS"; IFS=','
+         for flag in $arg; do
+           IFS="$save_ifs"
+           linker_opts="$linker_opts $flag"
+         done
+         IFS="$save_ifs"
+         ;;
+       -Xlinker)
+         eat=1
+         linker_opts="$linker_opts $2"
+         ;;
+       *)
+         set x "$@" "$1"
+         shift
+         ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
 case $1 in
   '')
      echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
@@ -53,6 +167,9 @@ EOF
     echo "compile $scriptversion"
     exit $?
     ;;
+  cl | *[/\\]cl)
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
 esac
 
 ofile=
_______________________________________________
http://lists.gnu.org/mailman/listinfo/libtool

Reply via email to