* lib/autoconf/headers.m4 (AC_CHECK_HEADER): Use _AC_CHECK_HEADER_COMPILE
by default. Continue to use _AC_CHECK_HEADER_PREPROC if fourth arg is '-'.
(_AC_CHECK_HEADER_PREPROC): Issue a deprecation warning.
(_AC_CHECK_HEADER_MONGREL, _AC_CHECK_HEADER_MONGREL_BODY): Remove.
* tests/local.at (AT_CHECK_M4): Support 'stderr' as fourth argument.
* tests/c.at, tests/semantics.at: Update uses of AC_CHECK_HEADER(S).
* doc/autoconf.texi, NEWS: Document change.
Signed-off-by: Zack Weinberg <[email protected]>
---
NEWS | 10 ++++
doc/autoconf.texi | 106 ++++++++++++++++++++++-----------------------
lib/autoconf/headers.m4 | 109 +++++++++--------------------------------------
tests/c.at | 28 +++++++++---
tests/local.at | 5 +-
tests/semantics.at | 17 ++++---
6 files changed, 115 insertions(+), 160 deletions(-)
diff --git a/NEWS b/NEWS
index de9d915..1378388 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,16 @@ GNU Autoconf NEWS - User visible changes.
echo. Macros AS_ECHO and AS_ECHO_N now expand unconditionally to
'printf "%s\n"' and 'printf %s'.
+** AC_CHECK_HEADER and AC_CHECK_HEADERS now default to doing only a
+ compilation test. This completes the transition from preprocessor-
+ based header tests begun in Autoconf 2.56.
+
+ The double test that was the default since Autoconf 2.64 is no
+ longer available. You can still request a preprocessor-only test
+ by specifying '-' as the fourth argument to either macro, but this
+ is now deprecated. If you really need that behavior use
+ AC_PREPROC_IFELSE.
+
** Macros
- New macro AC_C__GENERIC.
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 26e7b17..a68dc07 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -6253,26 +6253,21 @@ commands @var{action-if-found}, otherwise execute
header file is available, consider using @code{AC_CHECK_HEADERS}
instead.
-@var{includes} is decoded to determine the appropriate include
-directives. If omitted or empty, @file{configure} will check for both header
-existence (with the preprocessor) and usability (with the compiler),
-using @code{AC_INCLUDES_DEFAULT} for the compile test. If
-there is a discrepancy between the results, a warning is issued to the
-user, and the compiler results are favored (@pxref{Present But
-Cannot Be Compiled}). In general, favoring the compiler results means
-that a header will be treated as not found even though the file exists,
-because you did not provide enough prerequisites.
+@var{includes} should be the appropriate @dfn{prerequisite} code, i.e.@:
+whatever might be required to appear above
+@samp{#include <@var{header-file}>} for it to compile without error.
+This can be anything, but will normally be additional @samp{#include}
+directives. If @var{includes} is omitted or empty, @file{configure} will
+use the contents of the macro @code{AC_INCLUDES_DEFAULT}.
+@xref{Default Includes}.
-Providing a non-empty @var{includes} argument allows the code to provide
-any prerequisites prior to including the header under test; it is common
-to use the argument @code{AC_INCLUDES_DEFAULT} (@pxref{Default
-Includes}). With an explicit fourth argument, no preprocessor test is
-needed. As a special case, an @var{includes} of exactly @samp{-}
-triggers the older preprocessor check, which merely determines existence
-of the file in the preprocessor search path; this should only be used as
-a last resort (it is safer to determine the actual prerequisites and
-perform a compiler check, or else use @code{AC_PREPROC_IFELSE} to make
-it obvious that only a preprocessor check is desired).
+This macro used to check only for the @emph{presence} of a header, not
+whether its contents were acceptable to the compiler. Some older
+@command{configure} scripts rely on this behavior, so it is still
+available by specifying @samp{-} as @var{includes}. This mechanism is
+deprecated as of Autoconf 2.70; situations where a preprocessor-only
+check is required should use @code{AC_PREPROC_IFELSE}.
+@xref{Running the Preprocessor}.
This macro caches its result in the @code{ac_cv_header_@var{header-file}}
variable, with characters not suitable for a variable name mapped to
@@ -6303,47 +6298,49 @@ variable, with characters not suitable for a variable name mapped to
underscores.
@end defmac
-Previous versions of Autoconf merely checked whether the header was
-accepted by the preprocessor. This was changed because the old test was
-inappropriate for typical uses. Headers are typically used to compile,
-not merely to preprocess, and the old behavior sometimes accepted
-headers that clashed at compile-time (@pxref{Present But Cannot Be
-Compiled}). If you need to check whether a header is preprocessable,
-you can use @code{AC_PREPROC_IFELSE} (@pxref{Running the Preprocessor}).
+@defmac AC_CHECK_HEADERS_ONCE (@var{header-file}@dots{})
+@acindex{CHECK_HEADERS_ONCE}
+@cvindex HAVE_@var{header}
+For each given system header file @var{header-file} in the
+blank-separated argument list that exists, define
+@code{HAVE_@var{header-file}} (in all capitals).
-Actually requiring a header to compile improves the robustness of the
-test, but it also requires
-that you make sure that headers that must be included before the
-@var{header-file} be part of the @var{includes}, (@pxref{Default
-Includes}). If looking for @file{bar.h}, which requires that
-@file{foo.h} be included before if it exists, we suggest the following
-scheme:
+If you do not need the full power of @code{AC_CHECK_HEADERS}, this
+variant generates smaller, faster @command{configure} files. All
+headers passed to @code{AC_CHECK_HEADERS_ONCE} are checked for in one
+pass, early during the @command{configure} run. The checks cannot be
+conditionalized, you cannot specify an @var{action-if-found} or
+@var{action-if-not-found}, and @code{AC_INCLUDES_DEFAULT} is always used
+for the prerequisites.
+@end defmac
-@verbatim
+In previous versions of Autoconf, these macros merely checked whether
+the header was accepted by the preprocessor. This was changed because
+the old test was inappropriate for typical uses. Headers are typically
+used to compile, not merely to preprocess, and the old behavior
+sometimes accepted headers that clashed at compile-time
+(@pxref{Present But Cannot Be Compiled}). If for some reason it is
+inappropriate to check whether a header is compilable, you should use
+@code{AC_PREPROC_IFELSE} (@pxref{Running the Preprocessor}) instead of
+these macros.
+
+Requiring each header to compile improves the robustness of the test,
+but it also requires you to make sure that the @var{includes} are
+correct. Most system headers nowadays make sure to @code{#include}
+whatever they require, or else have their dependencies satisfied by
+@code{AC_INCLUDES_DEFAULT} (@pxref{Default Includes}), but
+@pxref{Header Portability}, for known exceptions. In general, if you
+are looking for @file{bar.h}, which requires that @file{foo.h} be
+included first if it exists, you should do something like this:
+
+@example
AC_CHECK_HEADERS([foo.h])
AC_CHECK_HEADERS([bar.h], [], [],
[#ifdef HAVE_FOO_H
# include <foo.h>
#endif
])
-@end verbatim
-
-The following variant generates smaller, faster @command{configure}
-files if you do not need the full power of @code{AC_CHECK_HEADERS}.
-
-@defmac AC_CHECK_HEADERS_ONCE (@var{header-file}@dots{})
-@acindex{CHECK_HEADERS_ONCE}
-@cvindex HAVE_@var{header}
-For each given system header file @var{header-file} in the
-blank-separated argument list that exists, define
-@code{HAVE_@var{header-file}} (in all capitals).
-This is a once-only variant of @code{AC_CHECK_HEADERS}. It generates the
-checking code at most once, so that @command{configure} is smaller and
-faster; but the checks cannot be conditionalized and are always done once,
-early during the @command{configure} run. Thus, this macro is only safe
-for checking headers that do not have prerequisites beyond what
-@code{AC_INCLUDES_DEFAULT} provides.
-@end defmac
+@end example
@node Declarations
@section Declarations
@@ -25982,7 +25979,8 @@ elsewhere.
The transition began with Autoconf 2.56. As of Autoconf 2.64 both
checks are performed, and @command{configure} complains loudly if the
compiler and the preprocessor do not agree. However, only the compiler
-result is considered.
+result is considered. As of Autoconf 2.70, only the compiler check is
+performed.
Consider the following example:
@@ -26032,7 +26030,7 @@ checking for pi.h... no
@end smallexample
@noindent
-The proper way the handle this case is using the fourth argument
+The proper way to handle this case is using the fourth argument
(@pxref{Generic Headers}):
@example
diff --git a/lib/autoconf/headers.m4 b/lib/autoconf/headers.m4
index 7f5dbce..0474e63 100644
--- a/lib/autoconf/headers.m4
+++ b/lib/autoconf/headers.m4
@@ -46,101 +46,20 @@
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
# [INCLUDES])
# ---------------------------------------------------------
-# We are slowly moving to checking headers with the compiler instead
-# of the preproc, so that we actually learn about the usability of a
-# header instead of its mere presence. But since users are used to
-# the old semantics, they check for headers in random order and
-# without providing prerequisite headers. This macro implements the
-# transition phase, and should be cleaned up latter to use compilation
-# only.
-#
-# If INCLUDES is empty, then check both via the compiler and preproc.
-# If the results are different, issue a warning, but keep the preproc
-# result.
-#
-# If INCLUDES is `-', keep only the old semantics.
-#
-# If INCLUDES is specified and different from `-', then use the new
-# semantics only.
+# This used to check for headers using the preprocessor only, but we
+# have now switched to running a full compilation, so that we actually
+# learn about the usability of a header instead of its mere presence.
+# The old behavior is still available by specifying `-' as the
+# INCLUDES (but this triggers a deprecation warning).
#
# The m4_indir allows for fewer expansions of $@.
AC_DEFUN([AC_CHECK_HEADER],
[m4_indir(m4_case([$4],
- [], [[_AC_CHECK_HEADER_MONGREL]],
[-], [[_AC_CHECK_HEADER_PREPROC]],
[[_AC_CHECK_HEADER_COMPILE]]), $@)
])# AC_CHECK_HEADER
-# _AC_CHECK_HEADER_MONGREL_BODY
-# -----------------------------
-# Shell function body for _AC_CHECK_HEADER_MONGREL
-m4_define([_AC_CHECK_HEADER_MONGREL_BODY],
-[ AS_LINENO_PUSH([$[]1])
- AS_VAR_SET_IF([$[]3],
- [AC_CACHE_CHECK([for $[]2], [$[]3], [])],
- [# Is the header compilable?
-AC_MSG_CHECKING([$[]2 usability])
-AC_COMPILE_IFELSE([AC_LANG_SOURCE([$[]4
-@%:@include <$[]2>])],
- [ac_header_compiler=yes],
- [ac_header_compiler=no])
-AC_MSG_RESULT([$ac_header_compiler])
-
-# Is the header present?
-AC_MSG_CHECKING([$[]2 presence])
-AC_PREPROC_IFELSE([AC_LANG_SOURCE([@%:@include <$[]2>])],
- [ac_header_preproc=yes],
- [ac_header_preproc=no])
-AC_MSG_RESULT([$ac_header_preproc])
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_[]_AC_LANG_ABBREV[]_preproc_warn_flag in #((
- yes:no: )
- AC_MSG_WARN([$[]2: accepted by the compiler, rejected by the preprocessor!])
- AC_MSG_WARN([$[]2: proceeding with the compiler's result])
- ;;
- no:yes:* )
- AC_MSG_WARN([$[]2: present but cannot be compiled])
- AC_MSG_WARN([$[]2: check for missing prerequisite headers?])
- AC_MSG_WARN([$[]2: see the Autoconf documentation])
- AC_MSG_WARN([$[]2: section "Present But Cannot Be Compiled"])
- AC_MSG_WARN([$[]2: proceeding with the compiler's result])
-m4_ifset([AC_PACKAGE_BUGREPORT],
-[m4_n([( AS_BOX([Report this to ]AC_PACKAGE_BUGREPORT)
- ) | sed "s/^/$as_me: WARNING: /" >&2])])dnl
- ;;
-esac
- AC_CACHE_CHECK([for $[]2], [$[]3],
- [AS_VAR_SET([$[]3], [$ac_header_compiler])])])
- AS_LINENO_POP
-])#_AC_CHECK_HEADER_MONGREL_BODY
-
-# _AC_CHECK_HEADER_MONGREL(HEADER-FILE,
-# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
-# [INCLUDES = DEFAULT-INCLUDES])
-# ------------------------------------------------------------------
-# Check using both the compiler and the preprocessor. If they disagree,
-# warn, and the preproc wins.
-#
-# This is not based on _AC_CHECK_HEADER_COMPILE and _AC_CHECK_HEADER_PREPROC
-# because it obfuscate the code to try to factor everything, in particular
-# because of the cache variables, and the `checking ...' messages.
-AC_DEFUN([_AC_CHECK_HEADER_MONGREL],
-[AC_REQUIRE_SHELL_FN([ac_fn_]_AC_LANG_ABBREV[_check_header_mongrel],
- [AS_FUNCTION_DESCRIBE([ac_fn_]_AC_LANG_ABBREV[_check_header_mongrel],
- [LINENO HEADER VAR INCLUDES],
- [Tests whether HEADER exists, giving a warning if it cannot be compiled
- using the include files in INCLUDES and setting the cache variable VAR
- accordingly.])],
- [$0_BODY])]dnl
-[AS_VAR_PUSHDEF([ac_Header], [ac_cv_header_$1])]dnl
-[ac_fn_[]_AC_LANG_ABBREV[]_check_header_mongrel ]dnl
-["$LINENO" "$1" "ac_Header" "AS_ESCAPE([AC_INCLUDES_DEFAULT([$4])], [""])"
-AS_VAR_IF([ac_Header], [yes], [$2], [$3])
-AS_VAR_POPDEF([ac_Header])])# _AC_CHECK_HEADER_MONGREL
-
-
# _AC_CHECK_HEADER_COMPILE_BODY
# -----------------------------
# Shell function body for _AC_CHECK_HEADER_COMPILE
@@ -154,6 +73,7 @@ m4_define([_AC_CHECK_HEADER_COMPILE_BODY],
AS_LINENO_POP
])# _AC_CHECK_HEADER_COMPILE_BODY
+
# _AC_CHECK_HEADER_COMPILE(HEADER-FILE,
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
# [INCLUDES = DEFAULT-INCLUDES])
@@ -172,6 +92,7 @@ AC_DEFUN([_AC_CHECK_HEADER_COMPILE],
AS_VAR_IF([ac_Header], [yes], [$2], [$3])
AS_VAR_POPDEF([ac_Header])])# _AC_CHECK_HEADER_COMPILE
+
# _AC_CHECK_HEADER_PREPROC_BODY
# -----------------------------
# Shell function body for _AC_CHECK_HEADER_PREPROC.
@@ -185,13 +106,16 @@ m4_define([_AC_CHECK_HEADER_PREPROC_BODY],
])# _AC_CHECK_HEADER_PREPROC_BODY
-
# _AC_CHECK_HEADER_PREPROC(HEADER-FILE,
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# --------------------------------------------------------------
# Check the preprocessor accepts HEADER-FILE.
AC_DEFUN([_AC_CHECK_HEADER_PREPROC],
-[AC_REQUIRE_SHELL_FN([ac_fn_]_AC_LANG_ABBREV[_check_header_preproc],
+[AC_DIAGNOSE([obsolete], [Checking for headers with the preprocessor only
+is deprecated. Specify prerequisite code to AC_CHECK_HEADER
+instead of using fourth argument `-'. (Many headers need no
+prerequisites.)])dnl
+AC_REQUIRE_SHELL_FN([ac_fn_]_AC_LANG_ABBREV[_check_header_preproc],
[AS_FUNCTION_DESCRIBE([ac_fn_]_AC_LANG_ABBREV[_check_header_preproc],
[LINENO HEADER VAR],
[Tests whether HEADER is present, setting the cache variable VAR accordingly.])],
@@ -202,6 +126,7 @@ AS_VAR_IF([ac_Header], [yes], [$2], [$3])
AS_VAR_POPDEF([ac_Header])dnl
])# _AC_CHECK_HEADER_PREPROC
+
# _AC_CHECK_HEADER_OLD(HEADER-FILE, [ACTION-IF-FOUND],
# [ACTION-IF-NOT-FOUND])
# _AC_CHECK_HEADER_NEW(HEADER-FILE, [ACTION-IF-FOUND],
@@ -222,6 +147,14 @@ AC_DEFUN([_AC_CHECK_HEADER_NEW],
You should use AC_CHECK_HEADER with a fourth argument.])]dnl
[_AC_CHECK_HEADER_COMPILE($@)])
+# _AC_CHECK_HEADER_MONGREL(HEADER-FILE,
+# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# ------------------------------------------------------------------
+# In case anyone used this undocumented macro. Map to the _PREPROC
+# semantics to minimize the chance of breaking anything.
+AU_DEFUN([_AC_CHECK_HEADER_MONGREL],
+ [AC_CHECK_HEADER([$1], [$2], [$3], [-])])
+
# _AH_CHECK_HEADER(HEADER-FILE)
# -----------------------------
diff --git a/tests/c.at b/tests/c.at
index 2e8f149..b1d4644 100644
--- a/tests/c.at
+++ b/tests/c.at
@@ -123,8 +123,12 @@ test "x$ac_c_preproc_warn_flag" = xyes &&
CPP="./mycpp $CPP"
# Exercise CPP.
-AC_CHECK_HEADERS(stdio.h autoconf_io.h, [], [], [-])]])
+AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>]])],
+ [AC_DEFINE([HAVE_STDIO_H], [1], [Define if you have stdio.h])])
+AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <autoconf_io.h>]])],
+ [AC_DEFINE([HAVE_AUTOCONF_IO_H], [1], [Define if you have autoconf_io.h])])
+]])
AT_CHECK_DEFINES(
[/* #undef HAVE_AUTOCONF_IO_H */
#define HAVE_STDIO_H 1
@@ -139,14 +143,14 @@ AT_CLEANUP
AT_SETUP([AC_PROG_CPP without warnings])
-# Ignore if /lib/cpp doesn't work
-AT_CHECK([[echo '#include <stdio.h>' | /lib/cpp || exit 77]],
+# Ignore if the cpp in $PATH doesn't work
+AT_CHECK([[echo '#include <stdio.h>' | cpp || exit 77]],
[], [ignore], [ignore])
# A cpp which exit status is meaningless.
AT_DATA([mycpp],
[[#! /bin/sh
-/lib/cpp "$@"
+cpp "$@"
exit 0
]])
@@ -159,7 +163,11 @@ test "x$ac_c_preproc_warn_flag" != xyes &&
AC_MSG_ERROR([failed to detect preprocessor warning option])
# Exercise CPP.
-AC_CHECK_HEADERS(stdio.h autoconf_io.h, [], [], [-])]])
+AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>]])],
+ [AC_DEFINE([HAVE_STDIO_H], [1], [Define if you have stdio.h])])
+AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <autoconf_io.h>]])],
+ [AC_DEFINE([HAVE_AUTOCONF_IO_H], [1], [Define if you have autoconf_io.h])])
+]])
AT_CHECK_DEFINES(
[/* #undef HAVE_AUTOCONF_IO_H */
@@ -179,8 +187,8 @@ AT_CLEANUP
AT_SETUP([AC_PROG_CPP via CC])
-# Ignore if /lib/cpp doesn't work
-AT_CHECK([[echo '#include <stdio.h>' | /lib/cpp || exit 77]],
+# Ignore if the cpp in $PATH doesn't work
+AT_CHECK([[echo '#include <stdio.h>' | cpp || exit 77]],
[], [ignore], [ignore])
AT_DATA([mycc],
@@ -204,7 +212,11 @@ test "$CPP" != "$CC -E" &&
AC_MSG_ERROR([error messages on stderr cause the preprocessor selection to fail])
# Exercise CPP.
-AC_CHECK_HEADERS(stdio.h autoconf_io.h, [], [], [-])]])
+AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <stdio.h>]])],
+ [AC_DEFINE([HAVE_STDIO_H], [1], [Define if you have stdio.h])])
+AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <autoconf_io.h>]])],
+ [AC_DEFINE([HAVE_AUTOCONF_IO_H], [1], [Define if you have autoconf_io.h])])
+]])
AT_CHECK_DEFINES(
[/* #undef HAVE_AUTOCONF_IO_H */
diff --git a/tests/local.at b/tests/local.at
index 97a1e1d..47501bf 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -113,13 +113,14 @@ m4_define([AT_CHECK_M4],
[AT_CHECK([$1], [$2], [$3],
m4_case([$4], [], [], [ignore], [ignore], [stderr]))
m4_case([$4], [], [], [ignore], [],
-[AT_CHECK([[sed 's/^[^:]*m4[-.ex0-9]*: *\([^:]*:\) *\([0-9][0-9]*: \)/m4:\1\2/
+[AT_CHECK([[mv stderr stderr-raw &&
+ sed 's/^[^:]*m4[-.ex0-9]*: *\([^:]*:\) *\([0-9][0-9]*: \)/m4:\1\2/
s/^\([^:]*:\) *\([0-9][0-9]*:\)[^:]*m4[-.ex0-9]*: /m4:\1\2 /
s/: C\(annot open \)\([^`:]*\):/: c\1`\2'\'':/
s/: include:\( cannot open\)/:\1/
s/^autom4te: [^ ]*m4[.ex]* /autom4te: m4 /
s/ (E[A-Z]*)$//
- ' stderr >&2]], [0], [], [$4])])
+ ' stderr-raw >&2]], [0], [], [$4])])
])
# AT_CHECK_AUTOM4TE(FLAGS, [EXIT-STATUS = 0], STDOUT, STDERR)
diff --git a/tests/semantics.at b/tests/semantics.at
index c0b78a1..cc8b953 100644
--- a/tests/semantics.at
+++ b/tests/semantics.at
@@ -219,13 +219,7 @@ AT_DATA([autoconf_io.h],
AT_CONFIGURE_AC([AC_CHECK_HEADERS(stdio.h autoconf_io.h)])
AT_CHECK_AUTOCONF([-W obsolete])
AT_CHECK_AUTOHEADER
-AT_CHECK_CONFIGURE([CPPFLAGS=-I.], [0], [ignore],
-[configure: WARNING: autoconf_io.h: present but cannot be compiled
-configure: WARNING: autoconf_io.h: check for missing prerequisite headers?
-configure: WARNING: autoconf_io.h: see the Autoconf documentation
-configure: WARNING: autoconf_io.h: section "Present But Cannot Be Compiled"
-configure: WARNING: autoconf_io.h: proceeding with the compiler's result
-])
+AT_CHECK_CONFIGURE([CPPFLAGS=-I.])
AT_CHECK_ENV
AT_CHECK_DEFINES(
[/* #undef HAVE_AUTOCONF_IO_H */
@@ -251,7 +245,14 @@ AT_DATA([header2.h],
AT_CONFIGURE_AC([AC_CHECK_HEADERS(header2.h, [], [], -)])
-AT_CHECK_AUTOCONF([-W obsolete])
+AT_CHECK_AUTOCONF([-W obsolete], [], [], [stderr])
+AT_CHECK([[grep '^configure\.ac' stderr]], [0],
+[configure.ac:4: warning: Checking for headers with the preprocessor only
+configure.ac:4: is deprecated. Specify prerequisite code to AC_CHECK_HEADER
+configure.ac:4: instead of using fourth argument `-'. (Many headers need no
+configure.ac:4: prerequisites.)
+configure.ac:4: the top level
+])
AT_CHECK_AUTOHEADER
AT_CHECK_CONFIGURE([CPPFLAGS=-I.])
AT_CHECK_ENV