[Top][All Lists]

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

[PATCH 2/3] AM_PROG_CC_C_O: don't rely on AC_PROG_CC_C_O, re-implement s

From: Stefano Lattarini
Subject: [PATCH 2/3] AM_PROG_CC_C_O: don't rely on AC_PROG_CC_C_O, re-implement similar logic
Date: Fri, 24 May 2013 20:21:03 +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/', we could see
    warnings like these (here slightly tweaked for legibility): 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... 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

  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

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

* 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
* t/ 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/ Likewise.
* t/ Move AC_PROG_CC invocation after AM_PROG_AR invocation.
* t/ Likewise.
* t/ Move AC_PROG_CC invocation after LT_INIT and
AM_PROG_AR invocations.  Make autoconf and autoheader warnings fatal.
* t/ Adjust to the new semantics, enhance a  little,
and reduce code duplication.
* t/ Make autoconf warnings fatal.
* t/ Likewise.
* t/ Likewise, and fix a comment.
* t/ Enhance a couple of error messages.
* Drop "nullification" of AM_PROG_CC_C_O.
* NEWS: Adjust.

Signed-off-by: Stefano Lattarini <address@hidden>
 NEWS                         | 29 +++++++++++++-------                 |  5 ----
 m4/ar-lib.m4                 |  1 -
 m4/init.m4                   |  6 ++--
 m4/minuso.m4                 | 51 +++++++++++++++++++++-------------
 t/            |  2 +-
 t/                  |  2 +-
 t/          | 65 ++++++++++++++++++++++++++++++++------------
 t/              |  4 +--
 t/                  |  2 +-
 t/                 |  2 +-
 t/               |  4 +--
 t/           |  6 ++--
 t/ |  2 +-
 t/                  |  2 +-
 15 files changed, 116 insertions(+), 67 deletions(-)

diff --git a/NEWS b/NEWS
index 16790b2..79cdb23 100644
--- 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:
diff --git a/ b/
index 74b7c1c..1a0620f 100644
--- a/
+++ b/
@@ -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
diff --git a/m4/ar-lib.m4 b/m4/ar-lib.m4
index 53c8c2a..58726d0 100644
--- a/m4/ar-lib.m4
+++ b/m4/ar-lib.m4
@@ -13,7 +13,6 @@
 [AC_BEFORE([$0], [LT_INIT])dnl
 AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
diff --git a/m4/init.m4 b/m4/init.m4
index fb6ed58..432ff20 100644
--- a/m4/init.m4
+++ b/m4/init.m4
@@ -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.
diff --git a/m4/minuso.m4 b/m4/minuso.m4
index 3e68f2b..3b2a849 100644
--- a/m4/minuso.m4
+++ b/m4/minuso.m4
@@ -5,20 +5,35 @@
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
-# --------------
-# Like AC_PROG_CC_C_O, but changed for automake.
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
-# 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
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  # 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"
-dnl Make sure AC_PROG_CC is never called again, or it will override our
-dnl setting of CC.
-          [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+# For backward compatibility.
diff --git a/t/ b/t/
index 5fb6177..630282e 100644
--- a/t/
+++ b/t/
@@ -22,9 +22,9 @@ required=cc
 cat >> <<EOF
diff --git a/t/ b/t/
index ef6398f..7829dbf 100644
--- a/t/
+++ b/t/
@@ -19,8 +19,8 @@
 cat >> <<'END'
 cat > << 'END'
diff --git a/t/ b/t/
index 920a0dc..08522a4 100644
--- a/t/
+++ b/t/
@@ -29,25 +29,28 @@ echo 'int main (void) { return 0; }' > foo.c
 cp configure.bak
-cat >> << 'END'
-# Since AM_PROG_CC_C_O rewrites $CC, it's an error to call AC_PROG_CC
-# after it.
+cat > acinclude.m4 <<'END'
+# 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]);;
-$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 - > << 'END'
 dnl It's OK to call AM_PROG_CC_C_O after AC_PROG_CC.
-# Make sure that $CC can be used after AM_PROG_CC_C_O.
-$CC --version || exit 1
-$CC -v || exit 1
@@ -61,21 +64,49 @@ if test "$AM_TESTSUITE_SIMULATING_NO_CC_C_O" != no; then
   $EGREP 'understands? -c and -o together.* yes$' stdout
 # No repeated checks please.
 test $(grep -c ".*-c['\" ].*-o['\" ]" stdout) -eq 1
 $MAKE maintainer-clean
+rm -rf autom4te*.cache
+# ---
+cat configure.bak - > << 'END'
+dnl It's also OK to call AM_PROG_CC_C_O *before* AC_PROG_CC.
+$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
+  $EGREP 'understands? -c and -o together.* yes$' stdout
+# Repeated checks are OK in this case, but should be cached.
+test $(grep ".*-c['\" ].*-o['\" ]" stdout \
+        | $FGREP -v ' (cached) ' | wc -l) -eq 1
+$MAKE maintainer-clean
 rm -rf autom4te*.cache
+# ---
 cat configure.bak - > << 'END'
 dnl It's also OK to call AM_PROG_CC_C_O *without* AC_PROG_CC.
-# Make sure that $CC can be used after AM_PROG_CC_C_O.
-$CC --version || exit 1
-$CC -v || exit 1
diff --git a/t/ b/t/
index 0e6a375..a6464ec 100755
--- a/t/
+++ b/t/
@@ -44,11 +44,11 @@ int wish_granted (void)
-# 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
+$AUTOCONF -Wall -Werror
 $AUTOMAKE --copy --add-missing
 for vpath in : false; do
diff --git a/t/ b/t/
index f9ee218..d00b6f9 100644
--- a/t/
+++ b/t/
@@ -47,7 +47,7 @@ END
 CC=$am_testaux_builddir/cc-no-c-o; export CC
+$AUTOCONF -Wall -Werror
 $AUTOMAKE --copy --add-missing
 for vpath in : false; do
diff --git a/t/ b/t/
index da5d7e6..e01a60a 100644
--- a/t/
+++ b/t/
@@ -22,8 +22,8 @@
 cat >> << 'END'
 cat > << 'END'
diff --git a/t/ b/t/
index 98b523b..85be517 100644
--- a/t/
+++ b/t/
@@ -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'
diff --git a/t/ b/t/
index 3eb366d..07764cd 100644
--- a/t/
+++ b/t/
@@ -31,14 +31,14 @@ AC_CONFIG_MACRO_DIR([m4])
 AC_LANG_PUSH([Objective C])
   [whether the Objective C compiler really works],
diff --git a/t/ b/t/
index 897f966..053ce41 100644
--- a/t/
+++ b/t/
@@ -25,9 +25,9 @@ required='cc libtoolize'
 cat >> << 'END'
diff --git a/t/ b/t/
index f9cdc74..2b3d163 100644
--- a/t/
+++ b/t/
@@ -91,7 +91,7 @@ int lib (void)
+$AUTOCONF -Werror -Wall
 $AUTOMAKE -Wno-override
 cd lib

reply via email to

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