summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2020-10-14 11:21:30 -0400
committerZack Weinberg <zackw@panix.com>2020-11-30 11:45:27 -0500
commitb8c150bd0d8a3979ec1060f4c0a498e6bd1cd717 (patch)
tree45be03dce4c2c73c410dac31a6b4655c7c5b943e
parent82bc59ff70c5923a1e3be9953763e080b6634c28 (diff)
downloadautoconf-b8c150bd0d8a3979ec1060f4c0a498e6bd1cd717.tar.gz
AT_CHECK_MACRO: test C++ as well as C, cross as well as native
Many of the reported regressions in Autoconf 2.70 betas went unnoticed for years because Autoconf’s bundled test suite didn’t test most of the macros with a C++ compiler and/or in cross compilation mode. There’s a special makefile target ‘maintainer-check-c++’ that runs all the tests with CC=g++, but that doesn’t catch the regressions either, because it doesn’t compare the configure results with what you’d have gotten with a C compiler. Also, C and C++ have diverged to the point where setting CC to a C++ compiler doesn’t work reliably anymore. This patch overhauls AT_CHECK_MACRO to test each macro four times: (C compiler, C++ compiler) x (native mode, cross-compilation mode). All four tests are expected to produce the same config.cache and config.h, except for certain predictable differences due to running AC_PROG_CXX instead of AC_PROG_CC, and a short list of known, acceptable differences, maintained in mktests.pl. There are two classes of known, acceptable differences. Macros that use AC_RUN_IFELSE aren’t tested in cross-compilation mode at all, because they may crash the script (this is temporary and will be revisited after 2.70). Macros that correctly detect a difference between C and C++ (e.g. AC_HEADER_STDBOOL will notice that C++ doesn’t have the _Bool type) are annotated with the specific cache variable and #define that varies. mktests.pl now also has the capability to provide values for the MACRO-USE, ADDITIONAL-COMMANDS, and AUTOCONF-FLAGS arguments to AT_CHECK_(AU_)MACRO, on a per-macro basis, but that’s not used in this patch. Some of the manual uses of AT_CHECK_MACRO do not need to test C++ and/or cross compilation; for them, there is a new test helper, AT_CHECK_CONFIGURE_AC. Another new helper, AT_PRESERVE_CONFIG_STATUS, is used extensively in AT_CHECK_(AU_)MACRO but may be also useful in manual tests that need to do multiple configure runs. This change supersedes AT_CHECK_MACRO_CROSS and ‘make maintainer-check-c++’, which are removed. In my testing, setting CC to a C++ compiler no longer works at all, for reasons that are impractical to fix (e.g. C++ compilers choke on the test for C2011 features) so I have added a note to NEWS saying that this is not supported anymore. * tests/local.at (AT_CHECK_MACRO): Default behavior is now to test the macro in both native and cross-compilation mode, and expect the results to be identical. If the macro transitively required AC_PROG_CC, and a C++ compiler is available, then test it twice more with AC_LANG([C++]) in effect, and again expect the results to be identical. New fifth argument TEST-PARAMETERS can modify this behavior. (_AT_FILTER_CXX_CV_VARIES, _AT_FILTER_CXX_DEFINE_VARIES): New, subroutines of AT_CHECK_MACRO. (AT_CHECK_MACRO_CROSS): Remove, subsumed by new AT_CHECK_MACRO behavior. (AT_CHECK_AU_MACRO): Forward to AT_CHECK_MACRO for the basic test; then do the same autoupdate test as before, as a separate test group. (at_check_env): Also ignore OPENMP_CXXFLAGS. (AT_CONFIG_CMP): Add third argument EXTRA-VARIANCE that specifies additional variables that are expected to vary in a particular test. (_AT_CONFIG_CMP_PRUNE): New, subroutine of AT_CONFIG_CMP. (AT_DEFINES_CMP): New helper macro that compares config.h headers, with the ability to ignore variation in specific defines. (_AT_DEFINES_CMP_PRUNE): New, subroutine of AT_DEFINES_CMP. (AT_PRESERVE_CONFIG_STATUS): New helper that makes copies of config.h, config.log, config.status, and state-env.after under names that won’t be clobbered by a subsequent run of configure. (AT_CHECK_CONFIGURE_AC): New helper that defines a complete test group consisting of a single invocation of _AT_CHECK_AC_MACRO; effectively what AT_CHECK_MACRO used to be. (_AT_CHECK_AC_MACRO): Correct documentation comment; the PRE-TESTS argument has always been optional. * tests/mktests.pl (test_parameters): New global data object giving extra arguments to pass to AT_CHECK_MACRO/AT_CHECK_AU_MACRO on a per-macro basis. (emit_test): New function that handles emitting calls to AT_CHECK_(AU_)MACRO with the desired arguments. (scan_m4_files): Use emit_test. (au_exclude_list): Add AC_HAVE_LIBRARY, AC_COMPILE_CHECK, AC_TRY_CPP, AC_TRY_COMPILE, AC_TRY_LINK, and AC_TRY_RUN. * tests/semantics.at (AC_CHECK_LIB, AC_SEARCH_LIBS): Rewrite test using symbols from zlib instead of libm, to get consistent behavior from C and C++. (AC_SEARCH_LIBS (none needed)): Revise to clarify what is being tested. (AC_CHECK_DECLS): Use _AC_LANG_ABBREV when inspecting cache variables. (AC_CHECK_ALIGNOF, AC_CHECK_ALIGNOF struct) (AC_CHECK_SIZEOF, AC_CHECK_SIZEOF struct) No need for AT_CHECK_MACRO_CROSS. (AC_CHECK_FILES): Switch to AT_CHECK_CONFIGURE_AC. (AC_SYS_RESTARTABLE_SYSCALLS, AC_FUNC_WAIT3): Do not test in cross compilation mode. (AC_TRY_CPP, AC_TRY_COMPILE, AC_TRY_LINK, AC_TRY_RUN) (AC_COMPILE_CHECK, AC_HAVE_LIBRARY): New manual AT_CHECK_AU_MACRO tests. * tests/c.at (Extensions, C keywords, AC_PROG_CPP requires AC_PROG_CC) (AC_NO_EXECUTABLES (working linker), AC_NO_EXECUTABLES (broken linker)): Switch to AT_CHECK_CONFIGURE_AC. Also convert case statements to AS_CASE. (Broken/missing compilers): Pass CC=no-such-compiler on the command line instead of hardwiring it in the configure script. * tests/local.mk (maintainer-check-c++): Remove target. (maintainer-check): Run the ordinary ‘make check’ as well as ‘make maintainer-check-posix’.
-rw-r--r--NEWS12
-rw-r--r--tests/c.at56
-rw-r--r--tests/local.at429
-rw-r--r--tests/local.mk8
-rw-r--r--tests/mktests.pl114
-rw-r--r--tests/semantics.at325
6 files changed, 777 insertions, 167 deletions
diff --git a/NEWS b/NEWS
index 4cad963b..16849cf7 100644
--- a/NEWS
+++ b/NEWS
@@ -69,6 +69,18 @@ GNU Autoconf NEWS - User visible changes.
See the “Input” section of the manual for more detail, including
where to get the auxiliary scripts that may be needed by autoconf macros.
+*** Setting CC to a C++ compiler is no longer supported.
+
+ The C and C++ languages have diverged enough that we can no longer
+ guarantee that test C programs will be processed as intended by a
+ C++ compiler. In this release, configure will proceed anyway, but
+ many test results will be incorrect. In a future release, we may
+ make AC_PROG_CC error out if it detects that CC is a C++ compiler.
+
+ See the “Language Choice” section of the manual for instructions on
+ how to write configure scripts for C++ programs, and for programs
+ with code in more than one language.
+
*** Older versions of automake and aclocal (< 1.8) are no longer supported.
*** AC_CONFIG_SUBDIRS no longer directly supports Cygnus configure.
diff --git a/tests/c.at b/tests/c.at
index 1ae678d1..40720fe4 100644
--- a/tests/c.at
+++ b/tests/c.at
@@ -28,22 +28,24 @@ AT_BANNER([C low level compiling/preprocessing macros.])
## Extensions. ##
## ------------ ##
+AT_CHECK_CONFIGURE_AC([Object file extensions],
+[[AC_PROG_CC
+
# As far as we know only `foo', `foo.exe' are possible executable,
# and `foo.o', `foo.obj' are possible object files. Autoconf must not
# know that, but it is OK for the test suite to take this into account.
-AT_CHECK_MACRO([Extensions],
-[[AC_PROG_CC
-case $ac_exeext in
- '' | '.exe' ) ;;
- * ) AC_MSG_ERROR([suspicious executable suffix: $ac_exeext]);;
-esac
+AS@&t@_CASE([$ac_exeext],
+ ['' | '.exe'],
+ [],
+ [AC_MSG_ERROR([suspicious executable suffix: $ac_exeext])])
-case $ac_objext in
- 'o' | 'obj' ) ;;
- * ) AC_MSG_ERROR([suspicious object suffix: $ac_objext]);;
-esac
-]])
+AS@&t@_CASE([$ac_objext],
+ ['o' | 'obj'],
+ [],
+ [AC_MSG_ERROR([suspicious object suffix: $ac_objext])])
+AC_OUTPUT
+]])
## -------------------------- ##
@@ -58,13 +60,12 @@ AT_SETUP([Broken/missing compilers])
AT_DATA([configure.ac],
[[AC_INIT
-CC=no-such-compiler
AC_PROG_CC
AC_OUTPUT
]])
AT_CHECK_AUTOCONF
-AT_CHECK_CONFIGURE([], 77, ignore, ignore)
+AT_CHECK_CONFIGURE([CC=no-such-compiler], 77, ignore, ignore)
AT_CLEANUP
@@ -73,12 +74,15 @@ AT_CLEANUP
## C keywords. ##
## ------------ ##
-# GCC supports `const', `typeof', and `volatile'.
-AT_CHECK_MACRO([C keywords],
+AT_CHECK_CONFIGURE_AC([C keywords],
[[AC_PROG_CC
+
AC_C_CONST
AC_C_TYPEOF
AC_C_VOLATILE
+
+# If the C compiler is GCC, AC_C_{CONST,TYPEOF,VOLATILE} ought to all
+# detect support for their respective keyword.
case $GCC,$ac_cv_c_const,$ac_cv_c_typeof,$ac_cv_c_volatile in
yes,*no*)
AC_MSG_ERROR([failed to detect `const', `typeof', or `volatile' support]);;
@@ -86,20 +90,20 @@ esac
]])
-
## --------------------------------- ##
## AC_PROG_CPP requires AC_PROG_CC. ##
## --------------------------------- ##
-# Must invoke AC_PROG_CC.
-AT_CHECK_MACRO([AC_PROG_CPP requires AC_PROG_CC],
+AT_CHECK_CONFIGURE_AC([AC_PROG_CPP requires AC_PROG_CC],
[[AC_PROG_CPP
-test -z "$CC" &&
+
+# AC_PROG_CPP should have AC_REQUIREd AC_PROG_CC.
+if test -z "$CC"; then
AC_MSG_ERROR([looked for a C preprocessor without looking for a compiler])
+fi
]])
-
## --------------------------- ##
## AC_PROG_CPP with warnings. ##
## --------------------------- ##
@@ -232,21 +236,21 @@ AT_CLEANUP
## AC_NO_EXECUTABLES (working linker). ##
## ------------------------------------ ##
-AT_CHECK_MACRO([AC_NO_EXECUTABLES (working linker)],
-[AC_NO_EXECUTABLES
+AT_CHECK_CONFIGURE_AC([AC_NO_EXECUTABLES (working linker)],
+[[AC_NO_EXECUTABLES
AC_PROG_CC
-])
+]])
## ----------------------------------- ##
## AC_NO_EXECUTABLES (broken linker). ##
## ----------------------------------- ##
-AT_CHECK_MACRO([AC_NO_EXECUTABLES (broken linker)],
-[LDFLAGS=-lnosuchlibrary
+AT_CHECK_CONFIGURE_AC([AC_NO_EXECUTABLES (broken linker)],
+[[LDFLAGS=-lnosuchlibrary
AC_NO_EXECUTABLES
AC_PROG_CC
-])
+]])
## -------------------------- ##
diff --git a/tests/local.at b/tests/local.at
index 374e530c..e32c3d47 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -363,7 +363,7 @@ if test -f state-env.before && test -f state-env.after; then
[ERLANG_INSTALL_LIB_DIR_.*|ERLANG_ERTS_VER|OBJC|OBJCPP|OBJCFLAGS],
[OBJCXX|OBJCXXCPP|OBJCXXFLAGS],
[GOC|GOFLAGS],
- [OPENMP_CFLAGS],
+ [OPENMP_(C|CXX)FLAGS],
[LIBS|LIB@&t@OBJS|LTLIBOBJS|LDFLAGS],
[INSTALL(_(DATA|PROGRAM|SCRIPT))?],
[EXEEXT|OBJEXT],
@@ -394,8 +394,8 @@ fi
} [#]at_check_env])
-# AT_CONFIG_CMP(VAR-FILE-A, VAR-FILE-B)
-# -------------------------------------
+# AT_CONFIG_CMP(VAR-FILE-A, VAR-FILE-B, [EXTRA-VARIANCE])
+# -------------------------------------------------------
# Check the outcomes of two configure runs for equality by comparing dumps of
# their shell variables. VAR-FILE-A and VAR-FILE-B are two `set'-style shell
# variable space dumps.
@@ -419,6 +419,22 @@ fi
# - BASH_ARGV [bash]
# - LINENO [Posix]
# - _AST_FEATURES [ksh93]
+# - Optionally, variables that are expected to vary in a particular test.
+# This is controlled by the EXTRA-VARIANCE argument, which is a
+# whitespace-separated sequence of tokens. Each token means to ignore
+# one or more additional variables and/or rename some variables, as follows:
+#
+# cross: ignore cross_compiling
+# cxx: ignore all of:
+# - CC, CPP, CCC, CXX, CXXCPP, CFLAGS, CXXFLAGS, GCC, GXX
+# - ac_cv_env_(any of the above)_(set|value)
+# - ac_cv_c_compiler_gnu, ac_cv_cxx_compiler_gnu
+# - ac_cv_c_decl_report, ac_cv_cxx_decl_report
+# - ac_cv_prog_c_*, ac_cv_prog_cxx_*, ac_cv_prog_ac_ct_(CC|CXX)
+# - ac_cv_prog_CPP, ac_cv_prog_CXXCPP
+# + other ac_cv_c_* are renamed to ac_cv_cxx_*
+# + OPENMP_CFLAGS is renamed to OPENMP_CXXFLAGS
+# vary:NAME (where NAME is any identifier): ignore ac_cv_NAME
#
# Furthermore, it is okay for a non-cache variable initialized to empty in one
# run to be unset in another run. This happens when, for example, cache update
@@ -429,14 +445,14 @@ fi
#
# Lines that do not look like `foo=bar' are probably latter lines of
# multiline values; trim them.
-#
m4_define([AT_CONFIG_CMP],
[for act_file in $1 $2
do
- $SED '/^ac_cv_/ b
+ $SED '/^ac_cv_/ b skip
/^m4_defn([m4_re_word])=./ !d
/^[[^=]]*='\'''\''$/ d
/^a[[cs]]_/ d
+ : skip
/^OLDPWD=/ d
/^PPID=/ d
/^RANDOM=/ d
@@ -450,11 +466,124 @@ do
/^BASH_ARGV=/ d
/^LINENO=/ d
/^_AST_FEATURES=/ d
- ' $act_file >at_config_vars-$act_file
+m4_map_args_w([$3], [_AT_CONFIG_CMP_PRUNE(], [)])dnl
+' < $act_file > at_config_vars-$act_file
done
AT_CMP([at_config_vars-$1], [at_config_vars-$2])[]dnl
])# AT_CONFIG_CMP
+# _AT_CONFIG_CMP_PRUNE(TOKEN)
+# ---------------------------
+# Subroutine of AT_CONFIG_CMP which implements the extra-variance rules
+# described above. Expands to additional sed commands to be inserted in
+# the program above.
+# Note for future readers: not all sed implementations allow alternations
+# in regexes (e.g. /^ac_cv_env_CC_\(set\|value\)=/ would not be portable).
+m4_define([_AT_CONFIG_CMP_PRUNE],
+[m4_bmatch([$1],
+ [^cross$],
+[ /^cross_compiling=/ d
+],
+ [^cxx$],
+[ /^CC=/ d
+ /^CPP=/ d
+ /^CCC=/ d
+ /^CXX=/ d
+ /^CXXCPP=/ d
+ /^CFLAGS=/ d
+ /^CXXFLAGS=/ d
+ /^GCC=/ d
+ /^GXX=/ d
+ /^ac_cv_env_CC_set=/ d
+ /^ac_cv_env_CC_value=/ d
+ /^ac_cv_env_CPP_set=/ d
+ /^ac_cv_env_CPP_value=/ d
+ /^ac_cv_env_CFLAGS_set=/ d
+ /^ac_cv_env_CFLAGS_value=/ d
+ /^ac_cv_env_GCC_set=/ d
+ /^ac_cv_env_GCC_value=/ d
+ /^ac_cv_env_CCC_set=/ d
+ /^ac_cv_env_CCC_value=/ d
+ /^ac_cv_env_CXX_set=/ d
+ /^ac_cv_env_CXX_value=/ d
+ /^ac_cv_env_CXXCPP_set=/ d
+ /^ac_cv_env_CXXCPP_value=/ d
+ /^ac_cv_env_CXXFLAGS_set=/ d
+ /^ac_cv_env_CXXFLAGS_value=/ d
+ /^ac_cv_env_GXX_set=/ d
+ /^ac_cv_env_GXX_value=/ d
+ /^ac_cv_prog_ac_ct_CC=/ d
+ /^ac_cv_prog_ac_ct_CXX=/ d
+ /^ac_cv_prog_CPP=/ d
+ /^ac_cv_prog_CXXCPP=/ d
+ /^ac_cv_c_compiler_gnu=/ d
+ /^ac_cv_cxx_compiler_gnu=/ d
+ /^ac_cv_c_decl_report=/ d
+ /^ac_cv_cxx_decl_report=/ d
+ /^ac_cv_prog_c_@<:@^=@:>@*=/ d
+ /^ac_cv_prog_cc_@<:@^=@:>@*=/ d
+ /^ac_cv_prog_cxx_@<:@^=@:>@*=/ d
+ s/^ac_cv_c_/ac_cv_cxx_/
+ s/^OPENMP_CFLAGS=/OPENMP_CXXFLAGS=/
+],
+ [^vary:],
+[ /^ac_cv_]m4_bpatsubsts([$1], [\<vary:], [])[=/ d
+],
+ [m4_fatal([unrecognized AT_CONFIG_CMP variance token: "$1"])])])
+
+
+# AT_DEFINES_CMP(CONFIG-H-A, CONFIG-H-B, [EXTRA-VARIANCE])
+# --------------------------------------------------------
+# Check the outcomes of two configure runs for equality by comparing the
+# config.h headers they produced. Optionally, ignore changes to particular
+# defines, under the control of the EXTRA-VARIANCE argument, which is a
+# whitespace-separated sequence of tokens. Each token means to ignore
+# one or more additional defines, as follows:
+# vary:NAME (where NAME is any identifier): ignore #define/#undef NAME
+m4_define([AT_DEFINES_CMP],
+[m4_ifblank([$3], [AT_CMP([$1], [$2])],
+[for act_file in $1 $2
+do
+ $SED '
+m4_map_args_w([$3], [_AT_DEFINES_CMP_PRUNE(], [)])
+' < $act_file > at_defines-$act_file
+done
+AT_CMP([at_defines-$1], [at_defines-$2])[]dnl
+])])# AT_DEFINES_CMP
+
+
+# _AT_DEFINES_CMP_PRUNE(TOKEN)
+# ---------------------------
+# Subroutine of AT_DEFINES_CMP which implements the extra-variance rules
+# described above. Expands to one or more sed commands.
+# After quadrigraph replacement, each sed command group will be
+# /#define macro_name[ (]/ d ;#)
+# /#undef macro_name[ (]/ d ;#)
+# AC_DEFINE never emits tabs or puts whitespace between '#' and
+# 'define' or 'undef', so this is sufficient.
+m4_define([_AT_DEFINES_CMP_PRUNE],
+[m4_bmatch([$1],
+ [^vary:],
+[ /@%:@define ]m4_bpatsubsts([$1], [\<vary:], [])dnl
+[@<:@ @{:@@:>@/ d ;@%:@@:}@
+ /@%:@undef ]m4_bpatsubsts([$1], [\<vary:], [])dnl
+[@<:@ @{:@@:>@/ d ;@%:@@:}@
+],
+ [m4_fatal([unrecognized AT_DEFINES_CMP variance token: "$1"])])])
+
+
+# AT_PRESERVE_CONFIG_STATUS(SUFFIX)
+# ---------------------------------
+# Copy the files 'state-env.after', 'config.h', 'config.log', and
+# 'config.status' to names ending with SUFFIX, so they are not
+# clobbered by a subsequent run of configure.
+m4_define([AT_PRESERVE_CONFIG_STATUS],
+[cp -f state-env.after state-env.$1
+cp -f config.h config-h.$1
+cp -f config.log config-log.$1
+cp -f config.status config-status.$1
+])
+
# AT_CHECK_DEFINES(CONTENT)
# -------------------------
@@ -510,8 +639,8 @@ dnl pacify editors that don't understand sh case: ((
])
-# _AT_CHECK_AC_MACRO(AC-BODY, PRE-TESTS, [AUTOCONF-FLAGS])
-# --------------------------------------
+# _AT_CHECK_AC_MACRO(AC-BODY, [PRE-TESTS], [AUTOCONF-FLAGS])
+# ----------------------------------------------------------
# Create a minimalist configure.ac running the macro named
# NAME-OF-THE-MACRO, check that autoconf runs on that script,
# and that the generated configure script runs without error.
@@ -524,97 +653,267 @@ AT_CHECK_CONFIGURE
AT_CHECK_ENV
])# _AT_CHECK_AC_MACRO
+# AT_CHECK_CONFIGURE_AC(NAME, AC-BODY, [AUTOCONF-FLAGS],
+# [PRE-TESTS], [POST-TESTS])
+# -----------------------------------------------------
+# Shorthand for a complete test "group" consisting of a single
+# invocation of _AT_CHECK_AC_MACRO, possibly with some additional
+# tests executed before and after.
+m4_define([AT_CHECK_CONFIGURE_AC],
+[AT_SETUP([$1])
+_AT_CHECK_AC_MACRO([$2], [$4], [$3])
+$5
+AT_CLEANUP
+])
# AT_CHECK_MACRO(MACRO, [MACRO-USE], [ADDITIONAL-CMDS],
-# [AUTOCONF-FLAGS])
+# [AUTOCONF-FLAGS], [TEST-PARAMETERS])
# -----------------------------------------------------
-# Create a minimalist configure.ac running the macro named
-# NAME-OF-THE-MACRO, check that autoconf runs on that script,
+# Create a minimalist configure.ac running the macro named MACRO
+# (using the code in MACRO-USE if that argument is not empty,
+# otherwise a bare invocation of MACRO with no arguments),
+# check that autoconf runs on that script,
# and that the generated configure script runs without error.
-#
-# We run `configure' twice, both times with a cache, and compare
-# the environment after each run to detect inconsistencies.
+# AUTOCONF-FLAGS are passed to all invocations of autoconf.
+#
+# We always generate two variants of the minimalist configure.ac,
+# with and without forcing the script into cross-compilation mode
+# before executing MACRO-USE. If a C++ compiler is available, we
+# generate two more variants in which MACRO-USE is invoked while
+# AC_LANG([C++]) is in effect; as before, one forces the script into
+# cross-compilation mode and the other doesn't. All variants of the
+# generated configure script are run twice, once with an empty cache,
+# and once with a cache primed by the previous run.
+#
+# All four (or eight, if C++ is available) runs are expected to
+# produce the same results, except for the value of 'cross_compiling'
+# and differences due to running AC_PROG_CXX instead of AC_PROG_CC.
+# (See AT_CONFIG_CMP for details.)
+#
+# If ADDITIONAL-CMDS are present, they are executed after the first
+# pair of tests (with the C compiler, in native mode).
+#
+# If TEST-PARAMETERS are present, they should be a space-separated
+# list of modifiers to how the test is carried out. Currently
+# the following modifiers are defined:
+#
+# - `no-cross': Don't test this macro in cross-compilation mode.
+# This is for macros that use AC_RUN_IFELSE, and therefore, when
+# cross-compiling, they either crash or give a `best guess' answer
+# that may be wrong.
+#
+# - `cxx_cv_varies:NAME': The value of the cache variable ac_cv_NAME
+# may legitimately vary between the C tests and the C++ tests.
+#
+# - `cxx_define_varies:NAME' The value of the AC_DEFINEd macro NAME
+# may legitimately vary between the C tests and the C++ tests.
m4_define([AT_CHECK_MACRO],
[AT_SETUP([$1])
+# C compiler, native mode.
AT_CONFIGURE_AC([m4_default([$2], [$1])])
-
AT_CHECK_AUTOCONF([$4])
AT_CHECK_AUTOHEADER([$4], [ignore])
-for at_run in r1 r2
-do
- AT_CHECK_CONFIGURE([-C])
- cp -f state-env.after state-env.$at_run
- cp -f config.h config-h.$at_run
- cp -f config.log config-log.$at_run
- cp -f config.status config-status.$at_run
- AT_CHECK_ENV
-done
+cp -f configure.ac configure-ac.c-native
+cp -f configure configure.c-native
+cp -f config.hin config-hin.c-native
-AT_CMP([config-h.r1], [config-h.r2])
-AT_CONFIG_CMP([state-env.r1], [state-env.r2])
+AT_CHECK_CONFIGURE([-C])
+AT_PRESERVE_CONFIG_STATUS([c-native-r1])
+AT_CHECK_ENV
+AT_CHECK_CONFIGURE([-C])
+AT_PRESERVE_CONFIG_STATUS([c-native-r2])
+AT_CHECK_ENV
-$3
+AT_DEFINES_CMP([config-h.c-native-r1], [config-h.c-native-r2])
+AT_CONFIG_CMP([state-env.c-native-r1], [state-env.c-native-r2])
-AT_CLEANUP[]dnl
+m4_n([$3])dnl
+m4_bmatch([$5], [\<no-cross\>], [], [dnl
+
+# C compiler, cross-compilation mode.
+rm -rf config.cache autom4te.cache
+AT_CONFIGURE_AC(
+[cross_compiling=yes
+ac_tool_warned=yes
+m4_default([$2], [$1])])
+AT_CHECK_AUTOCONF([$4])
+AT_CHECK_AUTOHEADER([$4], [ignore])
+
+cp -f configure.ac configure-ac.c-cross
+cp -f configure configure.c-cross
+cp -f config.hin config-hin.c-cross
+
+AT_CHECK_CONFIGURE([-C])
+AT_PRESERVE_CONFIG_STATUS([c-cross-r1])
+AT_CHECK_ENV
+AT_DEFINES_CMP([config-h.c-native-r1], [config-h.c-cross-r1])
+AT_CONFIG_CMP([state-env.c-native-r1], [state-env.c-cross-r1], [cross])
+
+AT_CHECK_CONFIGURE([-C])
+AT_PRESERVE_CONFIG_STATUS([c-cross-r2])
+AT_CHECK_ENV
+AT_DEFINES_CMP([config-h.c-native-r1], [config-h.c-cross-r2])
+AT_CONFIG_CMP([state-env.c-native-r1], [state-env.c-cross-r2], [cross])
+])dnl
+
+# To save time, skip the C++-mode tests for any macro that did not
+# transitively require AC_PROG_CC; it won't make any difference.
+if grep '^CC=' state-env.c-native-r1 > /dev/null 2>&1; then
+
+ # C++ compiler, native mode.
+ rm -rf config.cache autom4te.cache
+ AT_CONFIGURE_AC(
+ [AC_LANG([C++])
+ m4_default([$2], [$1])])
+
+ # Autoconf may fail here because of an AC_LANG_ASSERT([C]); this
+ # means the macro is specific to C and should not be tested with the
+ # C++ compiler.
+ AT_CHECK_AUTOCONF([$4], [ignore], [ignore], [stderr])
+ if test -s stderr; then
+ AT_CHECK([grep 'error: AC_LANG_ASSERT: current language is not C' stderr],
+ [0], [ignore], [ignore])
+ else
+ AT_CHECK_AUTOHEADER([$4], [ignore])
+
+ cp -f configure.ac configure-ac.cxx-native
+ cp -f configure configure.cxx-native
+ cp -f config.hin config-hin.cxx-native
+
+ # If this configure pass fails with code 77, that means there is no
+ # C++ compiler available; don't mark the entire test group skipped,
+ # just skip the rest of the C++ testing.
+ AT_CHECK_CONFIGURE([-C;
+ status=$?
+ if test $status -eq 77; then
+ touch at-no-cxx
+ exit 0
+ else
+ exit $status
+ fi
+ ])
+ if test ! -f at-no-cxx; then
+ AT_PRESERVE_CONFIG_STATUS([cxx-native-r1])
+ AT_CHECK_ENV
+ AT_DEFINES_CMP([config-h.c-native-r1], [config-h.cxx-native-r1],
+ _AT_FILTER_CXX_DEFINE_VARIES([$5]))
+ AT_CONFIG_CMP([state-env.c-native-r1], [state-env.cxx-native-r1],
+ [cxx ]_AT_FILTER_CXX_CV_VARIES([$5]))
+
+ AT_CHECK_CONFIGURE([-C])
+ AT_PRESERVE_CONFIG_STATUS([cxx-native-r2])
+ AT_CHECK_ENV
+ AT_DEFINES_CMP([config-h.cxx-native-r1], [config-h.cxx-native-r2])
+ AT_CONFIG_CMP([state-env.cxx-native-r1], [state-env.cxx-native-r2])
+m4_bmatch([$5], [\<no-cross\>], [], [dnl
+
+ # Fourth run: C++ compiler, cross-compilation mode.
+
+ rm -rf config.cache autom4te.cache
+ AT_CONFIGURE_AC(
+ [cross_compiling=yes
+ ac_tool_warned=yes
+ AC_LANG([C++])
+ m4_default([$2], [$1])])
+ AT_CHECK_AUTOCONF([$4])
+ AT_CHECK_AUTOHEADER([$4], [ignore])
+
+ cp -f configure.ac configure-ac.cxx-cross
+ cp -f configure configure.cxx-cross
+ cp -f config.hin config-hin.cxx-cross
+
+ AT_CHECK_CONFIGURE([-C])
+ AT_PRESERVE_CONFIG_STATUS([cxx-cross-r1])
+ AT_CHECK_ENV
+ AT_DEFINES_CMP([config-h.cxx-native-r1], [config-h.cxx-cross-r1])
+ AT_CONFIG_CMP([state-env.cxx-native-r1], [state-env.cxx-cross-r1],
+ [cross])
+
+ AT_CHECK_CONFIGURE([-C])
+ AT_PRESERVE_CONFIG_STATUS([cxx-cross-r2])
+ AT_CHECK_ENV
+ AT_DEFINES_CMP([config-h.cxx-cross-r1], [config-h.cxx-cross-r2])
+ AT_CONFIG_CMP([state-env.cxx-cross-r1], [state-env.cxx-cross-r2])
+])dnl
+ fi # C++ compiler available
+ fi # macro can be used with C++
+fi # C++ makes a difference
+
+AT_CLEANUP
])# AT_CHECK_MACRO
-# AT_CHECK_MACRO_CROSS(MACRO, [MACRO-USE], [ADDITIONAL-CMDS],
-# [AUTOCONF-FLAGS])
-# -----------------------------------------------------------
-# Like the previous one, but creates two checks: for native
-# compile and for cross-compile.
-m4_define([AT_CHECK_MACRO_CROSS],
-[AT_CHECK_MACRO($@)
-AT_CHECK_MACRO([$1 (cross compile)],
- [AT_KEYWORDS([cross])
- # Exercise the code used when cross-compiling.
- cross_compiling=yes
- ac_tool_warned=yes
- m4_default([$2], [$1])],
- [$3], [$4])
-])
+# _AT_FILTER_CXX_CV_VARIES(TEST-PARAMETERS)
+# ---------------------------------------------
+# Subroutine of AT_CHECK_MACRO that expands to a sequence of
+# zero or more `vary:NAME' tokens, one for each occurrence of
+# `cxx_cv_varies:NAME' in TEST-PARAMETERS.
+m4_define([_AT_FILTER_CXX_CV_VARIES],
+[m4_map_args_w([$1], [_AT_FILTER_CXX_CV_VARY(], [)], [ ])])
+
+m4_define([_AT_FILTER_CXX_CV_VARY],
+[m4_bmatch([$1], [^cxx_cv_varies:],
+ [m4_bpatsubsts([$1], [\<cxx_cv_varies:], [vary:])])])
-# AT_CHECK_AU_MACRO(MACRO)
+# _AT_FILTER_CXX_DEFINE_VARIES(TEST-PARAMETERS)
+# ---------------------------------------------
+# Subroutine of AT_CHECK_MACRO that expands to a sequence of
+# zero or more `vary:NAME' tokens, one for each occurrence of
+# `cxx_define_varies:NAME' in TEST-PARAMETERS.
+m4_define([_AT_FILTER_CXX_DEFINE_VARIES],
+[m4_map_args_w([$1], [_AT_FILTER_CXX_DEFINE_VARY(], [)], [ ])])
+
+m4_define([_AT_FILTER_CXX_DEFINE_VARY],
+[m4_bmatch([$1], [^cxx_define_varies:],
+ [m4_bpatsubsts([$1], [\<cxx_define_varies:], [vary:])])])
+
+
+# AT_CHECK_AU_MACRO(MACRO, [MACRO-USE], [ADDITIONAL-CMDS],
+# [AUTOCONF-FLAGS], [TEST-PARAMETERS])
# ------------------------
-# Create a minimalist configure.ac running the macro named
-# NAME-OF-THE-MACRO, check that autoconf runs on that script,
-# and that the generated configure script runs without error.
-#
-# Then run autoupdate on that script, and check that NAME-OF-THE-MACRO
-# no longer appears in configure.ac, autoconf runs on the updated
-# script, the configure script still runs without error, and the
-# result is unchanged.
-#
-# On the first pass, check for a -Wobsolete warning naming
-# NAME-OF-THE-MACRO. On the second pass, *don't* check for the
-# absence of -Wobsolete warnings, because many of autoupdate's edits
-# leave the configure.ac author with some manual work to do, and
-# indicate this by inserting an m4_warn message to be removed
-# after the manual work is complete.
+# Do all the tests that AT_CHECK_MACRO(...) would do.
+#
+# In addition, run autoupdate on configure.ac; afterward, verify that
+# MACRO no longer appears in configure.ac, autoconf runs on the
+# updated script, the configure script still runs without error, and
+# the result of configuration is unchanged.
+#
+# Before running autoupdate, check for a -Wobsolete warning naming
+# MACRO from configure. After running autoupdate, *don't* check for
+# the absence of -Wobsolete warnings, because many of autoupdate's
+# edits leave the configure.ac author with some manual work to do, and
+# indicate this by inserting an m4_warn message to be removed after
+# the manual work is complete.
m4_define([AT_CHECK_AU_MACRO],
-[AT_SETUP([$1])
+[AT_CHECK_MACRO([$1], [$2], [$3], [-Wno-obsolete $4], [$5])
+
+AT_SETUP([autoupdating $1])
AT_KEYWORDS([autoupdate])
-AT_CONFIGURE_AC([$1])
+AT_CONFIGURE_AC([m4_default([$2], [$1])])
-AT_CHECK_AUTOCONF([], 0, [], [stderr])
+AT_CHECK_AUTOCONF([$4], 0, [], [stderr])
AT_CHECK([grep 'macro .$1. is obsolete' stderr], 0, [ignore], [ignore])
-AT_CHECK_AUTOHEADER([-Wno-obsolete], [ignore])
+AT_CHECK_AUTOHEADER([-Wno-obsolete $4], [ignore])
AT_CHECK_CONFIGURE
AT_CHECK_ENV
+AT_PRESERVE_CONFIG_STATUS([before-au])
rm config.hin
AT_CHECK_AUTOUPDATE([], 0, [], ignore)
AT_CHECK([grep '^$1$' configure.ac], 1)
-AT_CHECK_AUTOCONF([-Wno-obsolete])
-AT_CHECK_AUTOHEADER([-Wno-obsolete], [ignore])
+AT_CHECK_AUTOCONF([-Wno-obsolete $4])
+AT_CHECK_AUTOHEADER([-Wno-obsolete $4], [ignore])
AT_CHECK_CONFIGURE
AT_CHECK_ENV
+AT_PRESERVE_CONFIG_STATUS([after-au])
+
+AT_CMP([config-h.before-au], [config-h.after-au])
+AT_CONFIG_CMP([state-env.before-au], [state-env.after-au])
AT_CLEANUP[]dnl
])# AT_CHECK_AU_MACRO
diff --git a/tests/local.mk b/tests/local.mk
index 3b8688cf..f712b531 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -210,10 +210,10 @@ CLEANFILES += tests/mktests.tmp tests/mktests.stamp
## maintainer-check ##
-# These cannot be run in parallel.
+# The test suite cannot be run in parallel with itself.
maintainer-check:
+ $(MAKE) $(AM_MAKEFLAGS) check
$(MAKE) $(AM_MAKEFLAGS) maintainer-check-posix
- $(MAKE) $(AM_MAKEFLAGS) maintainer-check-c++
# The hairy heredoc is more robust than using echo.
CLEANFILES += expr
@@ -234,7 +234,3 @@ expr:
maintainer-check-posix: expr
POSIXLY_CORRECT=yes $(MAKE) $(AM_MAKEFLAGS) check
rm expr
-
-# Try using G++ as a C compiler.
-maintainer-check-c++:
- CC=g++ $(MAKE) $(AM_MAKEFLAGS) check
diff --git a/tests/mktests.pl b/tests/mktests.pl
index 2571ef21..63920897 100644
--- a/tests/mktests.pl
+++ b/tests/mktests.pl
@@ -27,7 +27,7 @@ use warnings FATAL => 'all';
# Not every macro can be run without arguments, and some are already
# tested elsewhere.
my @ac_exclude_list = (
- # Internal macros are used elsewhere.
+ # Internal macros should not be invoked directly from a configure.ac.
qr/^_?_AC_/,
# Used in many places.
@@ -128,11 +128,88 @@ my @au_exclude_list = (
qr/^AC_(DIAGNOSE|FATAL|OBSOLETE|WARNING)$/,
qr/^AC_(FOREACH|LINK_FILES|PREREQ)$/,
+ # Need arguments. Tested in semantics.at.
+ qr/^AC_HAVE_LIBRARY$/,
+ qr/^AC_COMPILE_CHECK$/,
+ qr/^AC_TRY_(COMPILE|CPP|LINK|RUN)$/,
+
# Not macros, just mapping from old variable name to a new one.
qr/^ac_cv_prog_(gcc|gxx|g77)$/,
);
+# test_parameters
+# ---------------
+# Extra arguments to pass to the test macro for particular macros.
+# Keys are macro names, values are records containing one or more
+# of the possible optional arguments to AT_CHECK_(AU_)MACRO:
+# macro_use, additional_commands, autoconf_flags, test_parameters => '...'.
+# Entries in this hash are grouped by common situations, and sorted
+# alphabetically within each group.
+# Note that you must provide M4 quotation; emit_test will not quote
+# the arguments for you. (This is so you can _not_ quote the arguments
+# when that's useful.)
+
+my %test_parameters = (
+ # Uses AC_RUN_IFELSE, cross-compilation test fails.
+ AC_FC_CHECK_BOUNDS => { test_parameters => '[no-cross]' },
+ AC_FUNC_CHOWN => { test_parameters => '[no-cross]' },
+ AC_FUNC_FNMATCH => { test_parameters => '[no-cross]' },
+ AC_FUNC_FORK => { test_parameters => '[no-cross]' },
+ AC_FUNC_GETGROUPS => { test_parameters => '[no-cross]' },
+ AC_FUNC_LSTAT => { test_parameters => '[no-cross]' },
+ AC_FUNC_MALLOC => { test_parameters => '[no-cross]' },
+ AC_FUNC_MEMCMP => { test_parameters => '[no-cross]' },
+ AC_FUNC_MKTIME => { test_parameters => '[no-cross]' },
+ AC_FUNC_MMAP => { test_parameters => '[no-cross]' },
+ AC_FUNC_REALLOC => { test_parameters => '[no-cross]' },
+ AC_FUNC_STAT => { test_parameters => '[no-cross]' },
+ AC_FUNC_STRCOLL => { test_parameters => '[no-cross]' },
+ AC_FUNC_STRNLEN => { test_parameters => '[no-cross]' },
+ AC_FUNC_STRTOD => { test_parameters => '[no-cross]' },
+
+ # Different result with a C++ compiler than a C compiler:
+ # C++ compilers may or may not support these features from C1999 and later.
+ AC_C_RESTRICT => {
+ test_parameters => ('[cxx_define_varies:restrict' .
+ ' cxx_cv_varies:cxx_restrict]')
+ },
+ AC_C_TYPEOF => {
+ test_parameters => ('[cxx_define_varies:typeof' .
+ ' cxx_define_varies:HAVE_TYPEOF' .
+ ' cxx_cv_varies:cxx_typeof]')
+ },
+ AC_C__GENERIC => {
+ test_parameters => ('[cxx_define_varies:HAVE_C__GENERIC' .
+ ' cxx_cv_varies:cxx__Generic]')
+ },
+ AC_C_VARARRAYS => {
+ test_parameters => ('[cxx_define_varies:HAVE_C_VARARRAYS' .
+ ' cxx_define_varies:__STDC_NO_VLA__' .
+ ' cxx_cv_varies:cxx_vararrays]')
+ },
+
+ # stdbool.h is supposed to be includeable from C++, per C++2011
+ # [support.runtime], but the type _Bool was not added to the C++
+ # standard, so it may or may not be present depending on how much
+ # the C++ compiler cares about C source compatibility.
+ AC_CHECK_HEADER_STDBOOL => {
+ test_parameters => ('[cxx_define_varies:HAVE__BOOL' .
+ ' cxx_cv_varies:type__Bool]')
+ },
+ AC_HEADER_STDBOOL => {
+ test_parameters => ('[cxx_define_varies:HAVE__BOOL' .
+ ' cxx_cv_varies:type__Bool]')
+ },
+
+ # G++ forces -D_GNU_SOURCE which, with some versions of GNU libc,
+ # changes the declaration of strerror_r. Blech.
+ AC_FUNC_STRERROR_R => {
+ test_parameters => ('[cxx_define_varies:STRERROR_R_CHAR_P' .
+ ' cxx_cv_varies:func_strerror_r_char_p]')
+ },
+);
+
# skip_macro MACRO, EXCLUDE-LIST
# ------------------------------
# Returns truthy if any of the regexes in EXCLUDE-LIST match MACRO.
@@ -147,6 +224,35 @@ sub skip_macro
}
+# emit_test FH, TEST-MACRO, MACRO
+# --------------------------------
+# Emit code to FH to test MACRO using TEST-MACRO.
+# TEST-MACRO is expected to be either AT_CHECK_MACRO or AT_CHECK_AU_MACRO;
+# see local.at.
+sub emit_test
+{
+ my ($fh, $test_macro, $macro) = @_;
+ my $params = $test_parameters{$macro} || {};
+ my $macro_use = ${$params}{macro_use} || '';
+ my $additional_commands = ${$params}{additional_commands} || '';
+ my $autoconf_flags = ${$params}{autoconf_flags} || '';
+ my $test_parameters = ${$params}{test_parameters} || '';
+
+ $autoconf_flags = '[]'
+ if $autoconf_flags eq '' && $test_parameters ne '';
+ $additional_commands = '[]'
+ if $additional_commands eq '' && $autoconf_flags ne '';
+ $macro_use = '[]'
+ if $macro_use eq '' && $additional_commands ne '';
+
+ print $fh "$test_macro([$macro]";
+ print $fh ", $autoconf_flags" if $autoconf_flags ne '';
+ print $fh ", $additional_commands" if $additional_commands ne '';
+ print $fh ", $autoconf_flags" if $autoconf_flags ne '';
+ print $fh ", $test_parameters" if $test_parameters ne '';
+ print $fh ")\n";
+}
+
# scan_m4_files
# -------------
# Scan all of the Autoconf source files and produce lists of macros
@@ -267,12 +373,14 @@ EOF
if (@$ac_macros)
{
print $fh "\n# Modern macros.\n";
- print $fh "AT_CHECK_MACRO([$_])\n" for sort @$ac_macros;
+ emit_test ($fh, 'AT_CHECK_MACRO', $_)
+ for sort @$ac_macros;
}
if (@$au_macros)
{
print $fh "\n# Obsolete macros.\n";
- print $fh "AT_CHECK_AU_MACRO([$_])\n" for sort @$au_macros;
+ emit_test ($fh, 'AT_CHECK_AU_MACRO', $_)
+ for sort @$au_macros;
}
}
else
diff --git a/tests/semantics.at b/tests/semantics.at
index d14e5713..8e218355 100644
--- a/tests/semantics.at
+++ b/tests/semantics.at
@@ -26,81 +26,177 @@ AT_BANNER([Semantics.])
# AC_CHECK_LIB
# ------------
-# Well, I can't imagine a system where `cos' is neither in libc, nor
-# in libm. Nor can I imagine a lib more likely to exists than libm.
-# But there are systems without libm, on which we don't want to have
-# this test fail, so exit successfully if `cos' is in libc.
-AT_CHECK_MACRO([AC_CHECK_LIB],
-[AC_TRY_LINK_FUNC(cos,
- [AC_MSG_ERROR([`cos' is in `libc'], 77)])
+# Test for symbols in a library that is very likely to be available
+# and can be used from both C and C++: zlib, which we assume is
+# available unless <zlib.h> doesn't exist.
+# We used to use math library symbols for this, but that no longer
+# works, because some C++ compilers pull in libm by default when the
+# matching C compiler doesn't, breaking AT_CHECK_MACRO's expectations.
+AT_CHECK_MACRO([AC_CHECK_LIB], [[
+AC_CHECK_HEADER([zlib.h], [], [
+ AC_MSG_NOTICE([zlib not available, skipping test])
+ AS_EXIT(77)
+])
-AC_CHECK_LIB(m, cos,,
- [AC_MSG_ERROR([cannot find `cos' in `libm'])])
+# Using : for the ACTION-IF-FOUND in each call to AC_CHECK_LIB
+# prevents LIBS from accumulating copies of "-lz".
-# No kidding, using variables was broken in 2.50 :(
-ac_sin=sin
-AC_CHECK_LIB(m, $ac_sin,,
- [AC_MSG_ERROR([cannot find `\$ac_sin' (= `$ac_sin') in `libm'])])
-
-AS_UNSET([ac_cv_lib_m_acos])
-ac_m=m
-AC_CHECK_LIB($ac_m, acos,,
- [AC_MSG_ERROR([cannot find `acos' in `\$ac_m' (= `$ac_m')])])
-if test "${ac_cv_lib_m_acos+set}" != set; then
- AC_MSG_ERROR([ac_cv_lib_m_acos not set])
+AC_CHECK_LIB([z], [zlibVersion], [:], [
+ AC_MSG_ERROR([cannot find zlibVersion in libz])
+])
+if test "${ac_cv_lib_z_zlibVersion+set}" != set; then
+ AC_MSG_ERROR([ac_cv_lib_z_zlibVersion not set])
fi
-ac_asin=asin
-AC_CHECK_LIB($ac_m, $ac_asin,,
- [AC_MSG_ERROR([cannot find `\$ac_asin' (= `$ac_asin') in `\$ac_m' (= `$ac_m')])])
-# But if the bug is in the caching mechanism, then be sure we
-# correctly detect failures.
+# No kidding, using variables was broken in 2.50 :(
+ac_deflate=deflate
+AC_CHECK_LIB([z], [$ac_deflate], [:], [
+ AC_MSG_ERROR([cannot find \$ac_deflate (= $ac_deflate) in libz])
+])
+if test "${ac_cv_lib_z_deflate+set}" != set; then
+ AC_MSG_ERROR([ac_cv_lib_z_deflate not set])
+fi
-AC_CHECK_LIB(m, cossack,
- [AC_MSG_ERROR([found `cossack' in `libm'])])
+ac_z=z
+AC_CHECK_LIB([$ac_z], [deflateEnd], [:], [
+ AC_MSG_ERROR([cannot find deflateEnd in lib\$ac_z (= lib$ac_z)])
+])
+if test "${ac_cv_lib_z_deflateEnd+set}" != set; then
+ AC_MSG_ERROR([ac_cv_lib_z_deflateEnd not set])
+fi
-# No kidding, using variables was broken in 2.50 :(
-ac_sinner=sinner
-AC_CHECK_LIB(m, $ac_sinner,
- [AC_MSG_ERROR([found `\$ac_sinner' (= `$ac_sinner') in `libm'])])
+ac_inflate=inflate
+AC_CHECK_LIB([$ac_z], [$ac_inflate], [:], [
+ AC_MSG_ERROR(
+ [cannot find \$ac_inflate (= $ac_inflate) in lib\$ac_z (= lib$ac_z)])
+])
+if test "${ac_cv_lib_z_inflate+set}" != set; then
+ AC_MSG_ERROR([ac_cv_lib_z_inflate not set])
+fi
-ac_m=m
-AC_CHECK_LIB($ac_m, acossack,
- [AC_MSG_ERROR([found `acossack' in `\$ac_m' (= `$ac_m')])])
+# Also test for symbols that don't (well, shouldn't) exist.
+# These should still set their cache variables!
+AC_CHECK_LIB([z], [deflagrate], [
+ AC_MSG_ERROR([found deflagrate in libz])
+], [:])
+if test "${ac_cv_lib_z_deflagrate+set}" != set; then
+ AC_MSG_ERROR([ac_cv_lib_z_zlibVersion not set])
+fi
-ac_asinner=asinner
-AC_CHECK_LIB($ac_m, $ac_asinner,
- [AC_MSG_ERROR([found `\$ac_asinner' (= `$ac_asinner') in `\$ac_m' (= `$ac_m')])])
+ac_defenestrate=defenestrate
+AC_CHECK_LIB([z], [$ac_defenestrate], [
+ AC_MSG_ERROR([found \$ac_defenestrate (= $ac_defenestrate) in libz])
+], [:])
+if test "${ac_cv_lib_z_defenestrate+set}" != set; then
+ AC_MSG_ERROR([ac_cv_lib_z_defenestrate not set])
+fi
-])
+AC_CHECK_LIB([$ac_z], [defoliate], [
+ AC_MSG_ERROR([found defoliate in lib\$ac_z (= lib$ac_z)])
+], [:])
+if test "${ac_cv_lib_z_defoliate+set}" != set; then
+ AC_MSG_ERROR([ac_cv_lib_z_defoliate not set])
+fi
+
+ac_infiltrate=infiltrate
+AC_CHECK_LIB([$ac_z], [$ac_infiltrate], [
+ AC_MSG_ERROR(
+ [found \$ac_infiltrate (= $ac_infiltrate) in lib\$ac_z (= lib$ac_z)])
+], [:])
+if test "${ac_cv_lib_z_infiltrate+set}" != set; then
+ AC_MSG_ERROR([ac_cv_lib_z_infiltrate not set])
+fi
+]])
# AC_SEARCH_LIBS
# --------------
-AT_CHECK_MACRO([AC_SEARCH_LIBS],
-[
-AC_SEARCH_LIBS(cos, oser m ust,,
- [AC_MSG_ERROR([cannot find `cos'])])
-
-case "$ac_cv_search_cos" in
- -loser|-lust) AC_MSG_ERROR([jeez, $ac_cv_search_cos must be a cool library!]) ;;
-esac
+# Like AC_CHECK_LIBS, we use zlib here because we need the behavior to
+# be consistent between the C and C++ compilers.
+AT_CHECK_MACRO([AC_SEARCH_LIBS (needed)], [[
+AC_CHECK_HEADER([zlib.h], [], [
+ AC_MSG_NOTICE([zlib not available, skipping test])
+ AS_EXIT(77)
])
+# Unlike AC_CHECK_LIBS, AC_SEARCH_LIBS sets $LIBS *even if*
+# ACTION-IF-FOUND is given, so we need to reset it after each test.
+ac_at_save_LIBS="$LIBS"
+
+AC_SEARCH_LIBS([zlibVersion], [z], [:], [:])
+if test x"$ac_cv_search_zlibVersion" != x-lz; then
+ AC_MSG_ERROR([wrong zlibVersion search result: $ac_cv_search_zlibVersion])
+fi
+LIBS="$ac_at_save_LIBS"
+
+# No kidding, using variables was broken in 2.50 :(
+ac_deflate=deflate
+AC_SEARCH_LIBS([$ac_deflate], [z], [:], [:])
+if test x"$ac_cv_search_deflate" != x-lz; then
+ AC_MSG_ERROR([wrong deflate search result: $ac_cv_search_deflate])
+fi
+LIBS="$ac_at_save_LIBS"
+
+ac_z=z
+AC_SEARCH_LIBS([deflateEnd], [$ac_z], [:], [:])
+if test x"$ac_cv_search_deflateEnd" != x-lz; then
+ AC_MSG_ERROR([wrong deflateEnd search result: $ac_cv_search_deflateEnd])
+fi
+LIBS="$ac_at_save_LIBS"
+
+ac_inflate=inflate
+AC_SEARCH_LIBS([$ac_inflate], [$ac_z], [:], [:])
+if test x"$ac_cv_search_inflate" != x-lz; then
+ AC_MSG_ERROR([wrong inflate search result: $ac_cv_search_inflate])
+fi
+LIBS="$ac_at_save_LIBS"
+
+# Also test for symbols that don't (well, shouldn't) exist.
+# These should still set their cache variables!
+AC_SEARCH_LIBS([deflagrate], [z], [:], [:])
+if test x"$ac_cv_search_deflagrate" != xno; then
+ AC_MSG_ERROR([wrong deflagrate search result: $ac_cv_search_deflagrate])
+fi
+LIBS="$ac_at_save_LIBS"
+
+ac_defenestrate=defenestrate
+AC_SEARCH_LIBS([$ac_defenestrate], [z], [:], [:])
+if test x"$ac_cv_search_defenestrate" != xno; then
+ AC_MSG_ERROR([wrong defenestrate search result: $ac_cv_search_defenestrate])
+fi
+LIBS="$ac_at_save_LIBS"
+
+AC_SEARCH_LIBS([defoliate], [$ac_z], [:], [:])
+if test x"$ac_cv_search_defoliate" != xno; then
+ AC_MSG_ERROR([wrong defoliate search result: $ac_cv_search_defoliate])
+fi
+LIBS="$ac_at_save_LIBS"
+
+ac_infiltrate=infiltrate
+AC_SEARCH_LIBS([$ac_infiltrate], [$ac_z], [:], [:])
+if test x"$ac_cv_search_infiltrate" != xno; then
+ AC_MSG_ERROR([wrong infiltrate search result: $ac_cv_search_infiltrate])
+fi
+LIBS="$ac_at_save_LIBS"
+]])
+
# AC_SEARCH_LIBS (none needed)
# ----------------------------
-AT_CHECK_MACRO([AC_SEARCH_LIBS (none needed)],
-[
-AC_SEARCH_LIBS(printf, oser c ust,,
- [AC_MSG_ERROR([cannot find `printf'])])
-
-case "$ac_cv_search_printf" in
- -loser|-lust) AC_MSG_ERROR([jeez, $ac_cv_search_printf must be a cool library!]) ;;
- -lc) AC_MSG_ERROR([huh, you need to give -lc?])
-esac
-])
+# This test doesn't need to be nearly as thorough as the above; its
+# purpose is simply to ensure that when no library is needed,
+# AC_SEARCH_LIBS really does produce "none needed" as its result.
+AT_CHECK_MACRO([AC_SEARCH_LIBS (none needed)], [[
+# No library should be required to link with printf, but we throw
+# -lc in the search list so that it includes both libraries that
+# don't exist and libraries that probably do.
+AC_SEARCH_LIBS([printf], [oser c ust], [:], [:])
+
+if test x"$ac_cv_search_printf" != "xnone required"; then
+ AC_MSG_ERROR([wrong printf search result: $ac_cv_search_printf])
+fi
+]])
# AC_CHECK_DECLS
@@ -145,8 +241,8 @@ AT_CHECK_MACRO([AC_CHECK_DECLS],
]])
AC_LANG_WERROR
AC_CHECK_DECL([undeclared (char *)], [AS_EXIT([1])],, [[]])
- if test -z "$ac_c_werror_flag"; then
- AC_MSG_ERROR([ac_c_werror_flag overwritten])
+ if test -z "$ac_[]_AC_LANG_ABBREV[]_werror_flag"; then
+ AC_MSG_ERROR([ac_]_AC_LANG_ABBREV[_werror_flag overwritten])
fi
]],
[AT_CHECK_DEFINES(
@@ -390,7 +486,7 @@ AT_CHECK([grep 'yes.*member of.*yes_s' config.h], [], [ignore])
# AC_CHECK_ALIGNOF
# ----------------
-AT_CHECK_MACRO_CROSS([AC_CHECK_ALIGNOF],
+AT_CHECK_MACRO([AC_CHECK_ALIGNOF],
[[AC_CHECK_ALIGNOF(char)
AC_CHECK_ALIGNOF(charchar,
[[#include <stddef.h>
@@ -407,7 +503,7 @@ AC_CHECK_ALIGNOF(charcharchar)
# AC_CHECK_ALIGNOF struct
# -----------------------
-AT_CHECK_MACRO_CROSS([AC_CHECK_ALIGNOF struct],
+AT_CHECK_MACRO([AC_CHECK_ALIGNOF struct],
[[AC_CHECK_ALIGNOF([struct { char c; }])
AC_CHECK_ALIGNOF([struct nosuchstruct])
]],
@@ -419,7 +515,7 @@ AT_CHECK([[grep "#define ALIGNOF_STRUCT_NOSUCHSTRUCT 0" config.h]],
# AC_CHECK_SIZEOF
# ---------------
-AT_CHECK_MACRO_CROSS([AC_CHECK_SIZEOF],
+AT_CHECK_MACRO([AC_CHECK_SIZEOF],
[[AC_CHECK_SIZEOF(char)
AC_CHECK_SIZEOF(charchar,,
[[#include <stdio.h>
@@ -435,7 +531,7 @@ AC_CHECK_SIZEOF(charcharchar)
# AC_CHECK_SIZEOF struct
# ----------------------
-AT_CHECK_MACRO_CROSS([AC_CHECK_SIZEOF struct],
+AT_CHECK_MACRO([AC_CHECK_SIZEOF struct],
[[AC_C_CONST
AC_CHECK_SIZEOF([struct x], [], [struct x { char c; int x; };])
AC_CHECK_SIZEOF([const struct x], [], [struct x { const char *p; int x; };])
@@ -510,12 +606,16 @@ AT_CLEANUP
# --------------
# FIXME: To really test HAVE_AC_EXISTS2 and HAVE_AC_MISSING2 we need to
# open AH_TEMPLATE to `configure.ac', which is not yet the case.
-AT_CHECK_MACRO([AC_CHECK_FILES],
-[touch at-exists1 at-exists2
+# Don't use AT_CHECK_MACRO for this one because AC_CHECK_FILES can't be
+# used when cross compiling.
+
+AT_CHECK_CONFIGURE_AC([AC_CHECK_FILES],
+[[touch at-exists1 at-exists2
ac_exists2=at-exists2
ac_missing2=at-missing2
AC_CHECK_FILES(at-exists1 at-missing1 $ac_exists2 $ac_missing2)
-rm at-exists1 at-exists2],
+rm at-exists1 at-exists2]],
+[], [],
[AT_CHECK_DEFINES(
[#define HAVE_AT_EXISTS1 1
/* #undef HAVE_AT_MISSING1 */
@@ -803,9 +903,100 @@ AT_CLEANUP
## ------------------------------- ##
-AT_CHECK_MACRO([AC_SYS_RESTARTABLE_SYSCALLS], , ,[-W no-obsolete])
+AT_CHECK_MACRO([AC_SYS_RESTARTABLE_SYSCALLS], , ,[-W no-obsolete], [no-cross])
AT_CHECK_MACRO([AC_FUNC_SETVBUF_REVERSED], , ,[-W no-obsolete])
-AT_CHECK_MACRO([AC_FUNC_WAIT3], , ,[-W no-obsolete])
+AT_CHECK_MACRO([AC_FUNC_WAIT3], , ,[-W no-obsolete], [no-cross])
+
+
+## ------------------------------------- ##
+## Obsolete macros requiring arguments. ##
+## ------------------------------------- ##
+
+# These all wrap the macro under test in an AC_CACHE_CHECK and an
+# AC_DEFINE so the full verification machinery of AT_CHECK_MACRO is
+# effective. Caution: AT_CHECK_AU_MACRO expects that after an
+# autoupdate run, a naive grep will not find the old macro name
+# anywhere in the updated configure.ac, not even as part of a
+# longer identifier. (But it's case sensitive.)
+
+AT_CHECK_AU_MACRO([AC_TRY_CPP],
+[[AC_CACHE_CHECK([working ac_try_cpp], [ac_cv_ac_try_cpp_works], [
+ AC_TRY_CPP([
+ @%:@if 2 + 2 != 4
+ @%:@error "SEVEN!" /* in memory of Stanislaw Lem */
+ @%:@endif
+ ], [ac_cv_ac_try_cpp_works=yes],
+ [ac_cv_ac_try_cpp_works=no])
+])
+if test $ac_cv_ac_try_cpp_works = yes; then
+ AC_DEFINE([ac_try_cpp_works], [1], [label])
+fi
+]])
+
+
+AT_CHECK_AU_MACRO([AC_TRY_COMPILE],
+[[AC_CACHE_CHECK([working ac_try_compile], [ac_cv_ac_try_compile_works], [
+ AC_TRY_COMPILE([int variable;], [return variable;],
+ [ac_cv_ac_try_compile_works=yes],
+ [ac_cv_ac_try_compile_works=no])
+])
+if test $ac_cv_ac_try_compile_works = yes; then
+ AC_DEFINE([ac_try_compile_works], [1], [label])
+fi
+]])
+
+
+AT_CHECK_AU_MACRO([AC_TRY_LINK],
+[[AC_CACHE_CHECK([working ac_try_link], [ac_cv_ac_try_link_works], [
+ AC_TRY_LINK([@%:@include <stdio.h>], [return !feof(stdin);],
+ [ac_cv_ac_try_link_works=yes],
+ [ac_cv_ac_try_link_works=no])
+])
+if test $ac_cv_ac_try_link_works = yes; then
+ AC_DEFINE([ac_try_link_works], [1], [label])
+fi
+]])
+
+
+# Oddly enough, AC_COMPILE_CHECK was shorthand for AC_MSG_CHECKING +
+# AC_TRY_LINK, not AC_TRY_COMPILE. When not cached, this will print
+# checking for working ac_compile_check... checking for feof ... yes
+# but whatever.
+AT_CHECK_AU_MACRO([AC_COMPILE_CHECK],
+[[AC_CACHE_CHECK([working ac_compile_check], [ac_cv_ac_compile_check_works], [
+ AC_COMPILE_CHECK([feof], [@%:@include <stdio.h>], [return !feof(stdin);],
+ [ac_cv_ac_compile_check_works=yes],
+ [ac_cv_ac_compile_check_works=no])
+])
+if test $ac_cv_ac_compile_check_works = yes; then
+ AC_DEFINE([ac_compile_check_works], [1], [label])
+fi
+]])
+
+
+AT_CHECK_AU_MACRO([AC_TRY_RUN],
+[[AC_CACHE_CHECK([working ac_try_run], [ac_cv_ac_try_run_works], [
+ AC_TRY_RUN([int main(void) { return 0; }],
+ [ac_cv_ac_try_run_works=yes],
+ [ac_cv_ac_try_run_works=no],
+ [ac_cv_ac_try_run_works=yes]) # cross compile, assume it works
+])
+if test $ac_cv_ac_try_run_works = yes; then
+ AC_DEFINE([ac_try_run_works], [1], [label])
+fi
+]])
+
+
+# For purpose of this test, we don't care whether these libraries
+# exist (as long as the result is consistent between C and C++)
+# but we _do_ need to make sure that autoupdate correctly handles
+# AC_HAVE_LIBRARY's acceptance of "-lfoo" and "libfoo.a" as the
+# LIBRARY argument, where AC_CHECK_LIB only takes "foo".
+AT_CHECK_AU_MACRO([AC_HAVE_LIBRARY],
+[[AC_HAVE_LIBRARY([alice])
+AC_HAVE_LIBRARY([-lbob])
+AC_HAVE_LIBRARY([libmallory.a])
+]])
## ----------------------------------------- ##