mirror of
git://git.sv.gnu.org/autoconf
synced 2025-02-17 14:01:27 +08:00
A patch was recently proposed for GNU libc to make *all* processes start up with file descriptors 0, 1, and 2 guaranteed to be open. Part of the rationale for this patch was that configure scripts fail catastrophically if these fds are closed, even if you just want to run --help or --version, e.g. $ ./configure --version <&-; echo $? ./configure: line 555: 0: Bad file descriptor 1 configure scripts cannot rely on behavior specific to GNU libc, so whether or not that patch gets committed, it makes sense for us to make configure scripts robust against being started up with closed stdin/stdout/stderr. This patch adds code to ensure fds 0, 1, and 2 are open, early in _AS_SHELL_SANITIZE. It uses a construct, ‘(exec 3>&n)’, that’s known not to work in very old shells, but that’s OK because those shells will be rejected by _AS_DETECT_BETTER_SHELL anyway. The worst-case scenario is that the “This script requires a shell more modern than all the shells I found on your system” error message won’t get printed. When these fds are found not to be open, we open them on /dev/null, in the normal I/O direction (0 for reading, 1 and 2 for writing). There is a case for opening them in the *opposite* direction so that, for instance, writes to fd 1 will fail when fd 1 started out closed. However, that would expose latent bugs that I think should be dealt with *after* 2.70. (See Savannah bug #110300 for more detail.) I also took the opportunity to rationalize the order of operations in _AS_SHELL_SANITIZE a little. All the special shell and environment variables that we care about are dealt with immediately after AS_BOURNE_COMPATIBLE, and _AS_PATH_SEPARATOR_PREPARE happens immediately before the first use of _AS_PATH_WALK. * lib/m4sugar/m4sh.m4 (_AS_ENSURE_STANDARD_FDS): New macro. (_AS_SHELL_SANITIZE): Move the “Unset variables that we do not need” and “NLS nuisances” blocks immediately after setting IFS; merge the unsetting of CDPATH into the main unsetting loop; move invocation of _AS_PATH_SEPARATOR_PREPARE to immediately above the “Find who we are” block; invoke _AS_ENSURE_STANDARD_FDS immediately before _AS_PATH_SEPARATOR_PREPARE. * tests/base.at (configure with closed standard fds): New test. * tests/torture.at (--help and --version in unwritable directory): New test.
922 lines
24 KiB
Plaintext
922 lines
24 KiB
Plaintext
# -*- Autotest -*-
|
|
|
|
AT_BANNER([Autoconf base layer.])
|
|
|
|
# Copyright (C) 2000-2001, 2003, 2005-2017, 2020 Free Software
|
|
# Foundation, Inc.
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
## ------------------------------- ##
|
|
## AC_REQUIRE: topological sort.. ##
|
|
## ------------------------------- ##
|
|
|
|
# Check that dependencies are always properly honored.
|
|
|
|
AT_SETUP([AC_REQUIRE: topological sort])
|
|
AT_KEYWORDS([m4@&t@_require])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[define([REQUIRE_AND_CHECK],
|
|
[AC_REQUIRE([$1])
|
|
test -z "$m4@&t@_translit([$1], [A-Z], [a-z])" && AS_EXIT(1)])
|
|
|
|
AC_DEFUN([TEST1],
|
|
[REQUIRE_AND_CHECK([TEST2a])
|
|
REQUIRE_AND_CHECK([TEST2b])
|
|
test1=set])
|
|
|
|
AC_DEFUN([TEST2a],
|
|
[test2a=set])
|
|
|
|
AC_DEFUN([TEST2b],
|
|
[REQUIRE_AND_CHECK([TEST3])
|
|
test2b=set])
|
|
|
|
AC_DEFUN([TEST3],
|
|
[REQUIRE_AND_CHECK([TEST2a])
|
|
test3=set])
|
|
|
|
AS@&t@_INIT
|
|
|
|
TEST1
|
|
test -z "$test1" &&
|
|
AC_MSG_ERROR([\$test1 is empty])
|
|
AS_EXIT(0)
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([], [0], [],
|
|
[[trailer.m4: warning: AC_INIT was never used
|
|
trailer.m4: warning: AC_OUTPUT was never used
|
|
]])
|
|
AT_CHECK_CONFIGURE
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## --------------------------- ##
|
|
## AC_REQUIRE: error message. ##
|
|
## --------------------------- ##
|
|
|
|
# Check that the message mentions AC_DEFUN, not m4_defun.
|
|
|
|
AT_SETUP([AC_REQUIRE: error message])
|
|
AT_KEYWORDS([m4@&t@_require])
|
|
AT_DATA([configure.ac],
|
|
[[AC_REQUIRE([AC_PROG_CC])
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([], [1], [],
|
|
[[configure.ac:1: error: AC_REQUIRE(AC_PROG_CC): cannot be used outside of an AC_DEFUN'd macro
|
|
configure.ac:1: the top level
|
|
autom4te: m4 failed with exit status: 1
|
|
]])
|
|
AT_CLEANUP
|
|
|
|
|
|
## ----------------------------------------------- ##
|
|
## AC_REQUIRE and AC_DEFUN_ONCE: Require, expand. ##
|
|
## ----------------------------------------------- ##
|
|
|
|
AT_SETUP([AC_REQUIRE & AC_DEFUN_ONCE: [Require, expand]])
|
|
AT_KEYWORDS([m4@&t@_require m4@&t@_require_once])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_DEFUN([TEST],
|
|
[AC_REQUIRE([MULTI_TEST])
|
|
AC_REQUIRE([SINGLE_TEST])])
|
|
|
|
AC_DEFUN([MULTI_TEST],
|
|
[multi_test=".$multi_test"])
|
|
|
|
AC_DEFUN_ONCE([SINGLE_TEST],
|
|
[single_test=".$single_test"])
|
|
|
|
AS@&t@_INIT
|
|
|
|
TEST
|
|
TEST
|
|
MULTI_TEST
|
|
MULTI_TEST
|
|
SINGLE_TEST
|
|
SINGLE_TEST
|
|
|
|
case $multi_test:$single_test in
|
|
...:. ) AS_EXIT(0);;
|
|
...:* ) AC_MSG_ERROR([DEFUN_ONCE is broken]);;
|
|
*:. ) AC_MSG_ERROR([DEFUN is broken (Wow, congrats!)]);;
|
|
esac
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([], 0, [],
|
|
[[trailer.m4: warning: AC_INIT was never used
|
|
trailer.m4: warning: AC_OUTPUT was never used
|
|
]])
|
|
|
|
AT_CHECK_CONFIGURE
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
|
|
## ----------------------------------------------- ##
|
|
## AC_REQUIRE and AC_DEFUN_ONCE: Expand, require. ##
|
|
## ----------------------------------------------- ##
|
|
|
|
AT_SETUP([AC_REQUIRE & AC_DEFUN_ONCE: [Expand, require]])
|
|
AT_KEYWORDS([m4@&t@_require m4@&t@_require_once])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_DEFUN([TEST],
|
|
[AC_REQUIRE([MULTI_TEST])
|
|
AC_REQUIRE([SINGLE_TEST])])
|
|
|
|
AC_DEFUN([MULTI_TEST],
|
|
[multi_test=".$multi_test"])
|
|
|
|
AC_DEFUN_ONCE([SINGLE_TEST],
|
|
[single_test=".$single_test"])
|
|
|
|
AS@&t@_INIT
|
|
|
|
MULTI_TEST
|
|
MULTI_TEST
|
|
SINGLE_TEST
|
|
SINGLE_TEST
|
|
TEST
|
|
TEST
|
|
|
|
case $multi_test:$single_test in
|
|
..:. ) AS_EXIT(0);;
|
|
..:* ) AC_MSG_ERROR([DEFUN_ONCE is broken]);;
|
|
*:. ) AC_MSG_ERROR([DEFUN is broken (Wow, congrats!)]);;
|
|
* ) AC_MSG_ERROR([received `$multi_test:$single_test']);;
|
|
esac
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([], 0, [],
|
|
[[trailer.m4: warning: AC_INIT was never used
|
|
trailer.m4: warning: AC_OUTPUT was never used
|
|
]])
|
|
AT_CHECK_CONFIGURE
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
|
|
## ------------------------- ##
|
|
## AC_REQUIRE & AC_PROVIDE. ##
|
|
## ------------------------- ##
|
|
|
|
AT_SETUP([AC_REQUIRE & AC_PROVIDE])
|
|
AT_KEYWORDS([m4@&t@_require])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_DEFUN([TEST],
|
|
[AC_REQUIRE([INNER_TEST])])
|
|
|
|
AC_DEFUN([INNER_TEST],
|
|
[inner_test=".$inner_test"])
|
|
|
|
AS@&t@_INIT
|
|
|
|
AC_PROVIDE([INNER_TEST])
|
|
TEST
|
|
|
|
case $inner_test in
|
|
"" ) AS_EXIT(0);;
|
|
* ) AC_MSG_ERROR([received `$inner_test']);;
|
|
esac
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([], 0, [],
|
|
[[trailer.m4: warning: AC_INIT was never used
|
|
trailer.m4: warning: AC_OUTPUT was never used
|
|
]])
|
|
AT_CHECK_CONFIGURE
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## -------- ##
|
|
## AC_INIT. ##
|
|
## -------- ##
|
|
|
|
# Make sure AC_INIT sets PACKAGE_TARNAME properly.
|
|
|
|
AT_SETUP([AC_INIT])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU fu], [1.0], [bug-fu@gnu.org])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF
|
|
AT_CHECK_CONFIGURE([-q])
|
|
|
|
# Ensure we get the expected definition:
|
|
AT_CHECK([grep "^PACKAGE_TARNAME='fu'\$" configure], [], [ignore])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ------------------------------------- ##
|
|
## AC_INIT with unusual version strings. ##
|
|
## ------------------------------------- ##
|
|
|
|
AT_SETUP([AC_INIT with unusual version strings])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU String++ with spaces (foo)],
|
|
[2.48++ (2010-07-03)],
|
|
[[https://example.com/?a=b&c=d#e]],
|
|
[string++],
|
|
[[https://example.com/?f=g&h=i%2fj#42]])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
if echo 'ab*c' | grep -F 'ab*c' >/dev/null 2>&1; then
|
|
FGREP="grep -F"
|
|
else
|
|
FGREP=fgrep
|
|
fi
|
|
|
|
AT_CHECK_AUTOCONF([-Werror])
|
|
AT_CHECK_CONFIGURE([-q])
|
|
AT_CHECK_CONFIGURE([--help], [], [stdout])
|
|
AT_CHECK([[$FGREP 'com/?a=b&c=d#e' stdout]], [], [ignore])
|
|
AT_CHECK([[$FGREP 'com/?f=g&h=i%2fj#42' stdout]], [], [ignore])
|
|
AT_CHECK_CONFIGURE([--version], [], [stdout])
|
|
AT_CHECK([$FGREP 'GNU String++ with spaces (foo)' stdout], [], [ignore])
|
|
AT_CHECK([$FGREP '2.48++ (2010-07-03)' stdout], [], [ignore])
|
|
|
|
AT_CHECK([./config.status --help], [], [stdout])
|
|
AT_CHECK([[$FGREP 'com/?a=b&c=d#e' stdout]], [], [ignore])
|
|
AT_CHECK([./config.status --version], [], [stdout])
|
|
AT_CHECK([$FGREP 'GNU String++ with spaces (foo)' stdout], [], [ignore])
|
|
AT_CHECK([$FGREP '2.48++ (2010-07-03)' stdout], [], [ignore])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU "String++"],
|
|
[2.48], [https://example.com/], [string++])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
|
|
AT_CHECK([grep 'AC_INIT: not a literal: ' stderr], [], [ignore])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU String++],
|
|
['codename' 2.48], [https://example.com/], [string++])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
|
|
AT_CHECK([grep 'AC_INIT: not a literal: ' stderr], [], [ignore])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU
|
|
String++], [2.48], [https://example.com/], [string++])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([-Werror])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU String++], ['2.48'], [https://example.com], [string++])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
|
|
AT_CHECK([grep 'AC_INIT: not a literal: ' stderr], [], [ignore])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU String++], [2.48], ['https://example.com'], [string++])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
|
|
AT_CHECK([grep 'AC_INIT: not a literal: ' stderr], [], [ignore])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU String++], [2.48], [https://example.com], [string++],
|
|
['https://example.com'])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
|
|
AT_CHECK([grep 'AC_INIT: not a literal: ' stderr], [], [ignore])
|
|
|
|
|
|
# The TARNAME argument is used to construct filenames, so it's even
|
|
# more constrained.
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU String++], [2.48], [https://example.com], ['string++'])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
|
|
AT_CHECK([grep 'AC_INIT: unsafe as a filename: ' stderr], [], [ignore])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU String++], [2.48], [https://example.com], [string ++])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
|
|
AT_CHECK([grep 'AC_INIT: unsafe as a filename: ' stderr], [], [ignore])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU String++], [2.48], [https://example.com], [string*])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([-Werror], [1], [ignore], [stderr])
|
|
AT_CHECK([grep 'AC_INIT: unsafe as a filename: ' stderr], [], [ignore])
|
|
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## -------------- ##
|
|
## AC_COPYRIGHT. ##
|
|
## -------------- ##
|
|
|
|
# Ensure the FSF notice as well as the user-provided one are present
|
|
# in the head of the testsuite as well as the --version output.
|
|
|
|
AT_SETUP([AC@&t@_COPYRIGHT])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([GNU fu], [1.0])
|
|
AC_COPYRIGHT([[This is just a test notice, not a real one, so let's avoid
|
|
words that may be matched by scanners for legal things,
|
|
causing extra work for distributors.
|
|
Multi-line values should be supported.
|
|
]])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF
|
|
AT_CHECK_CONFIGURE([--version], [], [stdout])
|
|
AT_CHECK([grep 'Copyright.*Free Software Foundation' stdout], [], [ignore])
|
|
AT_CHECK([grep 'This is just a test notice' stdout], [], [ignore])
|
|
AT_CHECK([sed -ne 50q -e '/Copyright/{' -e N -e N -e N -e N -e 's/#//g' ]dnl
|
|
[ -e 's/\n//g' -e p -e '}' configure ]dnl
|
|
[ | grep 'Copyright.*Free Software Foundation'],
|
|
[], [ignore])
|
|
AT_CHECK([sed 50q configure | grep 'This is just a test notice'], [], [ignore])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ---------------- ##
|
|
## AC_CACHE_CHECK. ##
|
|
## ---------------- ##
|
|
|
|
# Make sure AC_CACHE_CHECK is silent with -q.
|
|
# Also make sure we warn about cache id's not named with `_cv_'.
|
|
|
|
AT_SETUP([AC_CACHE_CHECK])
|
|
AT_KEYWORDS([CONFIG_SITE])
|
|
|
|
# Don't let a config.site file affect this test.
|
|
AS_UNSET([CONFIG_SITE])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT
|
|
# m4_define([ac_nothing], [ac_cv_absolutely_nothing])
|
|
AC_CACHE_CHECK([for nothing],
|
|
[ac_nothing],
|
|
[ac_nothing=found])
|
|
|
|
AC_MSG_CHECKING([for some other variable])
|
|
commands_to_set_it_was_run=false
|
|
AC_CACHE_VAL([my_cv_variable], [
|
|
# FOO
|
|
commands_to_set_it_was_run=true
|
|
my_cv_variable=true
|
|
])
|
|
AC_MSG_RESULT([$my_cv_variable])
|
|
|
|
# Ensure that the result is available at this point.
|
|
if ${my_cv_variable+false} :; then
|
|
AC_MSG_ERROR([AC@&@&t@t@_CACHE_VAL did not ensure that the cache variable was set])
|
|
fi
|
|
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([], [], [], [stderr])
|
|
AT_CHECK([grep 'must contain _cv_ to be cached' stderr], [], [ignore])
|
|
|
|
# Do not warn about defines:
|
|
sed 's/^# m4_define/m4_define/' configure.ac > t
|
|
mv -f t configure.ac
|
|
AT_CHECK_AUTOCONF
|
|
AT_CHECK_CONFIGURE([-q])
|
|
|
|
sed '/m4_define/d; s/ac_nothing/ac_cv_nothing/' configure.ac > t
|
|
mv -f t configure.ac
|
|
AT_CHECK_AUTOCONF
|
|
AT_CHECK_CONFIGURE([-q])
|
|
|
|
# Print a message saying that the result was cached, iff it was cached.
|
|
AT_CHECK_CONFIGURE([], [], [stdout])
|
|
AT_CHECK([grep 'cached' stdout], [1])
|
|
AT_CHECK_CONFIGURE([my_cv_variable='yes it is set'], [], [stdout])
|
|
AT_CHECK([grep 'cached.*yes it is set' stdout], [], [ignore])
|
|
|
|
# --cache-file is honored and has caching semantics.
|
|
AT_CHECK_CONFIGURE([--cache-file=foobar.cache], [], [stdout])
|
|
AT_CHECK([grep 'cached' stdout], [1])
|
|
AT_CHECK([test ! -f config.cache])
|
|
AT_CHECK([grep 'my_cv_variable.*true' foobar.cache], [], [ignore])
|
|
AT_CHECK_CONFIGURE([--cache-file=foobar.cache], [], [stdout])
|
|
AT_CHECK([grep 'some other variable.*cached.*true' stdout], [], [ignore])
|
|
|
|
# A setting on the command line overrides the cache.
|
|
AT_CHECK_CONFIGURE([--cache-file=foobar.cache my_cv_variable='override'], [], [stdout])
|
|
AT_CHECK([grep 'cached.*override' stdout], [], [ignore])
|
|
AT_CHECK([grep 'my_cv_variable.*override' foobar.cache], [], [ignore])
|
|
|
|
# Values containing braces need special internal treatment.
|
|
AT_CHECK_CONFIGURE([-C ac_cv_nothing='{' my_cv_variable='contains } brace'],
|
|
[], [stdout])
|
|
AT_CHECK([grep 'ac_cv_nothing.*{' config.cache], [], [ignore])
|
|
AT_CHECK([grep 'my_cv_variable.*contains } brace' config.cache], [], [ignore])
|
|
AT_CHECK_CONFIGURE([-C], [], [stdout])
|
|
AT_CHECK([grep 'nothing.*{' stdout], [], [ignore])
|
|
AT_CHECK([grep 'some other variable.*contains } brace' stdout], [], [ignore])
|
|
rm -f config.cache
|
|
|
|
# Diagnose common side-effects that are errors in COMMANDS-TO-SET-IT:
|
|
sed 's/^# FOO/AC_DEFINE([some-define], [1], [oooh.])/' configure.ac > t
|
|
mv -f t configure.ac
|
|
AT_CHECK_AUTOCONF([], [], [], [stderr])
|
|
AT_CHECK([grep 'suspicious.*AC_DEFINE' stderr], [], [ignore])
|
|
|
|
sed 's/^AC_DEFINE.*/AC_SUBST([some_substitution], [oooh.])/' configure.ac > t
|
|
mv -f t configure.ac
|
|
AT_CHECK_AUTOCONF([], [], [], [stderr])
|
|
AT_CHECK([grep 'suspicious.*AC_SUBST' stderr], [], [ignore])
|
|
|
|
# Ensure the examples from the manual work as intended.
|
|
# Taken from autoconf.texi:Caching Results
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT
|
|
AC_DEFUN([AC_SHELL_TRUE],
|
|
[AC_CACHE_CHECK([whether true(1) works], [my_cv_shell_true_works],
|
|
[my_cv_shell_true_works=no
|
|
(true) 2>/dev/null && my_cv_shell_true_works=yes
|
|
if test "x$my_cv_shell_true_works" = xyes; then
|
|
AC_DEFINE([TRUE_WORKS], [1],
|
|
[Define if `true(1)' works properly.])
|
|
fi])
|
|
])
|
|
AC_SHELL_TRUE
|
|
]])
|
|
AT_CHECK_AUTOCONF([-Werror], [1], [], [stderr])
|
|
AT_CHECK([grep 'suspicious.*AC_DEFINE' stderr], [], [ignore])
|
|
|
|
# Taken from autoconf.texi:Caching Results
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT
|
|
AC_DEFUN([AC_SHELL_TRUE],
|
|
[AC_CACHE_CHECK([whether true(1) works], [my_cv_shell_true_works],
|
|
[my_cv_shell_true_works=no
|
|
(true) 2>/dev/null && my_cv_shell_true_works=yes])
|
|
if test "x$my_cv_shell_true_works" = xyes; then
|
|
AC_DEFINE([TRUE_WORKS], [1],
|
|
[Define if `true(1)' works properly.])
|
|
fi
|
|
])
|
|
AC_SHELL_TRUE
|
|
AC_OUTPUT
|
|
]])
|
|
AT_CHECK_AUTOCONF([-Werror])
|
|
AT_CHECK_CONFIGURE([-C], [], [stdout])
|
|
AT_CHECK([grep my_cv_shell_true_works config.cache], [], [ignore])
|
|
AT_CHECK([grep 'true.*works.*yes' stdout], [], [ignore])
|
|
|
|
AT_CHECK_CONFIGURE([--config-cache], [], [stdout])
|
|
AT_CHECK([grep 'true.*works.*cached.*yes' stdout], [], [ignore])
|
|
|
|
# config.status only pays attention to the cache file with --recheck.
|
|
AT_CHECK([./config.status], [], [stdout])
|
|
AT_CHECK([grep cache stdout], [1])
|
|
AT_CHECK([./config.status --recheck], [], [stdout])
|
|
AT_CHECK([grep cache stdout], [0], [ignore])
|
|
|
|
# By default, configure uses no cache file, neither loading nor updating it.
|
|
: > a-stamp-file
|
|
AT_CHECK_CONFIGURE([], [], [stdout])
|
|
AT_CHECK([grep cache stdout], [1])
|
|
AT_CHECK([LC_ALL=C ls -t config.cache a-stamp-file | sed 1q | grep config.cache], [1])
|
|
|
|
# Using a symlinked cache file works.
|
|
: > cache
|
|
rm -f config.cache
|
|
AS_LN_S([cache], [config.cache])
|
|
AT_CHECK_CONFIGURE([-C])
|
|
# Either the system does not support symlinks, or the symlinked-to file
|
|
# should be updated.
|
|
AT_CHECK([test -s cache || test ! -h config.cache])
|
|
|
|
# config.site can specify a site-wide cache, accumulating information.
|
|
# Also test that we don't run afoul of sourcing a file with leading -.
|
|
AT_DATA([-config.site],
|
|
[[cache_file=sitecache
|
|
]])
|
|
AT_DATA([sitecache],
|
|
[[my_cv_some_preset_cache_var=yes
|
|
]])
|
|
CONFIG_SITE=-config.site
|
|
export CONFIG_SITE
|
|
AT_CHECK_CONFIGURE
|
|
AT_CHECK([grep my_cv_some_preset_cache_var sitecache], [], [ignore])
|
|
AT_CHECK([grep my_cv_shell_true_works sitecache], [], [ignore])
|
|
AT_CHECK_CONFIGURE([], [], [stdout])
|
|
AT_CHECK([grep 'whether true.*works.*cached' stdout], [], [ignore])
|
|
|
|
dnl Until we can find a way to avoid catastrophic failure,
|
|
dnl skip the rest of this test on such shells.
|
|
echo 'if' > syntax
|
|
AT_CHECK([${CONFIG_SHELL-$SHELL} -c 'case `. ./syntax; echo $?` in
|
|
0|"") exit 77;; esac'], [0], [ignore], [ignore])
|
|
|
|
# Check that config cache scripts must be well-formed.
|
|
AT_DATA([bad.site],
|
|
[[fi
|
|
]])
|
|
CONFIG_SITE=$PWD/bad.site
|
|
AT_CHECK_CONFIGURE([ || exit 1], [1], [stdout], [stderr])
|
|
AT_CHECK([grep 'failed to load site script' stderr], [], [ignore], [ignore],
|
|
[AT_CHECK([grep 'whether true' stdout], [1])])
|
|
|
|
# However, a missing file is ignored.
|
|
CONFIG_SITE=./no-such-file
|
|
AT_CHECK_CONFIGURE
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## --------------- ##
|
|
## AC_CACHE_LOAD. ##
|
|
## --------------- ##
|
|
|
|
# Test AC_CACHE_LOAD.
|
|
|
|
AT_SETUP([AC_CACHE_LOAD])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT
|
|
$some_test_code
|
|
AC_CACHE_LOAD
|
|
AC_MSG_NOTICE([some_cv_variable is $some_cv_variable])
|
|
AC_OUTPUT
|
|
]])
|
|
AT_CHECK_AUTOCONF
|
|
AS_UNSET([some_test_code])
|
|
AT_DATA([new-cache],
|
|
[[some_cv_variable=value-from-new-cache
|
|
]])
|
|
AT_CHECK_CONFIGURE([some_test_code='eval cache_file=new-cache'], [], [stdout])
|
|
AT_CHECK([grep 'some_cv_variable.*value-from-new-cache' stdout], [], [ignore])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ---------------- ##
|
|
## AC_COMPUTE_INT. ##
|
|
## ---------------- ##
|
|
|
|
# Make sure AC_COMPUTE_INT fails properly.
|
|
|
|
AT_SETUP([AC_COMPUTE_INT])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT
|
|
AC_COMPUTE_INT([invalid_expression],
|
|
[**0**],
|
|
[],
|
|
[invalid_expression=failed])
|
|
test "$invalid_expression" = failed ||
|
|
AC_MSG_ERROR([**0** evaluated to $invalid_expression instead of failing])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF
|
|
AT_CHECK_CONFIGURE
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ---------------- ##
|
|
## AC_TRY_COMMAND. ##
|
|
## ---------------- ##
|
|
|
|
AT_SETUP([AC_TRY_COMMAND])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT
|
|
|
|
if AC_TRY_COMMAND([(echo "The Cat in the Hat";
|
|
echo "The Hat in the Cat" >&2) |
|
|
grep \^The\ Cat\ in\ the\ Hat\$ >/dev/null]); then
|
|
:
|
|
else
|
|
AC_MSG_ERROR([didn't see the Cat in the Hat])
|
|
fi
|
|
|
|
if AC_TRY_COMMAND([(echo "The Cat in the Hat";
|
|
echo "The Hat in the Cat" >&2) |
|
|
grep \^The\ Hat\ in\ the\ Cat\$ >/dev/null]); then
|
|
AC_MSG_ERROR([saw the Hat in the Cat])
|
|
fi
|
|
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF
|
|
AT_CHECK_CONFIGURE([-q])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ------------ ##
|
|
## Input/Output ##
|
|
## ------------ ##
|
|
|
|
AT_SETUP([Input/Output])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT
|
|
cat <&AS@&t@_ORIGINAL_STDIN_FD >&AS@&t@_MESSAGE_FD
|
|
AC_OUTPUT
|
|
]])
|
|
AT_CHECK_AUTOCONF
|
|
AT_CHECK([echo Hello | CONFIG_SITE=/dev/null ./configure $configure_options | grep -v '^configure: '],, [Hello
|
|
])
|
|
AT_CHECK([echo Hello | CONFIG_SITE=/dev/null ./configure $configure_options --silent])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ------------------- ##
|
|
## configure arguments ##
|
|
## ------------------- ##
|
|
|
|
AT_SETUP([configure arguments])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT
|
|
echo "$@"
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF
|
|
AT_CHECK_CONFIGURE([FOO=bar --enable-baz --without-zork --silent], [0], [stdout], [ignore])
|
|
AT_CHECK([grep 'FOO=bar --enable-baz --without-zork --silent' stdout], [0], [ignore], [ignore])
|
|
|
|
dnl check that syntax error is detected
|
|
AT_CHECK_CONFIGURE([=], [1], [], [ignore], [ignore])
|
|
AT_CHECK_CONFIGURE([1=2], [1], [], [ignore], [ignore])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## ------------------------------ ##
|
|
## AC_ARG_ENABLE and AC_ARG_WITH. ##
|
|
## ------------------------------ ##
|
|
|
|
AT_SETUP([AC_ARG_ENABLE and AC_ARG_WITH])
|
|
|
|
AT_DATA_M4SH([configure.ac],
|
|
[[AC_INIT
|
|
# Taken from autoconf.texi:Pretty Help Strings.
|
|
AC_ARG_WITH([foo],
|
|
[AS_HELP_STRING([--with-foo],
|
|
[use foo (default is no)])],
|
|
[use_foo=$withval],
|
|
[use_foo=no])
|
|
AC_ARG_WITH([c++],
|
|
[AS_HELP_STRING([--with-c++],
|
|
[with c++])],
|
|
[choice_with=$withval])
|
|
AC_ARG_ENABLE([c++],
|
|
[AS_HELP_STRING([--enable-c++],
|
|
[enable c++])],
|
|
[choice_enable=$enableval])
|
|
echo "use_foo: $use_foo"
|
|
echo "with_c++: $with_c__, $choice_with"
|
|
echo "enable_c++: $enable_c__, $choice_enable"
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF
|
|
AT_CHECK_CONFIGURE([--help | grep foo], [0],
|
|
[[ --with-foo use foo (default is no)
|
|
]], [ignore])
|
|
AT_CHECK_CONFIGURE([--with-foo=yes --with-c++ --disable-c++],
|
|
[], [stdout], [ignore])
|
|
AT_CHECK([grep 'use_foo: yes' stdout], [], [ignore])
|
|
AT_CHECK([grep 'with_c++: yes, yes' stdout], [], [ignore])
|
|
AT_CHECK([grep 'enable_c++: no, no' stdout], [], [ignore])
|
|
AT_CHECK([grep 'unrecognized option' stdout], [1])
|
|
AT_CHECK_CONFIGURE([--without-foo --with-c++=no --enable-c++=maybe],
|
|
[], [stdout], [ignore])
|
|
AT_CHECK([grep 'use_foo: no' stdout], [], [ignore])
|
|
AT_CHECK([grep 'with_c++: no, no' stdout], [], [ignore])
|
|
AT_CHECK([grep 'enable_c++: maybe, maybe' stdout], [], [ignore])
|
|
AT_CHECK([grep 'unrecognized option' stdout], [1])
|
|
AT_CHECK_CONFIGURE([], [], [stdout], [ignore])
|
|
AT_CHECK([grep 'use_foo: no' stdout], [], [ignore])
|
|
AT_CHECK([grep 'with_c++: , $' stdout], [], [ignore])
|
|
AT_CHECK([grep 'enable_c++: , $' stdout], [], [ignore])
|
|
AT_CHECK([grep 'unrecognized option' stdout], [1])
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
## --------------------- ##
|
|
## configure directories ##
|
|
## --------------------- ##
|
|
|
|
AT_SETUP([configure directories])
|
|
|
|
CONFIG_SITE=/dev/null
|
|
export CONFIG_SITE
|
|
|
|
AT_DATA([foo.in],
|
|
[[prefix=@prefix@
|
|
exec_prefix=@exec_prefix@
|
|
libdir=@libdir@
|
|
]])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT
|
|
AC_CONFIG_FILES([foo])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF
|
|
dnl check that relative paths are rejected
|
|
AT_CHECK_CONFIGURE([--libdir=.], [1], [ignore], [stderr])
|
|
AT_CHECK([grep 'expected an absolute directory name for --libdir: \.' stderr],
|
|
[0], [ignore])
|
|
|
|
dnl check that extra slashes are stripped, and that defaults are not expanded
|
|
AT_CHECK_CONFIGURE([--prefix=/usr//])
|
|
AT_CHECK([cat foo], [0], [[prefix=/usr
|
|
exec_prefix=${prefix}
|
|
libdir=${exec_prefix}/lib
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
## ---------- ##
|
|
## AC_SUBST. ##
|
|
## ---------- ##
|
|
|
|
AT_SETUP([AC_SUBST])
|
|
AT_KEYWORDS([AS@&t@_IDENTIFIER_IF])
|
|
|
|
# Check that a valid variable name is used.
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([test], [1])
|
|
AC_SUBST([1], [bar])
|
|
AC_OUTPUT
|
|
]])
|
|
AT_CHECK_AUTOCONF([], [1], [], [stderr])
|
|
AT_CHECK([grep 'not a valid shell variable' stderr], [], [ignore])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([test], [1])
|
|
AC_SUBST([], [bar])
|
|
AC_OUTPUT
|
|
]])
|
|
AT_CHECK_AUTOCONF([], [1], [], [stderr])
|
|
AT_CHECK([grep 'not a valid shell variable' stderr], [], [ignore])
|
|
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([test], [1])
|
|
AC_SUBST([*], [bar])
|
|
AC_OUTPUT
|
|
]])
|
|
AT_CHECK_AUTOCONF([], [1], [], [stderr])
|
|
AT_CHECK([grep 'not a valid shell variable' stderr], [], [ignore])
|
|
|
|
# Make sure AC_SUBST handles variables as expected.
|
|
AT_DATA([file.in],
|
|
[[@FOO@
|
|
@BAR@
|
|
FOO
|
|
]])
|
|
AT_DATA([configure.ac],
|
|
[[AC_INIT([test], [0])
|
|
m4_define([FOO], [baz])
|
|
AC_SUBST([FOO], [bar])
|
|
BAR=one
|
|
AC_SUBST([B@&t@AR])
|
|
BAR=two
|
|
AC_CONFIG_FILES([file])
|
|
AC_OUTPUT
|
|
]])
|
|
|
|
AT_CHECK_AUTOCONF([], [], [], [stderr])
|
|
AT_CHECK_CONFIGURE
|
|
AT_CHECK([cat file], [],
|
|
[[bar
|
|
two
|
|
FOO
|
|
]])
|
|
|
|
AT_CLEANUP
|
|
|
|
## ----------------------------------- ##
|
|
## configure with closed standard fds ##
|
|
## ----------------------------------- ##
|
|
|
|
AT_SETUP([configure with closed standard fds])
|
|
AT_KEYWORDS([AS@&t@_INIT])
|
|
|
|
# Create a configure script that runs a relatively complicated but
|
|
# self-contained test. Run it.
|
|
AT_CONFIGURE_AC([[AC_PROG_CC]])
|
|
AT_CHECK_AUTOCONF
|
|
AT_CHECK_AUTOHEADER
|
|
AT_CHECK_CONFIGURE([], [], [stdout], [stderr])
|
|
AT_CHECK_ENV
|
|
|
|
mv stdout stdout-expected
|
|
mv stderr stderr-expected
|
|
mv state-env.after state-env-expected
|
|
mv config.status config-status-expected
|
|
mv config.h config-h-expected
|
|
|
|
# Run it again with stdin (fd 0) closed.
|
|
# There should be no change to the stdout or stderr output and thoe
|
|
# result of configuration should be the same.
|
|
|
|
AT_CHECK_CONFIGURE([ 0<&- ], [], [stdout], [stderr])
|
|
AT_CHECK_ENV
|
|
AT_CMP([stdout-expected], [stdout])
|
|
AT_CMP([stderr-expected], [stderr])
|
|
AT_CONFIG_CMP([state-env-expected], [state-env.after])
|
|
|
|
mv stdout stdout-closed-0
|
|
mv stderr stderr-closed-0
|
|
mv state-env.after state-env-closed-0
|
|
mv config.status config-status-closed-0
|
|
mv config.h config-h-closed-0
|
|
|
|
# Run it again with stdout (fd 1) closed.
|
|
# There should be no change to the stderr output and the
|
|
# result of configuration should be the same. (Any output
|
|
# that would have gone to stdout, of course, is lost.)
|
|
|
|
AT_CHECK_CONFIGURE([ 1>&- ], [], [stdout], [stderr])
|
|
AT_CHECK_ENV
|
|
AT_CHECK([test -f stdout && test ! -s stdout])
|
|
AT_CMP([stderr-expected], [stderr])
|
|
AT_CONFIG_CMP([state-env-expected], [state-env.after])
|
|
|
|
mv stdout stdout-closed-1
|
|
mv stderr stderr-closed-1
|
|
mv state-env.after state-env-closed-1
|
|
mv config.status config-status-closed-1
|
|
mv config.h config-h-closed-1
|
|
|
|
# Run it again with stderr (fd 2) closed.
|
|
# There should be no change to the stdout output and the
|
|
# result of configuration should be the same. (Any output
|
|
# that would have gone to stderr, of course, is lost.)
|
|
|
|
AT_CHECK_CONFIGURE([ 2>&- ], [], [stdout], [stderr])
|
|
AT_CHECK_ENV
|
|
AT_CMP([stdout-expected], [stdout])
|
|
AT_CHECK([test -f stderr && test ! -s stderr])
|
|
AT_CONFIG_CMP([state-env-expected], [state-env.after])
|
|
|
|
mv stdout stdout-closed-2
|
|
mv stderr stderr-closed-2
|
|
mv state-env.after state-env-closed-2
|
|
mv config.status config-status-closed-2
|
|
mv config.h config-h-closed-2
|
|
|
|
AT_CLEANUP
|