summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2020-12-04 16:32:35 -0500
committerZack Weinberg <zackw@panix.com>2020-12-04 16:41:43 -0500
commitc38538737c6d221674b9bc746b6b1430f64d4aaa (patch)
treeca11e11215d9f37ded68a746ec18ef9a12dbcf4b
parent2a7a441b437d9a87271078877c2fc425137f9a3b (diff)
downloadautoconf-c38538737c6d221674b9bc746b6b1430f64d4aaa.tar.gz
Revert "AC_PROG_CC: define via AC_DEFUN_ONCE". (#110350)
Revert commit 18c140b50b0619454d4da50d58a318cc257d580a, restoring AC_PROG_CC to being defined as an ordinary AC_DEFUN. This broke third-party macros (e.g. the Autoconf Macro Archive’s AX_PROG_CC_FOR_BUILD) that intentionally invoked AC_PROG_CC a second time with its guts redefined via a whole bunch of ‘pushdef’s. I don’t think we want to support this long-term, but needing access to a build-native compiler in cross-compilation is common enough that we should have *some* supported way to do it, and it may as well be AX_PROG_CC_FOR_BUILD until we come up with something better. If we go back to AC_DEFUN_ONCE for AC_PROG_CC in the future, we should do it consistently for all the “find me a compiler” macros -- it was *only* done for AC_PROG_CC in 18c140b5. The rationale for AC_DEFUN_ONCE seems to have been to reduce the size of the generated configure script. The bulk of the size accountable to AC_PROG_CC is the test programs for figuring out which version of the C standard is available, so I tweaked _AC_C_STD_TRY (and _AC_CXX_STD_TRY) to emit that text only once per program, into shell variables which can then be referenced repeatedly. Fixes bug #110350. * NEWS, doc/autoconf.texi: Revert documentation changes associated with AC_PROG_CC being a one-shot macro. * lib/autoconf/c.m4 (AC_PROG_CC): Revert to defining with AC_DEFUN. (_AC_C_STD_TRY, _AC_CXX_STD_TRY): Emit the test program only once, even if invoked multiple times with the same arguments. * tests/foreign.at (AX_PROG_CC_FOR_BUILD, AX_PROG_CXX_FOR_BUILD): New tests.
-rw-r--r--NEWS5
-rw-r--r--doc/autoconf.texi7
-rw-r--r--lib/autoconf/c.m416
-rw-r--r--tests/foreign.at252
4 files changed, 269 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index d20b543a..dbbea222 100644
--- a/NEWS
+++ b/NEWS
@@ -429,11 +429,6 @@ GNU Autoconf NEWS - User visible changes.
default search paths. Alternatively, use configure’s --x-includes
and --x-libraries command line options to tell it where they are.
-*** AC_PROG_CC is now defined via AC_DEFUN_ONCE.
-
- This means configure scripts will no longer check repeatedly for the
- C compiler under some combinations of macro use.
-
*** AS_IF’s if-false argument may be empty after macro expansion.
This long-standing limitation broke configure scripts that used
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index afeca056..01af2b29 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -7495,8 +7495,11 @@ and before @code{AC_PROG_CC} to select an empty default instead.
Many Autoconf macros use a compiler, and thus call
@samp{AC_REQUIRE([AC_PROG_CC])} to ensure that the compiler has been
determined before the body of the outermost @code{AC_DEFUN} macro.
-@code{AC_PROG_CC} is therefore defined via @code{AC_DEFUN_ONCE} to avoid
-needless reexpansion (@pxref{One-Shot Macros}).
+Although @code{AC_PROG_CC} is safe to directly expand multiple times, it
+performs certain checks (such as the proper value of @env{EXEEXT}) only
+on the first invocation. Therefore, care must be used when invoking
+this macro from within another macro rather than at the top level
+(@pxref{Expanded Before Required}).
@end defmac
@anchor{AC_PROG_CC_C_O}
diff --git a/lib/autoconf/c.m4 b/lib/autoconf/c.m4
index af1e1a71..ba8f9aa6 100644
--- a/lib/autoconf/c.m4
+++ b/lib/autoconf/c.m4
@@ -449,7 +449,7 @@ AU_DEFUN([ac_cv_prog_gcc],
AN_MAKEVAR([CC], [AC_PROG_CC])
AN_PROGRAM([cc], [AC_PROG_CC])
AN_PROGRAM([gcc], [AC_PROG_CC])
-AC_DEFUN_ONCE([AC_PROG_CC],
+AC_DEFUN([AC_PROG_CC],
[AC_LANG_PUSH(C)dnl
AC_ARG_VAR([CC], [C compiler command])dnl
AC_ARG_VAR([CFLAGS], [C compiler flags])dnl
@@ -1191,11 +1191,16 @@ dnl SVR4 -Xc -D__EXTENSIONS__
# helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE,
# else ACTION-IF-UNAVAILABLE.
AC_DEFUN([_AC_C_STD_TRY],
+[m4_divert_once([INIT_PREPARE],
+[# Test code for whether the C compiler supports ]m4_translit($1, [c], [C])[.
+AS_VAR_SET([ac_c_conftest_$1],
+['m4_bpatsubsts(AC_LANG_PROGRAM([$2], [$3]), ['], ['\\''])'])
+])]dnl
[AC_MSG_CHECKING([for $CC option to enable ]m4_translit($1, [c], [C])[ features])
AC_CACHE_VAL(ac_cv_prog_cc_$1,
[ac_cv_prog_cc_$1=no
ac_save_CC=$CC
-AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
+AC_LANG_CONFTEST([AC_LANG_DEFINES_PROVIDED][$ac_c_conftest_$1])
for ac_arg in '' $4
do
CC="$ac_save_CC $ac_arg"
@@ -2256,12 +2261,17 @@ fi])
# If eventually successful, run ACTION-IF-AVAILABLE, else
# ACTION-IF-UNAVAILABLE.
AC_DEFUN([_AC_CXX_STD_TRY],
+[m4_divert_once([INIT_PREPARE],
+[# Test code for whether the C++ compiler supports ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[.
+AS_VAR_SET([ac_cxx_conftest_$1],
+['m4_bpatsubsts(AC_LANG_PROGRAM([$2], [$3]), ['], ['\\''])'])
+])]dnl
[AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features])
AC_LANG_PUSH(C++)dnl
AC_CACHE_VAL(ac_cv_prog_cxx_$1,
[ac_cv_prog_cxx_$1=no
ac_save_CXX=$CXX
-AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
+AC_LANG_CONFTEST([AC_LANG_DEFINES_PROVIDED][$ac_cxx_conftest_$1])
for ac_arg in '' $4
do
CXX="$ac_save_CXX $ac_arg"
diff --git a/tests/foreign.at b/tests/foreign.at
index 7a49333a..f3a53420 100644
--- a/tests/foreign.at
+++ b/tests/foreign.at
@@ -1,6 +1,6 @@
# -*- Autotest -*-
-AT_BANNER([Compatibility with other tools.])
+AT_BANNER([Compatibility with external tools and macros.])
# Copyright (C) 2000-2007, 2009-2017, 2020 Free Software Foundation,
# Inc.
@@ -141,3 +141,253 @@ AT_CHECK_MAKE([install])
AT_CHECK([test -f inst/file1 && test -f inst/file2 && test -x inst/file1])
AT_CLEANUP
+
+AT_SETUP([AX_PROG_CC_FOR_BUILD])
+
+cp "$abs_top_srcdir/build-aux/install-sh" \
+ "$abs_top_srcdir/build-aux/config.guess" \
+ "$abs_top_srcdir/build-aux/config.sub" .
+
+# The Autoconf Macro Archive's AX_PROG_CC_FOR_BUILD invokes AC_PROG_CC
+# twice, with a whole bunch of shell variables renamed at the m4 level
+# the second time. Git commit 18c140b50b0619454d4da50d58a318cc257d580a
+# broke this usage and the breakage went unnoticed for *eight years*.
+
+AT_DATA([aclocal.m4],
+[[# ax_prog_cc_for_build.m4
+# serial 18
+# Copyright (c) 2008 Paolo Bonzini <bonzini@gnu.org>
+
+AC_DEFUN([AX_PROG_CC_FOR_BUILD], [
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_PROG_CPP])
+AC_REQUIRE([AC_CANONICAL_BUILD])
+
+# Use the standard macros, but make them use other variable names
+m4@&t@_pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)
+m4@&t@_pushdef([ac_cv_prog_cc_c89], ac_cv_build_prog_cc_c89)
+m4@&t@_pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)
+m4@&t@_pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)
+m4@&t@_pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)
+m4@&t@_pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)
+m4@&t@_pushdef([ac_cv_c_compiler_gnu], ac_cv_build_c_compiler_gnu)
+m4@&t@_pushdef([ac_cv_exeext], ac_cv_build_exeext)
+m4@&t@_pushdef([ac_cv_objext], ac_cv_build_objext)
+m4@&t@_pushdef([ac_exeext], ac_build_exeext)
+m4@&t@_pushdef([ac_objext], ac_build_objext)
+m4@&t@_pushdef([CC], CC_FOR_BUILD)
+m4@&t@_pushdef([CPP], CPP_FOR_BUILD)
+m4@&t@_pushdef([GCC], GCC_FOR_BUILD)
+m4@&t@_pushdef([CFLAGS], CFLAGS_FOR_BUILD)
+m4@&t@_pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)
+m4@&t@_pushdef([EXEEXT], BUILD_EXEEXT)
+m4@&t@_pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)
+m4@&t@_pushdef([OBJEXT], BUILD_OBJEXT)
+m4@&t@_pushdef([host], build)
+m4@&t@_pushdef([host_alias], build_alias)
+m4@&t@_pushdef([host_cpu], build_cpu)
+m4@&t@_pushdef([host_vendor], build_vendor)
+m4@&t@_pushdef([host_os], build_os)
+m4@&t@_pushdef([ac_cv_host], ac_cv_build)
+m4@&t@_pushdef([ac_cv_host_alias], ac_cv_build_alias)
+m4@&t@_pushdef([ac_cv_host_cpu], ac_cv_build_cpu)
+m4@&t@_pushdef([ac_cv_host_vendor], ac_cv_build_vendor)
+m4@&t@_pushdef([ac_cv_host_os], ac_cv_build_os)
+m4@&t@_pushdef([ac_tool_prefix], ac_build_tool_prefix)
+m4@&t@_pushdef([am_cv_CC_dependencies_compiler_type], am_cv_build_CC_dependencies_compiler_type)
+m4@&t@_pushdef([am_cv_prog_cc_c_o], am_cv_build_prog_cc_c_o)
+m4@&t@_pushdef([cross_compiling], cross_compiling_build)
+
+cross_compiling_build=no
+
+ac_build_tool_prefix=
+AS@&t@_IF([test -n "$build"], [ac_build_tool_prefix="$build-"],
+ [test -n "$build_alias"],[ac_build_tool_prefix="$build_alias-"])
+
+AC_LANG_PUSH([C])
+AC_PROG_CC
+_AC_COMPILER_EXEEXT
+_AC_COMPILER_OBJEXT
+AC_PROG_CPP
+
+# Restore the old definitions
+m4@&t@_popdef([cross_compiling])
+m4@&t@_popdef([am_cv_prog_cc_c_o])
+m4@&t@_popdef([am_cv_CC_dependencies_compiler_type])
+m4@&t@_popdef([ac_tool_prefix])
+m4@&t@_popdef([ac_cv_host_os])
+m4@&t@_popdef([ac_cv_host_vendor])
+m4@&t@_popdef([ac_cv_host_cpu])
+m4@&t@_popdef([ac_cv_host_alias])
+m4@&t@_popdef([ac_cv_host])
+m4@&t@_popdef([host_os])
+m4@&t@_popdef([host_vendor])
+m4@&t@_popdef([host_cpu])
+m4@&t@_popdef([host_alias])
+m4@&t@_popdef([host])
+m4@&t@_popdef([OBJEXT])
+m4@&t@_popdef([LDFLAGS])
+m4@&t@_popdef([EXEEXT])
+m4@&t@_popdef([CPPFLAGS])
+m4@&t@_popdef([CFLAGS])
+m4@&t@_popdef([GCC])
+m4@&t@_popdef([CPP])
+m4@&t@_popdef([CC])
+m4@&t@_popdef([ac_objext])
+m4@&t@_popdef([ac_exeext])
+m4@&t@_popdef([ac_cv_objext])
+m4@&t@_popdef([ac_cv_exeext])
+m4@&t@_popdef([ac_cv_c_compiler_gnu])
+m4@&t@_popdef([ac_cv_prog_cc_g])
+m4@&t@_popdef([ac_cv_prog_cc_cross])
+m4@&t@_popdef([ac_cv_prog_cc_works])
+m4@&t@_popdef([ac_cv_prog_cc_c89])
+m4@&t@_popdef([ac_cv_prog_gcc])
+m4@&t@_popdef([ac_cv_prog_CPP])
+
+# restore global variables ac_ext, ac_cpp, ac_compile,
+# ac_link, ac_compiler_gnu (dependant on the current
+# language after popping):
+AC_LANG_POP([C])
+
+# Finally, set Makefile variables
+AC_SUBST(BUILD_EXEEXT)
+AC_SUBST(BUILD_OBJEXT)
+AC_SUBST([CFLAGS_FOR_BUILD])
+AC_SUBST([CPPFLAGS_FOR_BUILD])
+AC_SUBST([LDFLAGS_FOR_BUILD])
+])
+]])
+
+AT_DATA([configure.ac],
+[[AC_INIT([foo], [1.0])
+AX_PROG_CC_FOR_BUILD
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+]])
+
+AT_DATA([Makefile.in],
+[[CC = @CC@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+]])
+
+AT_CHECK_AUTOCONF
+AT_CHECK_CONFIGURE
+
+AT_CHECK([grep '^CC = ..*$' Makefile > /dev/null 2>&1])
+AT_CHECK([grep '^CC_FOR_BUILD = ..*$' Makefile > /dev/null 2>&1])
+
+AT_CLEANUP
+
+AT_SETUP([AX_PROG_CXX_FOR_BUILD])
+
+cp "$abs_top_srcdir/build-aux/install-sh" \
+ "$abs_top_srcdir/build-aux/config.guess" \
+ "$abs_top_srcdir/build-aux/config.sub" .
+
+# The Autoconf Macro Archive's AX_PROG_CXX_FOR_BUILD invokes AC_PROG_CXX
+# twice, with a whole bunch of shell variables renamed at the m4 level
+# the second time. This usage was never broken (unlike with AC_PROG_CC)
+# but it seems sensible to make sure it doesn't *get* broken.
+
+AT_DATA([aclocal.m4],
+[[# ax_prog_cxx_for_build.m4
+# serial 3
+# Copyright (c) 2008 Paolo Bonzini <bonzini@gnu.org>
+# Copyright (c) 2012 Avionic Design GmbH
+
+AC_DEFUN([AX_PROG_CXX_FOR_BUILD], [
+AC_LANG_PUSH([C++])
+
+AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+AC_REQUIRE([AC_CANONICAL_HOST])
+
+# Use the standard macros, but make them use other variable names
+m4@&t@_pushdef([ac_cv_prog_CXXCPP], ac_cv_build_prog_CXXCPP)
+m4@&t@_pushdef([ac_cv_prog_gxx], ac_cv_build_prog_gxx)
+m4@&t@_pushdef([ac_cv_prog_cxx_works], ac_cv_build_prog_cxx_works)
+m4@&t@_pushdef([ac_cv_prog_cxx_cross], ac_cv_build_prog_cxx_cross)
+m4@&t@_pushdef([ac_cv_prog_cxx_g], ac_cv_build_prog_cxx_g)
+m4@&t@_pushdef([CXX], CXX_FOR_BUILD)
+m4@&t@_pushdef([CXXCPP], CXXCPP_FOR_BUILD)
+m4@&t@_pushdef([CXXFLAGS], CXXFLAGS_FOR_BUILD)
+m4@&t@_pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)
+m4@&t@_pushdef([CXXCPPFLAGS], CXXCPPFLAGS_FOR_BUILD)
+m4@&t@_pushdef([host], build)
+m4@&t@_pushdef([host_alias], build_alias)
+m4@&t@_pushdef([host_cpu], build_cpu)
+m4@&t@_pushdef([host_vendor], build_vendor)
+m4@&t@_pushdef([host_os], build_os)
+m4@&t@_pushdef([ac_cv_host], ac_cv_build)
+m4@&t@_pushdef([ac_cv_host_alias], ac_cv_build_alias)
+m4@&t@_pushdef([ac_cv_host_cpu], ac_cv_build_cpu)
+m4@&t@_pushdef([ac_cv_host_vendor], ac_cv_build_vendor)
+m4@&t@_pushdef([ac_cv_host_os], ac_cv_build_os)
+m4@&t@_pushdef([ac_cxxcpp], ac_build_cxxcpp)
+m4@&t@_pushdef([ac_compile], ac_build_compile)
+m4@&t@_pushdef([ac_link], ac_build_link)
+
+save_cross_compiling=$cross_compiling
+save_ac_tool_prefix=$ac_tool_prefix
+cross_compiling=no
+ac_tool_prefix=
+
+AC_PROG_CXX
+AC_PROG_CXXCPP
+
+ac_tool_prefix=$save_ac_tool_prefix
+cross_compiling=$save_cross_compiling
+
+# Restore the old definitions
+m4@&t@_popdef([ac_link])
+m4@&t@_popdef([ac_compile])
+m4@&t@_popdef([ac_cxxcpp])
+m4@&t@_popdef([ac_cv_host_os])
+m4@&t@_popdef([ac_cv_host_vendor])
+m4@&t@_popdef([ac_cv_host_cpu])
+m4@&t@_popdef([ac_cv_host_alias])
+m4@&t@_popdef([ac_cv_host])
+m4@&t@_popdef([host_os])
+m4@&t@_popdef([host_vendor])
+m4@&t@_popdef([host_cpu])
+m4@&t@_popdef([host_alias])
+m4@&t@_popdef([host])
+m4@&t@_popdef([CXXCPPFLAGS])
+m4@&t@_popdef([CPPFLAGS])
+m4@&t@_popdef([CXXFLAGS])
+m4@&t@_popdef([CXXCPP])
+m4@&t@_popdef([CXX])
+m4@&t@_popdef([ac_cv_prog_cxx_g])
+m4@&t@_popdef([ac_cv_prog_cxx_cross])
+m4@&t@_popdef([ac_cv_prog_cxx_works])
+m4@&t@_popdef([ac_cv_prog_gxx])
+m4@&t@_popdef([ac_cv_prog_CXXCPP])
+
+# Finally, set Makefile variables
+AC_SUBST([CXXFLAGS_FOR_BUILD])
+AC_SUBST([CXXCPPFLAGS_FOR_BUILD])
+
+AC_LANG_POP([C++])
+])
+]])
+
+AT_DATA([configure.ac],
+[[AC_INIT([foo], [1.0])
+AX_PROG_CXX_FOR_BUILD
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+]])
+
+AT_DATA([Makefile.in],
+[[CXX = @CXX@
+CXX_FOR_BUILD = @CXX_FOR_BUILD@
+]])
+
+AT_CHECK_AUTOCONF
+AT_CHECK_CONFIGURE
+
+AT_CHECK([grep '^CXX = ..*$' Makefile > /dev/null 2>&1])
+AT_CHECK([grep '^CXX_FOR_BUILD = ..*$' Makefile > /dev/null 2>&1])
+
+AT_CLEANUP