AM_PROG_CC_C_O: don't rely on AC_PROG_CC_C_O, re-implement similar logic
authorStefano Lattarini <stefano.lattarini@gmail.com>
Wed, 15 May 2013 08:14:46 +0000 (10:14 +0200)
committerStefano Lattarini <stefano.lattarini@gmail.com>
Fri, 24 May 2013 15:35:30 +0000 (17:35 +0200)
** Theoretical problems of AC_PROG_CC_C_O:

  Both cc and $CC are checked to see if they support the '-c' and '-o'
  options together.
  This behaviour is highly inconsistent with that of the other macros
  related to C compiler checks -- which test only $CC.
  It can also cause unwarranted uses of the 'compile' script on systems
  where the default 'cc' is inferior, but the user is compiling with a
  proper, different compiler (e.g., gcc).

** Practical problems with our previous implementation of C support m4
   macros in Automake:

  - AM_PROG_AR must now be called *before* AC_PROG_CC; this wasn't the
    case before, and it turns out there are packages in the wild that
    relied on the old behaviour.

  - The cross-referenced requirements and macro rewrites juggled among
    AC_PROG_CC, AC_PROG_CC_C_O and AM_PROG_CC_C_O caused warnings in
    autoconf; for example, in our test 't/libobj3.sh', we could see
    warnings like these (here slightly tweaked for legibility):

        configure.ac:5: AC_REQUIRE: `AC_PROG_CC' expanded before required
        autoconf/c.m4:567: AC_PROG_CC_C_O is expanded from...
        autoconf/c.m4:429: AC_LANG_COMPILER(C) is expanded from...
        autoconf/lang.m4:329: AC_LANG_COMPILER_REQUIRE is expanded from...
        autoconf/general.m4:2606: AC_COMPILE_IFELSE is expanded from...
        m4sugar/m4sh.m4:639: AS_IF is expanded from...
        autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
        autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
        aclocal.m4:70: AM_PROG_AR is expanded from...
        configure.ac:5: the top level

** Fix all of that:

We fix all of the described issues with a new internal m4 macro
_AM_PROG_CC_C_O (inspired to, but not based on, AC_PROG_CC_C_O) that
gets tacked on to AC_PROG_CC automatically (this is done in the
Automake-generated aclocal.m4) and that takes care of checking and
adjusting '$CC' for "-c -o" support.

The macro AM_PROG_CC_C_O is still present, but is now just a thin
wrapper around such Automake-enhanced AC_PROG_CC.

It is worth noting that the present patch causes three slight
*backward-incompatibilities*:

  1. The name cache variable used by AM_PROG_CC_C_O is no longer
     computed (at configure runtime!) from the content of '$CC',
     but is statically defined as 'am_cv_prog_cc_c_o'.

  2. 'cc' is no longer checked by AM_PROG_CC_C_O, only '$CC' is.

  3. AM_PROG_CC_C_O no longer AC_DEFINE the C preprocessor symbol
     'NO_MINUS_C_MINUS_O'.

Given however that the third change can easily be worked around, that
the first two changes can be legitimately seen as bug fixes, and that
the new semantics introduced by such changes will simplify the transition
to Automake 2.0 (when the 'subdir-objects' will always be enabled
unconditionally), we believe they are acceptable to be shipped with
Automake 1.14.

With this patch, we also revert some of the testsuite adjustments done
in previous commit v1.13.2-178-g9877109 of 2013-05-24 (compile: rewrite
AC_PROG_CC with AM_PROG_CC_C_O contents).  Such adjustments are no longer
needed.

* m4/minuso.m4 (_AM_PROG_CC_C_O): New internal macro, basically and
adjusted version of a merge between Autoconf-provided AC_PROG_CC_C_O
and our old implementation of AM_PROG_CC_C_O.
(AM_PROG_CC_C_O): Redefine as a simple wrapper around AC_PROG_CC.
* m4/init.m4 (AC_PROG_CC): Append _AM_PROG_CC_C_O, not AM_PROG_CC_C_O,
to the pre-existing expansion of this macro.
* m4/ar-lib.m4 (AM_PROG_AR): No longer require it to be expanded after
AC_PROG_CC.
* t/aclocal-deps.sh: Move AC_PROG_CC invocation after AC_PROG_RANLIB
and AM_PROG_AR invocations.  Things should work this way too (as they
used to).
* t/subobj-clean-lt-pr10697.sh: Likewise.
* t/alloca.sh: Move AC_PROG_CC invocation after AM_PROG_AR invocation.
* t/condlib.sh: Likewise.
* t/aclocal-deps.sh: Move AC_PROG_CC invocation after LT_INIT and
AM_PROG_AR invocations.  Make autoconf and autoheader warnings fatal.
* t/am-prog-cc-c-o.sh: Adjust to the new semantics, enhance a  little,
and reduce code duplication.
* t/ccnoco.sh: Make autoconf warnings fatal.
* t/subpkg.sh: Likewise.
* t/ccnoco-lib.sh: Likewise, and fix a comment.
* t/link_cond.sh: Enhance a couple of error messages.
* configure.ac: Drop "nullification" of AM_PROG_CC_C_O.
* NEWS: Adjust.

Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
15 files changed:
NEWS
configure.ac
m4/ar-lib.m4
m4/init.m4
m4/minuso.m4
t/aclocal-deps.sh
t/alloca.sh
t/am-prog-cc-c-o.sh
t/ccnoco-lib.sh
t/ccnoco.sh
t/condlib.sh
t/link_cond.sh
t/objc-megademo.sh
t/subobj-clean-lt-pr10697.sh
t/subpkg.sh

diff --git a/NEWS b/NEWS
index 16790b26fdb0c3c77bf88e33fd6c98c7bc2e8e09..79cdb23f47828850e433ef31fddd329cda23f0b4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -107,16 +107,25 @@ New in 1.14:
 
   - Automake will automatically enhance the AC_PROG_CC autoconf macro
     to make it check, at configure time, that the C compiler supports
-    the combined use of both the "-c -o" options.  This "rewrite" of
-    AC_PROG_CC is only meant to be temporary, since future Autoconf
-    versions should provide all the features Automake needs.
-
-  - The AM_PROG_CC_C_O is no longer useful, and its use is a no-op
-    now.  Future Automake versions might start warning that this
-    macro is obsolete.  For better backward-compatibility, this macro
-    still sets a proper 'ac_cv_prog_cc_*_c_o' cache variable, and
-    define the 'NO_MINUS_C_MINUS_O' C preprocessor symbol, but you
-    should really stop relying on that.
+    the combined use of both the "-c -o" options.  The result of this
+    check is saved in the cache variable 'am_cv_prog_cc_c_o', and said
+    result can be overridden by pre-defining that variable.
+
+  - The AM_PROG_CC_C_O can still be called, but that should no longer
+    be necessary. This macro is now just a thin wrapper around the
+    Automake-enhanced AC_PROG_CC.  This means, among the other things,
+    that its behaviour is changed in three ways:
+
+      1. It no longer invokes the Autoconf-provided AC_PROG_CC_C_O
+         macros behind the scenes.
+
+      2. It caches the check result in the 'am_cv_prog_cc_c_o'variable,
+         and not in a 'ac_cv_prog_cc_*_c_o' variable whose exact name
+         in only dynamically computed at configure runtime (sic!) from
+         the content of the '$CC' variable.
+
+      3. It no longer automatically AC_DEFINE the C preprocessor
+         symbol 'NO_MINUS_C_MINUS_O'.
 
 * Texinfo support:
 
index 74b7c1cedc5b95b7cd317fbe9ee67e261c71083f..1a0620ff06ea87a69bae8bcedb0eaba2546b486c 100644 (file)
@@ -387,11 +387,6 @@ AC_ARG_VAR([AM_TEST_RUNNER_SHELL],
 
 # Look for C, C++ and fortran compilers to be used in the testsuite.
 
-dnl We don't care whether the C Compiler supports "-c -o" together
-dnl or not.  OTOH, we don't want $CC to be rewritten, so we must
-dnl redefine AM_PROG_CC_C_O to be a no-op.
-m4_define([AM_PROG_CC_C_O], [])
-
 dnl We don't want to abort our configuration script if no C compiler is
 dnl available, as such a compiler is only required to run part of the
 dnl testsuite, not to build or install Automake.  Ditto for C++, Fortran
index 53c8c2a7ef159df0c09b488997076cedf2e7e129..58726d0b02d0614e71353ff231000fbfd6d5eda3 100644 (file)
@@ -13,7 +13,6 @@
 AC_DEFUN([AM_PROG_AR],
 [AC_BEFORE([$0], [LT_INIT])dnl
 AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
-AC_BEFORE([AC_PROG_CC])
 AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 AC_REQUIRE_AUX_FILE([ar-lib])dnl
 AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
index fb6ed5851a6e19866afa5db0792b69e51905a65f..432ff200c9861590c5f0d8506cc63572ab248773 100644 (file)
@@ -9,8 +9,10 @@
 # This macro actually does too much.  Some checks are only needed if
 # your package does certain things.  But this isn't really a big deal.
 
-dnl Redefine AC_PROG_CC to automatically invoke AM_PROG_CC_C_O.
-m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[AM_PROG_CC_C_O
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
 ])
 
 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
index 3e68f2b7282c058c162f8acf50cefad828105987..3b2a849b074a1283feae52af077f18fa63c31042 100644 (file)
@@ -5,20 +5,35 @@
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# AM_PROG_CC_C_O
-# --------------
-# Like AC_PROG_CC_C_O, but changed for automake.
-AC_DEFUN_ONCE([AM_PROG_CC_C_O],
-[AC_LANG_PUSH([C])
-AC_REQUIRE([AC_PROG_CC_C_O])dnl
-AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 AC_REQUIRE_AUX_FILE([compile])dnl
-# FIXME: we rely on the cache variable name because
-# there is no other way.
-set dummy $CC
-am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
-eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
-if test "$am_t" != yes; then
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
    # Losing compiler, so override with the script.
    # FIXME: It is wrong to rewrite CC.
    # But if we don't then we get into trouble of one sort or another.
@@ -26,9 +41,7 @@ if test "$am_t" != yes; then
    # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
    CC="$am_aux_dir/compile $CC"
 fi
-AC_LANG_POP([C])
-dnl Make sure AC_PROG_CC is never called again, or it will override our
-dnl setting of CC.
-m4_define([AC_PROG_CC],
-          [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
-])
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
index 5fb6177be66eb793be8c8d3512ecf56fb3ed59f3..630282e0b95835b271d76d85e4358569dffb020f 100644 (file)
@@ -22,9 +22,9 @@ required=cc
 
 cat >>configure.ac <<EOF
 AC_CONFIG_MACRO_DIR([m4])
-AC_PROG_CC
 AC_PROG_RANLIB
 AM_PROG_AR
+AC_PROG_CC
 MY_MACRO
 AC_CONFIG_FILES([lib/Makefile])
 AC_OUTPUT
index ef6398fd4b152328c89d5f70da3fde3a2f34e8a7..7829dbf8666534221e8afbb2768d760e7d499090 100644 (file)
@@ -19,8 +19,8 @@
 . test-init.sh
 
 cat >> configure.ac <<'END'
-AC_PROG_CC
 AM_PROG_AR
+AC_PROG_CC
 END
 
 cat > Makefile.am << 'END'
index 920a0dc93a21b5f40a27749722410c6d70babaa2..08522a47225defafe8b7b73dd8666079d5ca02da 100644 (file)
@@ -29,25 +29,28 @@ echo 'int main (void) { return 0; }' > foo.c
 
 cp configure.ac configure.bak
 
-cat >> configure.ac << 'END'
-# Since AM_PROG_CC_C_O rewrites $CC, it's an error to call AC_PROG_CC
-# after it.
-AM_PROG_CC_C_O
-AC_PROG_CC
+cat > acinclude.m4 <<'END'
+AC_DEFUN([AM_TWEAKED_OUTPUT], [
+# For debugging.
+printf "CC = '%s'\\n" "$CC"
+# Make sure that $CC can be used after AM_PROG_CC_C_O.
+$CC --version || exit 1
+$CC -v || exit 1
+# $CC rewrite should only take place on time.
+case " $CC " in
+  *" compile"*" compile"*) AC_MSG_ERROR([CC rewritten twice]);;
+esac
+AC_OUTPUT
+])
 END
 
-$ACLOCAL -Wnone 2>stderr && { cat stderr >&2; exit 1; }
-cat stderr >&2
-grep '^configure\.ac:7:.* AC_PROG_CC .*called after AM_PROG_CC_C_O' stderr
+# ---
 
 cat configure.bak - > configure.ac << 'END'
 dnl It's OK to call AM_PROG_CC_C_O after AC_PROG_CC.
 AC_PROG_CC
 AM_PROG_CC_C_O
-# Make sure that $CC can be used after AM_PROG_CC_C_O.
-$CC --version || exit 1
-$CC -v || exit 1
-AC_OUTPUT
+AM_TWEAKED_OUTPUT
 END
 
 $ACLOCAL
@@ -61,21 +64,49 @@ if test "$AM_TESTSUITE_SIMULATING_NO_CC_C_O" != no; then
 else
   $EGREP 'understands? -c and -o together.* yes$' stdout
 fi
+
 # No repeated checks please.
 test $(grep -c ".*-c['\" ].*-o['\" ]" stdout) -eq 1
-$MAKE
 
+$MAKE
 $MAKE maintainer-clean
+rm -rf autom4te*.cache
+
+# ---
+
+cat configure.bak - > configure.ac << 'END'
+dnl It's also OK to call AM_PROG_CC_C_O *before* AC_PROG_CC.
+AM_PROG_CC_C_O
+AC_PROG_CC
+AM_TWEAKED_OUTPUT
+END
 
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE --add-missing
+
+./configure >stdout || { cat stdout; exit 1; }
+cat stdout
+if test "$AM_TESTSUITE_SIMULATING_NO_CC_C_O" != no; then
+  $EGREP 'understands? -c and -o together.* no$' stdout
+else
+  $EGREP 'understands? -c and -o together.* yes$' stdout
+fi
+
+# Repeated checks are OK in this case, but should be cached.
+test $(grep ".*-c['\" ].*-o['\" ]" stdout \
+        | $FGREP -v ' (cached) ' | wc -l) -eq 1
+
+$MAKE
+$MAKE maintainer-clean
 rm -rf autom4te*.cache
 
+# ---
+
 cat configure.bak - > configure.ac << 'END'
 dnl It's also OK to call AM_PROG_CC_C_O *without* AC_PROG_CC.
 AM_PROG_CC_C_O
-# Make sure that $CC can be used after AM_PROG_CC_C_O.
-$CC --version || exit 1
-$CC -v || exit 1
-AC_OUTPUT
+AM_TWEAKED_OUTPUT
 END
 
 $ACLOCAL
index 0e6a3751024df18178f479e4c33662507b3f5b8a..a6464ec98e715a89ea22b029767e3da236bc4b21 100755 (executable)
@@ -44,11 +44,11 @@ int wish_granted (void)
 }
 END
 
-# Make sure the compiler doesn't understand '-c -o'
+# Make sure the compiler doesn't understand '-c -o'.
 CC=$am_testaux_builddir/cc-no-c-o; export CC
 
 $ACLOCAL
-$AUTOCONF
+$AUTOCONF -Wall -Werror
 $AUTOMAKE --copy --add-missing
 
 for vpath in : false; do
index f9ee2183558dcda88c510bb4d80711e1499413f1..d00b6f93d7dd48bd31e5bd699f09137faaaf1ebb 100644 (file)
@@ -47,7 +47,7 @@ END
 CC=$am_testaux_builddir/cc-no-c-o; export CC
 
 $ACLOCAL
-$AUTOCONF
+$AUTOCONF -Wall -Werror
 $AUTOMAKE --copy --add-missing
 
 for vpath in : false; do
index da5d7e66246de4db99e5067005c6df27c9f8b824..e01a60a41ebe5a96d9be19be8040d201a3a2100c 100644 (file)
@@ -22,8 +22,8 @@
 cat >> configure.ac << 'END'
 AC_PROG_RANLIB
 AM_MAINTAINER_MODE
-AC_PROG_CC
 AM_PROG_AR
+AC_PROG_CC
 END
 
 cat > Makefile.am << 'END'
index 98b523bc34b4f7b2e23e221a776355b010822f60..85be517b2c0c35a3ff9ab59cafc2bedb9148672a 100644 (file)
@@ -64,7 +64,7 @@ run_make CXX=false
 
 # Sanity check.
 rm -f foo foo.exe
-run_make CC=false && exit 99
+run_make CC=false && fatal_ '"make CC=false" succeeded unexpectedly'
 
 $MAKE distclean
 
@@ -83,6 +83,6 @@ run_make CC=false
 
 # Sanity check.
 rm -f foo foo.exe
-run_make CXX=false && exit 99
+run_make CXX=false && fatal_ '"make CXX=false" succeeded unexpectedly'
 
 :
index 3eb366d9d2b9cf8164c202aa514570ccfca3399b..07764cd0ab2cb9de7ac03ae61da147f619008221 100644 (file)
@@ -31,14 +31,14 @@ AC_CONFIG_MACRO_DIR([m4])
 
 AM_INIT_AUTOMAKE
 
+AM_PROG_AR
+LT_INIT
+
 AC_PROG_CC
 AC_PROG_CXX
 AC_PROG_OBJC
 AC_PROG_OBJCXX
 
-AM_PROG_AR
-LT_INIT
-
 AC_LANG_PUSH([Objective C])
 AC_CACHE_CHECK(
   [whether the Objective C compiler really works],
index 897f966d914270ccfef2359518078fe6438f7070..053ce417797b9bb3819b3ff1364554690981d4fc 100644 (file)
@@ -25,9 +25,9 @@ required='cc libtoolize'
 . test-init.sh
 
 cat >> configure.ac << 'END'
-AC_PROG_CC
 AM_PROG_AR
 AC_PROG_LIBTOOL
+AC_PROG_CC
 AC_OUTPUT
 END
 
index f9cdc74e2bb58bf0de2522d9188be29f3bbc2dea..2b3d163a06431adf7001fded8d3b9cfb04e4581d 100644 (file)
@@ -91,7 +91,7 @@ int lib (void)
 EOF
 
 $ACLOCAL
-$AUTOCONF
+$AUTOCONF -Werror -Wall
 $AUTOMAKE -Wno-override
 
 cd lib