Wrap some MSVC options in the compile script.
authorPeter Rosin <peda@lysator.liu.se>
Sun, 1 Aug 2010 06:38:05 +0000 (08:38 +0200)
committerRalf Wildenhues <Ralf.Wildenhues@gmx.de>
Sun, 1 Aug 2010 06:58:43 +0000 (08:58 +0200)
* 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 file names 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.
* tests/defs.in: New required entry 'cl'.
* tests/compile3.test: New test.
* tests/compile4.test: New test.
* tests/compile5.test: New test.
* tests/Makefile.am: Update.

Signed-off-by: Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
ChangeLog
NEWS
doc/automake.texi
lib/compile
tests/Makefile.am
tests/Makefile.in
tests/compile3.test [new file with mode: 0755]
tests/compile4.test [new file with mode: 0755]
tests/compile5.test [new file with mode: 0755]
tests/defs.in

index 4f96039..20adef2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2010-08-01  Peter Rosin  <peda@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 file names 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.
+       * tests/defs.in: New required entry 'cl'.
+       * tests/compile3.test: New test.
+       * tests/compile4.test: New test.
+       * tests/compile5.test: New test.
+       * tests/Makefile.am: Update.
+
 2010-07-31  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        Add example git work flow; discuss merge --log in HACKING.
diff --git a/NEWS b/NEWS
index b3d4131..54fac91 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,9 @@ New in 1.11.0a:
   - The `lzma' compression scheme and associated automake option `dist-lzma'
     is obsoleted by `xz' and `dist-xz' due to upstream changes.
 
+  - The `compile' script now converts some options for MSVC for a better
+    user experience.
+
 Bugs fixed in 1.11.0a:
 
 * Bugs introduced by 1.11:
index 7484a76..00e24eb 100644 (file)
@@ -2171,7 +2171,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 file name
+translation where needed: @option{-I}, @option{-L}, @option{-l},
+@option{-Wl,} and @option{-Xlinker}.
 
 @item config.guess
 @itemx config.sub
index c0096a7..ae47d8b 100755 (executable)
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Wrapper for compilers which do not understand `-c -o'.
 
-scriptversion=2009-10-06.20; # UTC
+scriptversion=2010-08-01.07; # 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 <tromey@cygnus.com>.
 #
@@ -29,6 +29,121 @@ scriptversion=2009-10-06.20; # UTC
 # bugs to <bug-automake@gnu.org> or send patches to
 # <automake-patches@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"
+
+file_conv=
+
+# func_file_conv build_file
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Win32 hosts.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[^/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+       # lazily determine how to convert abs files
+       case `uname -s` in
+         MINGW*)
+           file_conv=mingw
+           ;;
+         CYGWIN*)
+           file_conv=cygwin
+           ;;
+         *)
+           file_conv=wine
+           ;;
+       esac
+      fi
+      case $file_conv in
+       mingw)
+         file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+         ;;
+       cygwin)
+         file=`cygpath -m "$file" || echo "$file"`
+         ;;
+       wine)
+         file=`winepath -w "$file" || echo "$file"`
+         ;;
+      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_file_conv "$2"
+             set x "$@" -Fo"$file"
+             shift
+             ;;
+           *)
+             func_file_conv "$2"
+             set x "$@" -Fe"$file"
+             shift
+             ;;
+         esac
+         ;;
+       -I*)
+         func_file_conv "${1#-I}"
+         set x "$@" -I"$file"
+         shift
+         ;;
+       -l*)
+         set x "$@" "${1#-l}.lib"
+         shift
+         ;;
+       -L*)
+         func_file_conv "${1#-L}"
+         linker_opts="$linker_opts -LIBPATH:$file"
+         ;;
+       -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 +168,9 @@ EOF
     echo "compile $scriptversion"
     exit $?
     ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
 esac
 
 ofile=
index 4fc4d15..bfc5270 100644 (file)
@@ -158,6 +158,9 @@ commen10.test \
 commen11.test \
 compile.test \
 compile2.test \
+compile3.test \
+compile4.test \
+compile5.test \
 compile_f90_c_cxx.test \
 compile_f_c_cxx.test \
 cond.test \
index b2e63ae..3a34745 100644 (file)
@@ -396,6 +396,9 @@ commen10.test \
 commen11.test \
 compile.test \
 compile2.test \
+compile3.test \
+compile4.test \
+compile5.test \
 compile_f90_c_cxx.test \
 compile_f_c_cxx.test \
 cond.test \
diff --git a/tests/compile3.test b/tests/compile3.test
new file mode 100755 (executable)
index 0000000..fc5cd8e
--- /dev/null
@@ -0,0 +1,45 @@
+#! /bin/sh
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# This program 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, or (at your option)
+# any later version.
+#
+# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Make sure `compile' wraps the Microsoft C/C++ compiler (cl) correctly
+
+. ./defs || Exit 1
+
+set -e
+
+cp "$testsrcdir/../lib/compile" .
+
+# Use a dummy cl, since cl isn't readily available on all systems
+cat >cl <<'END'
+#! /bin/sh
+echo "$@"
+END
+
+chmod +x ./cl
+
+# Check if compile handles "-o foo", -I, -l, -L, -Xlinker -Wl,
+opts=`./compile ./cl foo.c -o foo -lbar -Lgazonk -Ibaz -Xlinker foobar -Wl,-foo,bar`
+test x"$opts" = x"foo.c -Fefoo bar.lib -Ibaz -link -LIBPATH:gazonk foobar -foo bar"
+
+# Check if compile handles "-o foo.obj"
+opts=`./compile ./cl -c foo.c -o foo.obj -Ibaz`
+test x"$opts" = x"-c foo.c -Fofoo.obj -Ibaz"
+
+# Check if compile handles "-o foo.o"
+opts=`./compile ./cl -c foo.c -o foo.o -Ibaz`
+test x"$opts" = x"-c foo.c -Fofoo.o -Ibaz"
+
+:
diff --git a/tests/compile4.test b/tests/compile4.test
new file mode 100755 (executable)
index 0000000..9e7bcbb
--- /dev/null
@@ -0,0 +1,82 @@
+#! /bin/sh
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# This program 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, or (at your option)
+# any later version.
+#
+# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Make sure `compile' wraps the Microsoft C/C++ compiler (cl) correctly
+# with respect to absolute paths.
+
+required='cl'
+. ./defs || Exit 1
+
+set -e
+
+mkdir sub
+
+cat >sub/foo.c <<'EOF'
+int
+foo ()
+{
+  return 0;
+}
+EOF
+
+cat >main.c <<'EOF'
+extern int foo ();
+int
+main ()
+{
+  return foo ();
+}
+EOF
+
+absfoodir=`pwd`/sub
+absmain=`pwd`/main.c
+
+cat >> configure.in << 'END'
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_RANLIB
+AC_CONFIG_FILES([sub/Makefile])
+AC_OUTPUT
+END
+
+cat > Makefile.am << 'END'
+SUBDIRS = sub
+END
+
+cat > sub/Makefile.am << 'END'
+lib_LIBRARIES = libfoo.a
+libfoo_a_SOURCES = foo.c
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
+./configure
+$MAKE
+
+# cl expects archives to be named foo.lib, not libfoo.a so
+# make a simple copy here if needed. This is a severe case
+# of badness, but ignore that since this is not what is
+# being tested here...
+if test -f sub/libfoo.a; then
+  cp sub/libfoo.a sub/foo.lib
+fi
+
+./compile cl $CPPFLAGS $CFLAGS $LDFLAGS -L"$absfoodir" "$absmain" -o main -lfoo
+
+./main
+
+:
diff --git a/tests/compile5.test b/tests/compile5.test
new file mode 100755 (executable)
index 0000000..cd1468f
--- /dev/null
@@ -0,0 +1,81 @@
+#! /bin/sh
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# This program 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, or (at your option)
+# any later version.
+#
+# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Make sure the file name translation in the `compile' script works
+# correctly
+
+. ./defs || Exit 1
+
+set -e
+
+cp "$testsrcdir/../lib/compile" .
+
+# Use a dummy cl, since cl isn't readily available on all systems
+cat >cl <<'END'
+#! /bin/sh
+echo "$@"
+END
+
+chmod +x ./cl
+
+cat >>configure.in << 'END'
+AC_CANONICAL_HOST
+AC_CONFIG_FILES([check_host], [chmod +x check_host])
+AC_OUTPUT
+END
+
+: >Makefile.am
+
+cat >check_host.in << 'END'
+#! /bin/sh
+case @host_os@ in
+  mingw*)
+    ;;
+  *)
+    exit 77
+    ;;
+esac
+case @build_os@ in
+  mingw* | cygwin*)
+    ;;
+  *)
+    winepath -w / || exit 77
+    ;;
+esac
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
+./configure
+./check_host
+
+pwd=`pwd`
+
+# Check if "compile cl" transforms absolute file names to
+# host format (e.g /somewhere -> c:/msys/1.0/somewhere).
+
+res=`./compile ./cl -L"$pwd" | sed -e 's/-link -LIBPATH://'`
+
+case $res in
+  ?:[\\/]*)
+    ;;
+  *)
+    Exit 1
+    ;;
+esac
+
+:
index 1744a07..af4a3cd 100644 (file)
@@ -102,6 +102,12 @@ do
       echo "$me: running bzip2 --help"
       ( bzip2 --help ) || exit 77
       ;;
+    cl)
+      CC=cl
+      export CC
+      echo "$me: running $CC -?"
+      ( $CC -? ) || exit 77
+      ;;
     etags)
       # Exuberant Ctags will create a TAGS file even
       # when asked for --help or --version.  (Emacs's etags