summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ChangeLog364
-rw-r--r--tests/NEWS5
-rw-r--r--tests/README7
-rw-r--r--tests/guile.supp31
-rwxr-xr-xtests/mkshadow8
-rw-r--r--[-rwxr-xr-x]tests/run_make_tests.pl88
-rw-r--r--tests/scripts/features/archives95
-rw-r--r--tests/scripts/features/default_names49
-rw-r--r--tests/scripts/features/double_colon9
-rw-r--r--tests/scripts/features/errors19
-rw-r--r--tests/scripts/features/escape30
-rw-r--r--tests/scripts/features/include12
-rw-r--r--tests/scripts/features/jobserver61
-rw-r--r--tests/scripts/features/load102
-rw-r--r--tests/scripts/features/loadapi112
-rw-r--r--tests/scripts/features/mult_rules2
-rw-r--r--tests/scripts/features/output-sync334
-rw-r--r--tests/scripts/features/parallelism104
-rw-r--r--tests/scripts/features/patspecific_vars10
-rw-r--r--tests/scripts/features/patternrules5
-rw-r--r--tests/scripts/features/recursion16
-rw-r--r--tests/scripts/features/reinvoke17
-rw-r--r--tests/scripts/features/rule_glob37
-rw-r--r--tests/scripts/features/se_explicit17
-rw-r--r--tests/scripts/features/se_implicit34
-rw-r--r--tests/scripts/features/shell_assignment65
-rw-r--r--tests/scripts/features/targetvars12
-rw-r--r--tests/scripts/features/utf811
-rw-r--r--tests/scripts/features/varnesting47
-rw-r--r--tests/scripts/features/vpath2
-rw-r--r--tests/scripts/features/vpath365
-rw-r--r--tests/scripts/features/vpathgpath2
-rw-r--r--tests/scripts/features/vpathplus1
-rw-r--r--tests/scripts/functions/call15
-rw-r--r--tests/scripts/functions/file101
-rw-r--r--tests/scripts/functions/filter-out32
-rw-r--r--tests/scripts/functions/foreach6
-rw-r--r--tests/scripts/functions/guile99
-rw-r--r--tests/scripts/functions/sort98
-rw-r--r--tests/scripts/functions/wildcard12
-rw-r--r--tests/scripts/functions/word26
-rw-r--r--tests/scripts/misc/bs-nl129
-rw-r--r--tests/scripts/misc/fopen-fail15
-rw-r--r--tests/scripts/misc/general32
-rw-r--r--tests/scripts/options/dash-B4
-rw-r--r--tests/scripts/options/dash-C8
-rw-r--r--tests/scripts/options/dash-I4
-rw-r--r--tests/scripts/options/dash-W4
-rw-r--r--tests/scripts/options/dash-k11
-rw-r--r--tests/scripts/options/dash-n80
-rw-r--r--tests/scripts/options/eval10
-rw-r--r--tests/scripts/options/print-directory33
-rw-r--r--tests/scripts/options/symlinks10
-rw-r--r--tests/scripts/options/warn-undefined-variables4
-rw-r--r--tests/scripts/targets/DEFAULT4
-rw-r--r--tests/scripts/targets/INTERMEDIATE4
-rw-r--r--tests/scripts/targets/ONESHELL19
-rw-r--r--tests/scripts/targets/POSIX28
-rw-r--r--tests/scripts/targets/SECONDARY11
-rw-r--r--tests/scripts/variables/DEFAULT_GOAL2
-rw-r--r--tests/scripts/variables/GNUMAKEFLAGS42
-rw-r--r--tests/scripts/variables/LIBPATTERNS2
-rw-r--r--tests/scripts/variables/MAKE4
-rw-r--r--tests/scripts/variables/MAKEFLAGS26
-rw-r--r--tests/scripts/variables/MAKE_RESTARTS4
-rw-r--r--tests/scripts/variables/SHELL19
-rw-r--r--tests/scripts/variables/define56
-rw-r--r--tests/scripts/variables/flavors20
-rw-r--r--tests/scripts/variables/private44
-rw-r--r--tests/scripts/variables/special2
-rw-r--r--tests/test_driver.pl355
71 files changed, 2530 insertions, 588 deletions
diff --git a/tests/ChangeLog b/tests/ChangeLog
index d036568..653c5a7 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,354 @@
+2013-10-09 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/patspecific_vars: Typo fixes.
+
+2013-10-05 Paul Smith <psmith@gnu.org>
+
+ * test_driver.pl (run_all_tests): Rewrite to be more clear.
+ * scripts/features/jobserver: Avoid using $ENV{HOME} as it doesn't
+ exist everywhere.
+ * scripts/features/default_names: End with 1;
+
+ * scripts/features/loadapi: Use new calling signatures. Verify
+ the NOEXPAND flag works. Test with all valid function name
+ characters.
+
+2013-09-29 Paul Smith <psmith@gnu.org>
+
+ * scripts/variables/SHELL: Solaris /bin/sh can't handle options in
+ multiple words; skip that test.
+ * scripts/targets/ONESHELL: Ditto.
+
+ * scripts/variables/GNUMAKEFLAGS: Verify that GNUMAKEFLAGS is
+ cleared and options are not duplicated.
+
+2013-09-23 Paul Smith <psmith@gnu.org>
+
+ * scripts/options/print-directory: Rename dash-w to
+ print-directory to avoid conflicts with dash-W on case-insensitive
+ filesystems.
+
+2013-09-22 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/se_implicit: Verify that order-only tokens
+ inside second expansion are parsed correctly.
+ Test for Savannah bug #31155.
+
+ * run_make_tests.pl (set_more_defaults): If we can't find
+ gnumake.h based on the make program we might be running from a
+ remote build directory. Parse the Makefile for the right path.
+
+ Fix some test issues on Solaris.
+
+ * scripts/features/archives: Determine what output ar gives when
+ adding and replacing objects and compare with that.
+ * scripts/features/escape: Solaris /bin/sh doesn't properly handle
+ backslashes inside single quotes, so don't rely on it.
+ * scripts/features/output-sync: false(1) gives different exit
+ codes on different systems; use "exit 1" instead.
+ * scripts/features/parallelism: Increase the timeout for slower systems.
+
+2013-09-21 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/archives: Some versions of ar (MacOSX) generate
+ different output when creating archives. Run it and verify the
+ real output.
+ * scripts/features/default_names: MacOSX is, like Windows,
+ case-preserving / case-insensitive. Redo the test to avoid
+ checking for "UNIX".
+ * test_driver.pl (attach_default_output): Don't dup stdout into
+ stderr. Reported by Denis Excoffier <bug-tar@Denis-Excoffier.org>
+
+ * scripts/features/se_explicit: Fix a test that behaves
+ differently with/without archive capability enabled.
+ * scripts/features/output-sync: Don't test output-sync if it's not
+ enabled. We also skip it if parallelism is not enabled, although
+ strictly speaking some of the output-sync tests are valid even
+ without parallelism.
+ * scripts/features/jobserver: Move some tests that require the
+ jobserver from features/parallelism to a separate suite. Only run
+ this if jobserver mode is enabled.
+
+ * scripts/features/output-sync: Test shell functions writing to
+ stderr in recipes: ensure it's captured via output-sync. Test
+ output generated while reading makefiles and make sure it's
+ captured via output-sync. Make sure that fatal errors dump the
+ output so it's not lost.
+
+ * scripts/options/dash-w: Add a test for -w flag.
+
+2013-09-15 Paul Smith <psmith@gnu.org>
+
+ * scripts/misc/fopen-fail: Check for failure on infinite recursion.
+ * run_make_tests.pl (run_make_test): Allow the answer string to be
+ undef, which means that we shouldn't compare it at all. Only the
+ exit code matters in this case.
+ * test_driver.pl (compare_output): Ditto.
+ Test for Savannah bug #27374.
+
+ * scripts/features/parallelism: Test broken jobserver on recursion.
+ Test for Savannah bug #39934.
+
+ * scripts/options/eval: Verify --eval during restart.
+ Test for Savannah bug #39203.
+
+2013-09-14 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync: Verify -Orecurse properly.
+
+2013-09-12 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync: Modify for output sync behavior.
+ * scripts/variables/MAKE_RESTARTS: Ditto.
+ * scripts/variables/MAKEFLAGS: Remove mode for --trace.
+ * scripts/variables/GNUMAKEFLAGS: Ditto.
+
+2013-07-22 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/rule_glob: Add tests for wildcards in rules.
+ Test for Savannah bug #39310.
+
+2013-07-09 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/se_implicit: Add a test for SE rules depending
+ on other SE rules to be built.
+
+2013-05-26 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/archives: Test for Savannah bug #38442.
+
+ * scripts/misc/bs-nl: Test for Savannah bug #39035.
+ Add a test for Savannah bug #38945.
+
+2013-05-22 Paul Smith <psmith@gnu.org>
+
+ * scripts/options/dash-n: Fix results after MAKEFLAGS fixes.
+ * scripts/variables/MAKEFLAGS: Ditto.
+ * scripts/variables/GNUMAKEFLAGS: Ditto.
+
+2013-05-14 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/loadapi: Add plugin_is_GPL_compatible symbol.
+ * scripts/features/load: Ditto.
+
+2013-05-13 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync (output_sync_set): Update for new
+ --trace behavior.
+
+2013-05-05 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync (output_sync_set): Remove
+ extraneous enter/leave lines, which are no longer printed.
+ Add tests for syncing command line printing.
+ (output_sync_set): Rename options: "job"->"line"; "make"->"recurse"
+
+2013-05-04 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/loadapi: Use the new alloc functions.
+
+ * scripts/features/output-sync (output_sync_set): New test for
+ ordered recursive output for -Ojob / -Otarget.
+
+2013-05-03 Eli Zaretskii <eliz@gnu.org>
+
+ * scripts/features/load: Fix signatures of testload_gmk_setup and
+ explicit_setup, to bring them in line with the documentation.
+
+2013-04-28 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync (output_sync_set): Add tests for
+ the per-job syntax mode.
+ (output_sync_set): Test improved error message location.
+
+2013-04-15 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync (output_sync_set): New arg syntax.
+
+2013-04-14 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/output-sync: Rewrite to be more reliable.
+
+ * test_driver.pl (_run_command): Don't set SIGALRM until after we
+ start the child. Print errors to the top-level output, which will
+ be stderr.
+ (attach_default_output): Use a list of file handles as the stack.
+ (detach_default_output): Ditto.
+
+ * scripts/features/output-sync: Add a test for output-sync.
+
+2013-02-25 Paul Smith <psmith@gnu.org>
+
+ * run_make_tests.pl (valid_option): Support the -srcdir flag.
+ (set_more_defaults): Set up $srcdir if it's not set yet.
+
+ * scripts/functions/guile: Verify gmk-eval doesn't expand twice.
+ * scripts/features/load: Rework to test just the load capability.
+ * scripts/features/loadapi: New set of tests for the load API.
+
+2013-01-19 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/load: Test loaded files with and without "./"
+ prefix. Add tests for automatically rebuilding loaded files if
+ they are out of date or non-existent.
+
+2013-01-13 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/archives: Add a check targets that have parens,
+ but are not archives. See Savannah bug #37878.
+
+ * scripts/options/dash-n: Verify -n is preserved after recursive /
+ re-exec. See Savannah bug #38051.
+
+2013-01-12 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/parallelism: Change rule so it doesn't depend
+ on invocation order, etc.
+
+2012-10-29 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/load: New test suite for the "load" directive.
+
+2012-09-09 Paul Smith <psmith@gnu.org>
+
+ * scripts/functions/file: Get errors in the C locale, not the
+ current locale. Fixes Savannah bug #35764.
+
+ * scripts/features/escape: Check that backslashes before
+ non-special characters are not removed.
+
+ * scripts/features/utf8: New test for UTF-8 support.
+ See Savannah bug #36529.
+
+ * scripts/targets/POSIX: Add tests for default macro values as
+ specified by IEEE Std 1003.1-2008. See Savannah bug #37069.
+
+2012-03-04 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/se_explicit: Test $(x:%=%) format in secondary
+ expansion prerequisite lists. See Savannah bug #16545.
+
+ * scripts/features/escape: Test escaped ":" in prerequisite lists.
+ See Savannah bug #12126.
+
+ * scripts/variables/private: Test appending private variables in
+ pattern-specific target rules. See Savannah bug #35468.
+
+2012-03-03 Paul Smith <psmith@gnu.org>
+
+ * scripts/variables/SHELL: Ensure .SHELLFLAGS works with options
+ separated by whitespace.
+
+ * scripts/targets/ONESHELL: Try .ONESHELL in combination with
+ whitespace-separated options in .SHELLFLAGS. See Savannah bug #35397.
+
+ * scripts/functions/filter-out: Add filter tests and test escape
+ operations. See Savannah bug #35410.
+
+ * guile.supp: Suppress valgrind errors from Guile
+ * run_make_tests.pl: Use the Guile suppression file.
+
+ * scripts/misc/bs-nl: Check for POSIX and non-POSIX
+ backslash/newline handling. Addresses Savannah bug #16670.
+
+2012-01-29 Paul Smith <psmith@gnu.org>
+
+ * scripts/variables/flavors: Add tests for ::=
+ * scripts/variables/define: Ditto
+
+ * scripts/functions/file: Test the new $(file ...) function.
+
+2012-01-12 Paul Smith <psmith@gnu.org>
+
+ * scripts/functions/guile: New regression tests for Guile support.
+
+2011-12-10 Paul Smith <psmith@gnu.org>
+
+ * scripts/targets/SECONDARY: Add prereq statements to ensure rules
+ are printed in the right order for test #9
+
+2011-11-14 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/double_colon: Check double-colon with escaped
+ filenames. See Savannah bug #33399.
+
+2011-09-18 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/parallelism: On re-exec make sure we preserve
+ the value of MAKEFLAGS when necessary. See Savannah bug #33873.
+
+ * scripts/features/vpath3: Verify handling of -lfoo libraries
+ found via vpath vs. the standard directory search.
+ See Savannah bug #32511.
+
+2011-09-12 Paul Smith <psmith@gnu.org>
+
+ * scripts/functions/call: Verify that using export in a $(call ...)
+ context creates a global variable. See Savannah bug #32498.
+
+2011-09-02 Paul Smith <psmith@gnu.org>
+
+ * scripts/options/dash-n: Verify that in "-n -t", the -n takes
+ priority. Patch from Michael Witten <mfwitten@gmail.com>.
+
+2011-08-29 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/varnesting: Test resetting of variables while
+ expanding them. See Savannah patch #7534
+
+2011-06-12 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/archives: Check archives with whitespace at the
+ beginning, end, and extra in the middle.
+ Another test for Savannah bug #30612.
+
+2011-05-07 Paul Smith <psmith@gnu.org>
+
+ * scripts/variables/private: Ensure we skip private variables when
+ appending. Test for Savannah bug #32872.
+
+ * scripts/functions/wildcard: Verify wildcard used to test for
+ file existence/non-existence.
+
+2011-05-02 Paul Smith <psmith@gnu.org>
+
+ * scripts/functions/sort: Add a test for Savannah bug #33125.
+
+2011-04-17 David A. Wheeler <dwheeler@dwheeler.com>
+
+ * scripts/features/shell_assignment: Regression for "!=" feature
+
+2010-11-06 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/targetvars: Fix known-good output for BS/NL changes.
+ * scripts/functions/call: Ditto.
+ * scripts/variables/special: Ditto.
+
+ * scripts/misc/bs-nl: New test suite for backslash/newline testing.
+
+2010-08-29 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/errors: Add new error message to output text.
+ * scripts/variables/SHELL: Ditto.
+ * scripts/targets/POSIX: Ditto.
+ * scripts/options/dash-k: Ditto.
+ * scripts/features/vpathplus: Ditto.
+ * scripts/features/patternrules: Ditto.
+ * scripts/features/parallelism: Ditto.
+
+2010-08-13 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/archives: New regression tests for archive
+ support. Test for fix to Savannah bug #30612.
+
+ * run_make_tests.pl (set_more_defaults): Set a %FEATURES hash to
+ the features available in $(.FEATURES).
+
+2010-08-10 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/reinvoke: Ensure command line variable settings
+ are preserved across make re-exec. Tests Savannah bug #30723.
+
2010-07-28 Paul Smith <psmith@gnu.org>
* scripts/targets/POSIX: Compatibility issues with Solaris (and
@@ -299,7 +650,7 @@
* test_driver.pl (toplevel): Skip all hidden files/directories (ones
beginning with ".").
- * scripts/functions/andor: Tests for $(and ..) and $(or ...)
+ * scripts/functions/andor: Tests for $(and ...) and $(or ...)
functions.
2006-02-08 Boris Kolpackov <boris@kolpackov.net>
@@ -386,9 +737,9 @@
2005-08-13 Boris Kolpackov <boris@kolpackov.net>
- * scripts/functions/wildcard: Wrap calls to $(wildcard ) with
+ * scripts/functions/wildcard: Wrap calls to $(wildcard) with
$(sort) so that the resulting order is no longer filesystem-
- dependant.
+ dependent.
2005-08-10 Boris Kolpackov <boris@kolpackov.net>
@@ -459,7 +810,7 @@
2005-06-09 Paul D. Smith <psmith@gnu.org>
- * scripts/functions/foreach: Add a test for Savannah bug #11913.
+ * scripts/functions/foreach: Add a test for Savannah bug #11913.
2005-05-31 Boris Kolpackov <boris@kolpackov.net>
@@ -479,7 +830,7 @@
2005-05-02 Paul D. Smith <psmith@gnu.org>
* scripts/features/parallelism: Add a test for exporting recursive
- variables containing $(shell ) calls. Rewrite this script to use
+ variables containing $(shell) calls. Rewrite this script to use
run_make_test() everywhere.
2005-04-07 Paul D. Smith <psmith@gnu.org>
@@ -1062,8 +1413,7 @@
ChangeLog file for the test suite created.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright (C) 1992-2013 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
diff --git a/tests/NEWS b/tests/NEWS
index 43971ec..7fb864c 100644
--- a/tests/NEWS
+++ b/tests/NEWS
@@ -72,7 +72,7 @@ Changes from 0.4.4 to 0.4.5 (April 29, 1995):
Also, some tests and stuff still haven't made it in because I
haven't had time to write the test scripts for them. But they,
- too, will get in eventually. Contributions of scripts (ie, tests
+ too, will get in eventually. Contributions of scripts (i.e., tests
that I can just drop in) are particularly welcome and will be
incorporated immediately.
@@ -162,8 +162,7 @@ Changes from 0.1 to 0.2 (5-4-92):
-------------------------------------------------------------------------------
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright (C) 1992-2013 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
diff --git a/tests/README b/tests/README
index 3860bdb..0663082 100644
--- a/tests/README
+++ b/tests/README
@@ -7,8 +7,7 @@ This entire test suite, including all test files, are copyright and
distributed under the following terms:
-----------------------------------------------------------------------------
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1992-2013 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -39,7 +38,7 @@ To run the test suite on Windows NT or DOS systems, use
"perl.exe ./run_make-tests.pl".
By default, the test engine picks up the first executable called "make"
-that it finds in your path. You may use the -make_path option (ie,
+that it finds in your path. You may use the -make_path option (i.e.,
"perl run_make_tests -make_path /usr/local/src/make-3.78/make") if
you want to run a particular copy. This now works correctly with
relative paths and when make is called something other than "make" (like
@@ -59,7 +58,7 @@ The options/dash-l test will not really test anything if the copy of
make you are using can't obtain the system load. Some systems require
make to be setgid sys or kmem for this; if you don't want to install
make just to test it, make it setgid to kmem or whatever group /dev/kmem
-is (ie, "chgrp kmem make;chmod g+s make" as root). In any case, the
+is (i.e., "chgrp kmem make;chmod g+s make" as root). In any case, the
options/dash-l test should no longer *fail* because make can't read
/dev/kmem.
diff --git a/tests/guile.supp b/tests/guile.supp
new file mode 100644
index 0000000..9e9b01b
--- /dev/null
+++ b/tests/guile.supp
@@ -0,0 +1,31 @@
+# Guile valgrind suppression file
+# Created with Guile 1.8.7
+
+# --- Garbage collection
+{
+ guilegc
+ Memcheck:Cond
+ ...
+ fun:scm_gc_for_newcell
+}
+{
+ guilegc
+ Memcheck:Value4
+ ...
+ fun:scm_gc_for_newcell
+}
+{
+ guilegc
+ Memcheck:Value8
+ ...
+ fun:scm_gc_for_newcell
+}
+
+
+# -- scm_alloc_struct
+{
+ guileheap
+ Memcheck:Leak
+ ...
+ fun:scm_alloc_struct
+}
diff --git a/tests/mkshadow b/tests/mkshadow
index d41b40e..5e0a402 100755
--- a/tests/mkshadow
+++ b/tests/mkshadow
@@ -3,9 +3,7 @@
# Simple script to make a "shadow" test directory, using symbolic links.
# Typically you'd put the shadow in /tmp or another local disk
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-2013 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -28,7 +26,7 @@ esac
dest="$1"
if [ ! -d "$dest" ]; then
- echo "Destination directory \`$dest' must exist!"
+ echo "Destination directory '$dest' must exist!"
exit 1
fi
@@ -55,5 +53,5 @@ done
rm -rf work
-echo "Shadow test suite created in \`$dest/$name'."
+echo "Shadow test suite created in '$dest/$name'."
exit 0
diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl
index 2c8c08b..54c2892 100755..100644
--- a/tests/run_make_tests.pl
+++ b/tests/run_make_tests.pl
@@ -11,9 +11,7 @@
# [-make <make prog>]
# (and others)
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-2013 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -29,13 +27,17 @@
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
+%FEATURES = ();
$valgrind = 0; # invoke make with valgrind
$valgrind_args = '';
-$memcheck_args = '--num-callers=15 --tool=memcheck --leak-check=full';
+$memcheck_args = '--num-callers=15 --tool=memcheck --leak-check=full --suppressions=guile.supp';
$massif_args = '--num-callers=15 --tool=massif --alloc-fn=xmalloc --alloc-fn=xcalloc --alloc-fn=xrealloc --alloc-fn=xstrdup --alloc-fn=xstrndup';
$pure_log = undef;
+# The location of the GNU make source directory
+$srcdir = '';
+
$command_string = '';
$all_tests = 0;
@@ -60,6 +62,15 @@ sub valid_option
return 1;
}
+ if ($option =~ /^-srcdir$/i) {
+ $srcdir = shift @argv;
+ if (! -f "$srcdir/gnumake.h") {
+ print "$option $srcdir: Not a valid GNU make source directory.\n";
+ exit 0;
+ }
+ return 1;
+ }
+
if ($option =~ /^-all([-_]?tests)?$/i) {
$all_tests = 1;
return 1;
@@ -98,6 +109,17 @@ sub valid_option
$old_makefile = undef;
+sub subst_make_string
+{
+ local $_ = shift;
+ $makefile and s/#MAKEFILE#/$makefile/g;
+ s/#MAKEPATH#/$mkpath/g;
+ s/#MAKE#/$make_name/g;
+ s/#PERL#/$perl_name/g;
+ s/#PWD#/$pwd/g;
+ return $_;
+}
+
sub run_make_test
{
local ($makestring, $options, $answer, $err_code, $timeout) = @_;
@@ -115,16 +137,9 @@ sub run_make_test
$makefile = &get_tmpfile();
}
- # Make sure it ends in a newline.
+ # Make sure it ends in a newline and substitute any special tokens.
$makestring && $makestring !~ /\n$/s and $makestring .= "\n";
-
- # Replace @MAKEFILE@ with the makefile name and @MAKE@ with the path to
- # make
- $makestring =~ s/#MAKEFILE#/$makefile/g;
- $makestring =~ s/#MAKEPATH#/$mkpath/g;
- $makestring =~ s/#MAKE#/$make_name/g;
- $makestring =~ s/#PERL#/$perl_name/g;
- $makestring =~ s/#PWD#/$pwd/g;
+ $makestring = subst_make_string($makestring);
# Populate the makefile!
open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
@@ -133,13 +148,10 @@ sub run_make_test
}
# Do the same processing on $answer as we did on $makestring.
-
- $answer && $answer !~ /\n$/s and $answer .= "\n";
- $answer =~ s/#MAKEFILE#/$makefile/g;
- $answer =~ s/#MAKEPATH#/$mkpath/g;
- $answer =~ s/#MAKE#/$make_name/g;
- $answer =~ s/#PERL#/$perl_name/g;
- $answer =~ s/#PWD#/$pwd/g;
+ if (defined $answer) {
+ $answer && $answer !~ /\n$/s and $answer .= "\n";
+ $answer = subst_make_string($answer);
+ }
run_make_with_options($makefile, $options, &get_logfile(0),
$err_code, $timeout);
@@ -228,14 +240,16 @@ sub run_make_with_options {
sub print_usage
{
&print_standard_usage ("run_make_tests",
- "[-make_path make_pathname] [-memcheck] [-massif]",);
+ "[-make MAKE_PATHNAME] [-srcdir SRCDIR] [-memcheck] [-massif]",);
}
sub print_help
{
&print_standard_help (
- "-make_path",
+ "-make",
"\tYou may specify the pathname of the copy of make to run.",
+ "-srcdir",
+ "\tSpecify the make source directory.",
"-valgrind",
"-memcheck",
"\tRun the test suite under valgrind's memcheck tool.",
@@ -317,7 +331,7 @@ sub set_more_defaults
$mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE):\n
'echo \"all:;\@echo \\\$(MAKE)\" | $make_path -f-' failed!\n";
$make_path = $mk;
- print "Make\t= `$make_path'\n" if $debug;
+ print "Make\t= '$make_path'\n" if $debug;
$string = `$make_path -v -f /dev/null 2> /dev/null`;
@@ -329,12 +343,8 @@ sub set_more_defaults
$make_name = $1;
}
else {
- if ($make_path =~ /$pathsep([^\n$pathsep]*)$/) {
- $make_name = $1;
- }
- else {
- $make_name = $make_path;
- }
+ $make_path =~ /^(?:.*$pathsep)?(.+)$/;
+ $make_name = $1;
}
# prepend pwd if this is a relative path (ie, does not
@@ -350,6 +360,24 @@ sub set_more_defaults
$mkpath = $make_path;
}
+ # If srcdir wasn't provided on the command line, see if the
+ # location of the make program gives us a clue. Don't fail if not;
+ # we'll assume it's been installed into /usr/include or wherever.
+ if (! $srcdir) {
+ $make_path =~ /^(.*$pathsep)?/;
+ my $d = $1 || '../';
+ -f "${d}gnumake.h" and $srcdir = $d;
+ }
+
+ # Not with the make program, so see if we can get it out of the makefile
+ if (! $srcdir && open(MF, "< ../Makefile")) {
+ local $/ = undef;
+ $_ = <MF>;
+ close(MF);
+ /^abs_srcdir\s*=\s*(.*?)\s*$/m;
+ -f "$1/gnumake.h" and $srcdir = $1;
+ }
+
# Get Purify log info--if any.
if (exists $ENV{PURIFYOPTIONS}
@@ -367,6 +395,8 @@ sub set_more_defaults
$parallel_jobs = 1;
}
+ %FEATURES = map { $_ => 1 } split /\s+/, `sh -c "echo '\\\$(info \\\$(.FEATURES))' | $make_path -f- 2>/dev/null"`;
+
# Set up for valgrind, if requested.
if ($valgrind) {
diff --git a/tests/scripts/features/archives b/tests/scripts/features/archives
new file mode 100644
index 0000000..a7ec881
--- /dev/null
+++ b/tests/scripts/features/archives
@@ -0,0 +1,95 @@
+# -*-mode: perl-*-
+
+$description = "Test GNU make's archive management features.";
+
+$details = "\
+This only works on systems that support it.";
+
+# If this instance of make doesn't support archives, skip it
+exists $FEATURES{archives} or return -1;
+
+# Create some .o files to work with
+utouch(-60, qw(a1.o a2.o a3.o));
+
+# Some versions of ar print different things on creation. Find out.
+my $created = `ar rv libxx.a a1.o 2>&1`;
+
+# Some versions of ar print different things on add. Find out.
+my $add = `ar rv libxx.a a2.o 2>&1`;
+$add =~ s/a2\.o/#OBJECT#/g;
+
+# Some versions of ar print different things on replacement. Find out.
+my $repl = `ar rv libxx.a a2.o 2>&1`;
+$repl =~ s/a2\.o/#OBJECT#/g;
+
+unlink('libxx.a');
+
+# Very simple
+run_make_test('all: libxx.a(a1.o)',
+ '', "ar rv libxx.a a1.o\n$created");
+
+# Multiple .o's. Add a new one to the existing library
+($_ = $add) =~ s/#OBJECT#/a2.o/g;
+run_make_test('all: libxx.a(a1.o a2.o)',
+ '', "ar rv libxx.a a2.o\n$_");
+
+# Touch one of the .o's so it's rebuilt
+utouch(-40, 'a1.o');
+($_ = $repl) =~ s/#OBJECT#/a1.o/g;
+run_make_test(undef, '', "ar rv libxx.a a1.o\n$_");
+
+# Use wildcards
+run_make_test('all: libxx.a(*.o)',
+ '', "#MAKE#: Nothing to be done for 'all'.\n");
+
+# Touch one of the .o's so it's rebuilt
+utouch(-30, 'a1.o');
+($_ = $repl) =~ s/#OBJECT#/a1.o/g;
+run_make_test(undef, '', "ar rv libxx.a a1.o\n$_");
+
+# Use both wildcards and simple names
+utouch(-50, 'a2.o');
+($_ = $add) =~ s/#OBJECT#/a3.o/g;
+$_ .= "ar rv libxx.a a2.o\n";
+($_ .= $repl) =~ s/#OBJECT#/a2.o/g;
+run_make_test('all: libxx.a(a3.o *.o)', '',
+ "ar rv libxx.a a3.o\n$_");
+
+# Check whitespace handling
+utouch(-40, 'a2.o');
+($_ = $repl) =~ s/#OBJECT#/a2.o/g;
+run_make_test('all: libxx.a( a3.o *.o )', '',
+ "ar rv libxx.a a2.o\n$_");
+
+rmfiles(qw(a1.o a2.o a3.o libxx.a));
+
+# Check non-archive targets
+# See Savannah bug #37878
+run_make_test(q!
+all: foo(bar).baz
+foo(bar).baz: ; @echo '$@'
+!,
+ '', "foo(bar).baz\n");
+
+# Check renaming of archive targets.
+# See Savannah bug #38442
+
+mkdir('artest', 0777);
+touch('foo.vhd');
+
+run_make_test(q!
+DIR = artest
+vpath % $(DIR)
+default: lib(foo)
+(%): %.vhd ; @cd $(DIR) && touch $(*F) && $(AR) $(ARFLAGS) $@ $(*F) >/dev/null 2>&1 && rm $(*F)
+.PHONY: default
+!,
+ '', "");
+
+run_make_test(undef, '', "#MAKE#: Nothing to be done for 'default'.\n");
+
+unlink('foo.vhd');
+remove_directory_tree('artest');
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/default_names b/tests/scripts/features/default_names
index e53127e..2e83880 100644
--- a/tests/scripts/features/default_names
+++ b/tests/scripts/features/default_names
@@ -10,32 +10,35 @@ open(MAKEFILE,"> $makefile");
print MAKEFILE "FIRST: ; \@echo It chose GNUmakefile\n";
close(MAKEFILE);
-# DOS/WIN32 platforms preserve case, but Makefile is the same file as makefile.
-# Just test what we can here (avoid Makefile versus makefile test).
-
-if ($port_type eq 'UNIX') {
- # Create another makefile called "makefile"
- open(MAKEFILE,"> makefile");
- print MAKEFILE "SECOND: ; \@echo It chose makefile\n";
- close(MAKEFILE);
-}
-
-# Create another makefile called "Makefile"
-open(MAKEFILE,"> Makefile");
-print MAKEFILE "THIRD: ; \@echo It chose Makefile\n";
+# Create another makefile called "makefile"
+open(MAKEFILE,"> makefile");
+print MAKEFILE "SECOND: ; \@echo It chose makefile\n";
close(MAKEFILE);
+# DOS/WIN32/MacOSX platforms are case-insensitive / case-preserving, so
+# Makefile is the same file as makefile. Just test what we can here.
+
+my $case_sensitive = 0;
+if (! -f 'Makefile') {
+ # Create another makefile called "Makefile"
+ $case_sensitive = 1;
+ open(MAKEFILE,"> Makefile");
+ print MAKEFILE "THIRD: ; \@echo It chose Makefile\n";
+ close(MAKEFILE);
+}
+
+run_make_with_options("","",&get_logfile);
+compare_output("It chose GNUmakefile\n",&get_logfile(1));
+unlink($makefile);
-&run_make_with_options("","",&get_logfile);
-&compare_output("It chose GNUmakefile\n",&get_logfile(1));
-unlink $makefile;
+run_make_with_options("","",&get_logfile);
+compare_output("It chose makefile\n",&get_logfile(1));
+unlink("makefile");
-if ($port_type eq 'UNIX') {
- &run_make_with_options("","",&get_logfile);
- &compare_output("It chose makefile\n",&get_logfile(1));
- unlink "makefile";
+if ($case_sensitive) {
+ run_make_with_options("","",&get_logfile);
+ compare_output("It chose Makefile\n",&get_logfile(1));
+ unlink("Makefile");
}
-&run_make_with_options("","",&get_logfile);
-&compare_output("It chose Makefile\n",&get_logfile(1));
-unlink "Makefile";
+1;
diff --git a/tests/scripts/features/double_colon b/tests/scripts/features/double_colon
index cad605d..1097775 100644
--- a/tests/scripts/features/double_colon
+++ b/tests/scripts/features/double_colon
@@ -151,5 +151,14 @@ two');
unlink('result','one','two');
+# TEST 10: check for proper backslash handling
+# Savannah bug #33399
+
+run_make_test('
+a\ xb :: ; @echo one
+a\ xb :: ; @echo two
+',
+ '', "one\ntwo\n");
+
# This tells the test driver that the perl test script executed properly.
1;
diff --git a/tests/scripts/features/errors b/tests/scripts/features/errors
index e372fe0..c0339cb 100644
--- a/tests/scripts/features/errors
+++ b/tests/scripts/features/errors
@@ -42,15 +42,17 @@ close(MAKEFILE);
unlink("cleanit");
$cleanit_error = `sh -c "$rm_command cleanit 2>&1"`;
+chomp $cleanit_error;
$delete_error_code = $? >> 8;
# TEST #1
# -------
-$answer = "$rm_command cleanit\n"
- . $cleanit_error
- ."$make_name: [clean] Error $delete_error_code (ignored)\n"
- ."$rm_command foo\n";
+$answer = "$rm_command cleanit
+$cleanit_error
+$makefile:2: recipe for target 'clean' failed
+$make_name: [clean] Error $delete_error_code (ignored)
+$rm_command foo\n";
&run_make_with_options($makefile,"",&get_logfile);
@@ -74,10 +76,11 @@ if (!$vos)
# TEST #2
# -------
-$answer = "$rm_command cleanit\n"
- . $cleanit_error
- ."$make_name: [clean2] Error $delete_error_code (ignored)\n"
- ."$rm_command foo\n";
+$answer = "$rm_command cleanit
+$cleanit_error
+$makefile:5: recipe for target 'clean2' failed
+$make_name: [clean2] Error $delete_error_code (ignored)
+$rm_command foo\n";
&run_make_with_options($makefile,"clean2 -i",&get_logfile);
diff --git a/tests/scripts/features/escape b/tests/scripts/features/escape
index 97a2994..bf069df 100644
--- a/tests/scripts/features/escape
+++ b/tests/scripts/features/escape
@@ -2,12 +2,10 @@
$description = "Test various types of escaping in makefiles.";
$details = "\
-Make sure that escaping of `:' works in target names.
+Make sure that escaping of ':' works in target names.
Make sure escaping of whitespace works in target names.
-Make sure that escaping of '#' works.";
-
-
-close(MAKEFILE);
+Make sure that escaping of '#' works.
+Make sure that backslash before non-special characters are kept.";
# TEST 1
@@ -26,7 +24,7 @@ foo\#bar.ext: ; @echo "foo#bar.ext = ($@)"',
run_make_test(undef,
'path=pre:',
- "#MAKEFILE#:2: *** target pattern contains no `%'. Stop.",
+ "#MAKEFILE#:2: *** target pattern contains no '%'. Stop.",
512);
# TEST 3: This one should work, since we escape the ":".
@@ -39,7 +37,7 @@ run_make_test(undef,
run_make_test(undef,
"'path=pre\\\\:'",
- "#MAKEFILE#:2: *** target pattern contains no `%'. Stop.",
+ "#MAKEFILE#:2: *** target pattern contains no '%'. Stop.",
512);
# TEST 5: This one should work
@@ -54,5 +52,23 @@ run_make_test(undef,
'sharp',
'foo#bar.ext = (foo#bar.ext)');
+# Test escaped colons in prerequisites
+# Quoting of backslashes in q!! is kind of messy.
+# Solaris sh does not properly handle backslashes even in '' so just
+# check the output make prints, not what the shell interprets.
+run_make_test(q!
+foo: foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar
+foo foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar: ; : '$@'
+!,
+ '', ": 'foo:bar'\n: 'foo\\:bar'\n: 'foo\\\\:bar'\n: 'foo'\n");
+
+# Test backslash before non-special chars: should be kept as-is
+
+run_make_test(q!
+all: ..\foo
+.DEFAULT: ; : '$@'
+!,
+ '', ": '..\\foo'\n");
+
# This tells the test driver that the perl test script executed properly.
1;
diff --git a/tests/scripts/features/include b/tests/scripts/features/include
index ba8908c..ee014bd 100644
--- a/tests/scripts/features/include
+++ b/tests/scripts/features/include
@@ -1,6 +1,6 @@
# -*-mode: perl; rm-trailing-spaces: nil-*-
-$description = "Test various forms of the GNU make `include' command.";
+$description = "Test various forms of the GNU make 'include' command.";
$details = "\
Test include, -include, sinclude and various regressions involving them.
@@ -60,7 +60,7 @@ run_make_test
error: foo.mk ; @echo $@
',
'',
- "#MAKE#: *** No rule to make target `foo.mk', needed by `error'. Stop.\n",
+ "#MAKE#: *** No rule to make target 'foo.mk', needed by 'error'. Stop.\n",
512
);
@@ -128,7 +128,7 @@ foo: baz
bar: baz
',
'',
-"#MAKE#: *** No rule to make target `baz', needed by `bar'. Stop.\n",
+"#MAKE#: *** No rule to make target 'baz', needed by 'bar'. Stop.\n",
512);
# Test that the diagnostics is issued even if the target has been
@@ -144,7 +144,7 @@ bar: baz
baz: end
',
'',
-"#MAKE#: *** No rule to make target `end', needed by `baz'. Stop.\n",
+"#MAKE#: *** No rule to make target 'end', needed by 'baz'. Stop.\n",
512);
# Test that the diagnostics is issued even if the target has been
@@ -162,7 +162,7 @@ baz: end
',
'',
"#MAKEFILE#:2: bar: No such file or directory
-#MAKE#: *** No rule to make target `end', needed by `baz'. Stop.\n",
+#MAKE#: *** No rule to make target 'end', needed by 'baz'. Stop.\n",
512);
if ($all_tests) {
@@ -172,7 +172,7 @@ if ($all_tests) {
include foo
foo: ; @echo foo = bar > $@
!,
- '', "#MAKE#: `foo' is up to date.\n");
+ '', "#MAKE#: 'foo' is up to date.\n");
rmfiles('foo');
}
diff --git a/tests/scripts/features/jobserver b/tests/scripts/features/jobserver
new file mode 100644
index 0000000..cedd4b3
--- /dev/null
+++ b/tests/scripts/features/jobserver
@@ -0,0 +1,61 @@
+# -*-perl-*-
+
+$description = "Test jobserver.";
+
+$details = "These tests are ones that specifically are different when the
+jobserver feature is available. Most -j tests are the same whether or not
+jobserver is available, and those appear in the 'parallelism' test suite.";
+
+exists $FEATURES{'jobserver'} or return -1;
+
+if (!$parallel_jobs) {
+ return -1;
+}
+
+# Don't put --jobserver-fds into a re-exec'd MAKEFLAGS.
+# We can't test this directly because there's no way a makefile can
+# show the value of MAKEFLAGS we were re-exec'd with. We can intuit it
+# by looking for "disabling jobserver mode" warnings; we should only
+# get one from the original invocation and none from the re-exec.
+# See Savannah bug #18124
+
+unlink('inc.mk');
+
+run_make_test(q!
+-include inc.mk
+recur:
+# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
+ @rm -f inc.mk
+ @$(MAKE) -j2 -f #MAKEFILE# all
+all:
+# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
+ @echo $@
+inc.mk:
+# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
+ @echo 'FOO = bar' > $@
+!,
+ '--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
+
+unlink('inc.mk');
+
+# Test recursion when make doesn't think it exists.
+# See Savannah bug #39934
+# Or Red Hat bug https://bugzilla.redhat.com/show_bug.cgi?id=885474
+
+open(MAKEFILE,"> Makefile2");
+print MAKEFILE '
+vpath %.c ../
+foo:
+';
+close(MAKEFILE);
+
+run_make_test(q!
+default: ; @ #MAKEPATH# -f Makefile2
+!,
+ '-j2 --no-print-directory',
+"#MAKE#[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
+#MAKE#[1]: Nothing to be done for 'foo'.");
+
+rmfiles('Makefile2');
+
+1;
diff --git a/tests/scripts/features/load b/tests/scripts/features/load
new file mode 100644
index 0000000..2e3f263
--- /dev/null
+++ b/tests/scripts/features/load
@@ -0,0 +1,102 @@
+# -*-perl-*-
+$description = "Test the load operator.";
+
+$details = "Test dynamic loading of modules.";
+
+# Don't do anything if this system doesn't support "load"
+exists $FEATURES{load} or return -1;
+
+my $sobuild = '$(CC) '.($srcdir? "-I$srcdir":'').' -g -shared -fPIC -o $@ $<';
+
+# First build a shared object
+# Provide both a default and non-default load symbol
+
+unlink(qw(testload.c testload.so));
+
+open(my $F, '> testload.c') or die "open: testload.c: $!\n";
+print $F <<'EOF' ;
+#include <string.h>
+#include <stdio.h>
+
+#include "gnumake.h"
+
+int plugin_is_GPL_compatible;
+
+int
+testload_gmk_setup (gmk_floc *pos)
+{
+ gmk_eval ("TESTLOAD = implicit", 0);
+ return 1;
+}
+
+int
+explicit_setup (gmk_floc *pos)
+{
+ gmk_eval ("TESTLOAD = explicit", 0);
+ return 1;
+}
+EOF
+close($F) or die "close: testload.c: $!\n";
+
+# Make sure we can compile
+run_make_test('testload.so: testload.c ; @'.$sobuild, '', '');
+
+# TEST 1
+run_make_test(q!
+PRE := $(.LOADED)
+load testload.so
+POST := $(.LOADED)
+all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
+!,
+ '', "pre= post=testload.so implicit\n");
+
+# TEST 2
+# Load using an explicit function
+run_make_test(q!
+PRE := $(.LOADED)
+load ./testload.so(explicit_setup)
+POST := $(.LOADED)
+all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
+!,
+ '', "pre= post=testload.so explicit\n");
+
+# TEST 4
+# Check multiple loads
+run_make_test(q!
+PRE := $(.LOADED)
+load ./testload.so
+load testload.so(explicit_setup)
+POST := $(.LOADED)
+all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
+!,
+ '', "pre= post=testload.so implicit\n");
+
+# TEST 5
+# Check auto-rebuild of loaded file that's out of date
+utouch(-10, 'testload.so');
+touch('testload.c');
+
+run_make_test(q!
+PRE := $(.LOADED)
+load ./testload.so
+POST := $(.LOADED)
+all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
+testload.so: testload.c ; @echo "rebuilding $@"; !.$sobuild,
+ '', "rebuilding testload.so\npre= post=testload.so implicit\n");
+
+# TEST 5
+# Check auto-rebuild of loaded file when it doesn't exist
+unlink('testload.so');
+
+run_make_test(q!
+PRE := $(.LOADED)
+-load ./testload.so(explicit_setup)
+POST := $(.LOADED)
+all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
+%.so: %.c ; @echo "rebuilding $@"; !.$sobuild,
+ '', "rebuilding testload.so\npre= post=testload.so explicit\n");
+
+unlink(qw(testload.c testload.so)) unless $keep;
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/loadapi b/tests/scripts/features/loadapi
new file mode 100644
index 0000000..6d3b03f
--- /dev/null
+++ b/tests/scripts/features/loadapi
@@ -0,0 +1,112 @@
+# -*-perl-*-
+$description = "Test the shared object load API.";
+
+$details = "Verify the different aspects of the shared object API.";
+
+# Don't do anything if this system doesn't support "load"
+exists $FEATURES{load} or return -1;
+
+my $sobuild = '$(CC) '.($srcdir? "-I$srcdir":'').' -g -shared -fPIC -o $@ $<';
+
+# First build a shared object
+# Provide both a default and non-default load symbol
+
+unlink(qw(testapi.c testapi.so));
+
+open(my $F, '> testapi.c') or die "open: testapi.c: $!\n";
+print $F <<'EOF' ;
+#include <string.h>
+#include <stdio.h>
+
+#include "gnumake.h"
+
+int plugin_is_GPL_compatible;
+
+static char *
+test_eval (const char *buf)
+{
+ gmk_eval (buf, 0);
+ return NULL;
+}
+
+static char *
+test_expand (const char *val)
+{
+ return gmk_expand (val);
+}
+
+static char *
+test_noexpand (const char *val)
+{
+ char *str = gmk_alloc (strlen (val));
+ strcpy (str, val);
+ return str;
+}
+
+static char *
+func_test (const char *funcname, unsigned int argc, char **argv)
+{
+ char *mem;
+
+ if (strcmp (funcname, "test-expand") == 0)
+ return test_expand (argv[0]);
+
+ if (strcmp (funcname, "test-eval") == 0)
+ return test_eval (argv[0]);
+
+ if (strcmp (funcname, "test-noexpand") == 0)
+ return test_noexpand (argv[0]);
+
+ mem = gmk_alloc (sizeof ("unknown"));
+ strcpy (mem, "unknown");
+ return mem;
+}
+
+int
+testapi_gmk_setup ()
+{
+ gmk_add_function ("test-expand", func_test, 1, 1, GMK_FUNC_DEFAULT);
+ gmk_add_function ("test-noexpand", func_test, 1, 1, GMK_FUNC_NOEXPAND);
+ gmk_add_function ("test-eval", func_test, 1, 1, GMK_FUNC_DEFAULT);
+ gmk_add_function ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.", func_test, 0, 0, 0);
+ return 1;
+}
+EOF
+close($F) or die "close: testapi.c: $!\n";
+
+run_make_test('testapi.so: testapi.c ; @'.$sobuild, '', '');
+
+# TEST 1
+# Check the gmk_expand() function
+run_make_test(q!
+EXPAND = expansion
+all: ; @echo $(test-expand $$(EXPAND))
+load testapi.so
+!,
+ '', "expansion\n");
+
+# TEST 2
+# Check the eval operation. Prove that the argument is expanded only once
+run_make_test(q!
+load testapi.so
+TEST = bye
+ASSIGN = VAR = $(TEST) $(shell echo there)
+$(test-eval $(value ASSIGN))
+TEST = hi
+all:;@echo '$(VAR)'
+!,
+ '', "hi there\n");
+
+# TEST 2
+# Check the no-expand capability
+run_make_test(q!
+load testapi.so
+TEST = hi
+all:;@echo '$(test-noexpand $(TEST))'
+!,
+ '', "\$(TEST)\n");
+
+unlink(qw(testapi.c testapi.so)) unless $keep;
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/mult_rules b/tests/scripts/features/mult_rules
index 6f120f1..e706e17 100644
--- a/tests/scripts/features/mult_rules
+++ b/tests/scripts/features/mult_rules
@@ -47,7 +47,7 @@ else
$error_code);
# Create the answer to what should be produced by this Makefile
-$answer = "$make_name: *** No rule to make target `extra.h', needed by `foo.o'. Stop.\n";
+$answer = "$make_name: *** No rule to make target 'extra.h', needed by 'foo.o'. Stop.\n";
&compare_output($answer,&get_logfile(1));
diff --git a/tests/scripts/features/output-sync b/tests/scripts/features/output-sync
new file mode 100644
index 0000000..75d7e81
--- /dev/null
+++ b/tests/scripts/features/output-sync
@@ -0,0 +1,334 @@
+# -*-perl-*-
+
+$description = "Test --output-sync (-O) option.";
+
+$details = "Test the synchronization of output from parallel jobs.";
+
+# If we don't have output sync support, never mind.
+exists $FEATURES{'output-sync'} or return -1;
+
+# Output sync can't be tested without parallelization
+$parallel_jobs or return -1;
+
+
+if ($vos) {
+ $sleep_command = "sleep -seconds";
+}
+else {
+ $sleep_command = "sleep";
+}
+
+# The following subdirectories with Makefiles are used in several
+# of the following tests. The model is:
+# foo/Makefile - has a "foo" target that waits for the bar target
+# bar/Makefile - has a "bar" target that runs immediately
+# - has a "baz" target that waits for the foo target
+#
+# So, you start the two sub-makes in parallel and first the "bar" target is
+# built, followed by "foo", followed by "baz". The trick is that first each
+# target prints a "start" statement, then waits (if appropriate), then prints
+# an end statement. Thus we can tell if the -O flag is working, since
+# otherwise these statements would be mixed together.
+
+@syncfiles = ();
+
+sub output_sync_clean {
+ rmfiles('foo/Makefile', 'bar/Makefile', @syncfiles);
+ rmdir('foo');
+ rmdir('bar');
+}
+
+# We synchronize the different jobs by having them wait for a sentinel file to
+# be created, instead of relying on a certain amount of time passing.
+# Unfortunately in this test we have to sleep after we see the sync file,
+# since we also want to make the obtaining of the write synchronization lock
+# reliable. If things are too fast, then sometimes a different job will steal
+# the output sync lock and the output is mis-ordered from what we expect.
+sub output_sync_wait {
+ return "while [ ! -f ../mksync.$_[0] ]; do :; done; rm -f ../mksync.$_[0].wait; $sleep_command 1";
+}
+sub output_sync_set {
+ return "date > ../mksync.$_[0]";
+}
+
+@syncfiles = qw(mksync.foo mksync.foo_start mksync.bar mksync.bar_start);
+
+output_sync_clean();
+mkdir('foo', 0777);
+mkdir('bar', 0777);
+
+$set_foo = output_sync_set('foo');
+$set_bar = output_sync_set('bar');
+$set_foo_start = output_sync_set('foo_start');
+$set_bar_start = output_sync_set('bar_start');
+
+$wait_foo = output_sync_wait('foo');
+$wait_bar = output_sync_wait('bar');
+$wait_foo_start = output_sync_set('foo_start');
+$wait_bar_start = output_sync_set('bar_start');
+
+open(MAKEFILE,"> foo/Makefile");
+print MAKEFILE <<EOF;
+all: foo
+
+foo: foo-base ; \@$set_foo
+
+foo-base:
+\t\@echo foo: start
+\t\@$wait_bar
+\t\@echo foo: end
+
+foo-job: foo-job-base ; \@$set_foo
+
+foo-job-base:
+\t\@$wait_bar_start
+\t\@echo foo: start
+\t\@$set_foo_start
+\t\@$wait_bar
+\t\@echo foo: end
+
+foo-fail:
+\t\@echo foo-fail: start
+\t\@$wait_bar
+\t\@echo foo-fail: end
+\t\@exit 1
+EOF
+close(MAKEFILE);
+
+open(MAKEFILE,"> bar/Makefile");
+print MAKEFILE <<EOF;
+all: bar baz
+
+bar: bar-base ; \@$set_bar
+bar-base:
+\t\@echo bar: start
+\t\@echo bar: end
+
+bar-job: bar-job-base ; \@$set_bar
+
+bar-job-base:
+\t\@echo bar: start
+\t\@$set_bar_start
+\t\@$wait_foo_start
+\t\@echo bar: end
+
+baz: baz-base
+baz-base:
+\t\@echo baz: start
+\t\@$wait_foo
+\t\@echo baz: end
+EOF
+close(MAKEFILE);
+
+# Test per-make synchronization.
+unlink(@syncfiles);
+run_make_test(qq!
+all: make-foo make-bar
+
+make-foo: ; \$(MAKE) -C foo
+
+make-bar: ; \$(MAKE) -C bar!,
+ '-j -Orecurse',
+"#MAKEPATH# -C foo
+#MAKE#[1]: Entering directory '#PWD#/foo'
+foo: start
+foo: end
+#MAKE#[1]: Leaving directory '#PWD#/foo'
+#MAKEPATH# -C bar
+#MAKE#[1]: Entering directory '#PWD#/bar'
+bar: start
+bar: end
+baz: start
+baz: end
+#MAKE#[1]: Leaving directory '#PWD#/bar'\n", 0, 6);
+
+# Test per-target synchronization.
+# Note we have to sleep again here after starting the foo makefile before
+# starting the bar makefile, otherwise the "entering/leaving" messages for the
+# submakes might be ordered differently than we expect.
+
+unlink(@syncfiles);
+run_make_test(qq!
+x=1
+\$xMAKEFLAGS += --no-print-directory
+
+all: make-foo make-bar
+
+make-foo: ; \$(MAKE) -C foo
+
+make-bar: ; $sleep_command 1 ; \$(MAKE) -C bar!,
+ '-j --output-sync=target',
+"#MAKEPATH# -C foo
+$sleep_command 1 ; #MAKEPATH# -C bar
+#MAKE#[1]: Entering directory '#PWD#/bar'
+bar: start
+bar: end
+#MAKE#[1]: Leaving directory '#PWD#/bar'
+#MAKE#[1]: Entering directory '#PWD#/foo'
+foo: start
+foo: end
+#MAKE#[1]: Leaving directory '#PWD#/foo'
+#MAKE#[1]: Entering directory '#PWD#/bar'
+baz: start
+baz: end
+#MAKE#[1]: Leaving directory '#PWD#/bar'\n", 0, 6);
+
+# Rerun but this time suppress the directory tracking
+unlink(@syncfiles);
+run_make_test(undef, '-j --output-sync=target x=',
+ "#MAKEPATH# -C foo
+$sleep_command 1 ; #MAKEPATH# -C bar
+bar: start
+bar: end
+foo: start
+foo: end
+baz: start
+baz: end\n", 0, 6);
+
+# Test that messages from make itself are enclosed with
+# "Entering/Leaving directory" messages.
+unlink(@syncfiles);
+run_make_test(qq!
+all: make-foo-fail make-bar-bar
+
+make-foo-fail: ; \$(MAKE) -C foo foo-fail
+
+make-bar-bar: ; $sleep_command 1 ; \$(MAKE) -C bar bar!,
+ '-j -O',
+"#MAKEPATH# -C foo foo-fail
+$sleep_command 1 ; #MAKEPATH# -C bar bar
+#MAKE#[1]: Entering directory '#PWD#/bar'
+bar: start
+bar: end
+#MAKE#[1]: Leaving directory '#PWD#/bar'
+#MAKE#[1]: Entering directory '#PWD#/foo'
+foo-fail: start
+foo-fail: end
+Makefile:20: recipe for target 'foo-fail' failed
+#MAKE#[1]: *** [foo-fail] Error 1
+#MAKE#[1]: Leaving directory '#PWD#/foo'
+#MAKEFILE#:4: recipe for target 'make-foo-fail' failed
+#MAKE#: *** [make-foo-fail] Error 2\n",
+512);
+
+# Test the per-job synchronization.
+# For this we'll have bar-job:
+# print start, invoke bar-start, wait for foo-start, print end, print-bar-end
+# And foo-job:
+# wait for bar-start, print foo-start, wait for bar-end, print end
+
+unlink(@syncfiles);
+run_make_test(qq!
+all: make-foo make-bar
+
+make-foo: ; \$(MAKE) -C foo foo-job
+
+make-bar: ; $sleep_command 1 ; \$(MAKE) -C bar bar-job!,
+ '-j --output-sync=line',
+"#MAKEPATH# -C foo foo-job
+$sleep_command 1 ; #MAKEPATH# -C bar bar-job
+#MAKE#[1]: Entering directory '#PWD#/foo'
+foo: start
+#MAKE#[1]: Leaving directory '#PWD#/foo'
+#MAKE#[1]: Entering directory '#PWD#/bar'
+bar: start
+#MAKE#[1]: Leaving directory '#PWD#/bar'
+#MAKE#[1]: Entering directory '#PWD#/bar'
+bar: end
+#MAKE#[1]: Leaving directory '#PWD#/bar'
+#MAKE#[1]: Entering directory '#PWD#/foo'
+foo: end
+#MAKE#[1]: Leaving directory '#PWD#/foo'\n", 0, 6);
+
+
+# Remove temporary directories and contents.
+output_sync_clean();
+
+# Ensure recursion doesn't mis-order or double-print output
+run_make_test(qq!
+all:
+\t\@echo foo
+\t\@+echo bar
+!,
+ '-j -Oline', "foo\nbar\n");
+
+run_make_test(undef, '-j -Otarget', "foo\nbar\n");
+
+# Ensure when make writes out command it's not misordered
+run_make_test(qq!
+all:
+\t\@echo foobar
+\ttrue
+!,
+ '-j -Oline', "foobar\ntrue\n");
+
+run_make_test(undef, '-j -Otarget', "foobar\ntrue\n");
+
+# Ensure that shell functions inside recipes write stderr to the sync file
+run_make_test(q!
+all: ; @: $(shell echo foo 1>&2)
+!,
+ '-w -Oline', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n");
+
+# Ensure that output generated while parsing makefiles is synced
+# when appropriate.
+run_make_test(q!
+$(shell echo foo 1>&2)
+all: ; echo bar
+!,
+ '-s -w -Otarget', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n#MAKE#: Entering directory '#PWD#'\nbar\n#MAKE#: Leaving directory '#PWD#'\n");
+
+# Test recursion
+$m1 = get_tmpfile();
+$m2 = get_tmpfile();
+
+open(M1, "> $m1");
+print M1 <<'EOF';
+$(shell echo d1 stderr 1>&2)
+$(info d1 stdout)
+all:; @:
+EOF
+close(M1);
+
+open(M2, "> $m2");
+print M2 <<'EOF';
+$(shell echo d2 stderr 1>&2)
+$(info d2 stdout)
+all:; @:
+# Force an ordering on the output
+$(shell sleep 1)
+EOF
+close(M2);
+
+run_make_test(qq!
+all: t1 t2
+t1: ; \@\$(MAKE) -f $m1
+t2: ; \@\$(MAKE) -f $m2
+!,
+ "-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKE#[1]: Entering directory '#PWD#'\nd2 stderr\nd2 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n");
+
+rmfiles($m1, $m2);
+
+# Ensure that output generated while parsing makefiles is synced
+# when appropriate.
+$m1 = get_tmpfile();
+
+open(M1, "> $m1");
+print M1 <<'EOF';
+$(shell echo d1 stderr 1>&2)
+$(info d1 stdout)
+$(error d1 failed)
+all:; @:
+EOF
+close(M1);
+
+run_make_test(qq!
+all: t1
+t1: ; -\@\$(MAKE) -f $m1
+!,
+ "-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n$m1:3: *** d1 failed. Stop.\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKEFILE#:3: recipe for target 't1' failed\n#MAKE#: [t1] Error 2 (ignored)\n");
+
+rmfiles($m1);
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/parallelism b/tests/scripts/features/parallelism
index cc0f84f..c702c26 100644
--- a/tests/scripts/features/parallelism
+++ b/tests/scripts/features/parallelism
@@ -41,7 +41,7 @@ all: 1 2; \@echo success
1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@
2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@",
"-j4",
- "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n");
+ "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n", 0, 7);
rmfiles(qw(1.inc 2.inc));
@@ -60,7 +60,7 @@ endif
1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@
2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@",
"-j4",
- "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n");
+ "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n", 0, 7);
rmfiles(qw(1.inc 2.inc));
@@ -91,21 +91,24 @@ run_make_test("
all: fail.1 ok fail.2 fail.3
fail.1 fail.2 fail.3:
- \@sleep \$(patsubst fail.%,%,\$\@)
+ \@$sleep_command \$(patsubst fail.%,%,\$\@)
\@echo Fail
\@exit 1
ok:
- \@sleep 4
+ \@$sleep_command 4
\@echo Ok done",
- '-rR -j5', 'Fail
+ '-rR -j5', "Fail
+#MAKEFILE#:6: recipe for target 'fail.1' failed
#MAKE#: *** [fail.1] Error 1
#MAKE#: *** Waiting for unfinished jobs....
Fail
+#MAKEFILE#:6: recipe for target 'fail.2' failed
#MAKE#: *** [fail.2] Error 1
Fail
+#MAKEFILE#:6: recipe for target 'fail.3' failed
#MAKE#: *** [fail.3] Error 1
-Ok done',
+Ok done",
512);
@@ -140,81 +143,40 @@ intermed: | phony ; touch $@
phony: ; : phony', '-rR -j', ': phony');
rmfiles('target');
-# TEST #10: Don't put --jobserver-fds into a re-exec'd MAKEFLAGS.
-# We can't test this directly because there's no way a makefile can
-# show the value of MAKEFLAGS we were re-exec'd with. We can intuit it
-# by looking for "disabling jobserver mode" warnings; we should only
-# get one from the original invocation and none from the re-exec.
-# See Savannah bug #18124
+# TEST #11: Make sure -jN from MAKEFLAGS is processed even when we re-exec
+# See Savannah bug #33873
+
+$extraENV{MAKEFLAGS} = '-j4';
run_make_test(q!
+things = thing1 thing2
+all: $(things)
+thing1:; @sleep 1; echo '$@ start'; sleep 2; echo '$@ end'
+thing2:; @echo '$@ start'; sleep 2; echo '$@ end'
-include inc.mk
-recur:
-# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
- @rm -f inc.mk
- @$(MAKE) -j2 -f #MAKEFILE# all
-all:
-# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
- @echo $@
-inc.mk:
-# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
- @echo 'FOO = bar' > $@
+inc.mk: ; @touch $@
!,
- '--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
+ '', "thing2 start\nthing1 start\nthing2 end\nthing1 end\n");
+delete $extraENV{MAKEFLAGS};
rmfiles('inc.mk');
-if ($all_tests) {
- # Implicit files aren't properly recreated during parallel builds
- # Savannah bug #26864
+# Ensure intermediate/secondary files are not pruned incorrectly.
+# See Savannah bug #30653
- # The first run works fine
- run_make_test(q!
-%.bar: %.x foo.y ; cat $^ > $@
-%.x: ; touch $@
-foo.y: foo.y.in ; cp $< $@
-foo.y.in: ; touch $@
-!,
- '-j2 main.bar',
- "touch foo.y.in
-touch main.x
-cp foo.y.in foo.y
-cat main.x foo.y > main.bar
-rm main.x");
-
- # Now we touch the .in file and make sure it still works
- touch('foo.y.in');
-
- run_make_test(undef, '-j2 main.bar', "cp foo.y.in foo.y
-touch main.x
-cat main.x foo.y > main.bar
-rm main.x");
-
- # Clean up
- rmfiles(qw(foo.y foo.y.in main.bar));
-}
+utouch(-15, 'file2');
+utouch(-10, 'file4');
+utouch(-5, 'file1');
-if ($all_tests) {
- # Jobserver FD handling is messed up in some way.
- # Savannah bug #28189
- # It doesn't look like that bug anymore but this is the code it runs
-
- run_make_test(q!
-ifdef EXTRA
-vpath %.dst /
-xxx.dst: ; true
-yyy.dst: ; true
-endif
-
-M := $(MAKE)
-xx: ; $M --no-print-directory -j2 -f $(MAKEFILE_LIST) xxx.dst yyy.dst EXTRA=1
+run_make_test(q!
+.INTERMEDIATE: file3
+file4: file3 ; @mv -f $< $@
+file3: file2 ; touch $@
+file2: file1 ; @touch $@
!,
- '-j2',
- '#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.
-true
-true
-');
-}
+ '--no-print-directory -j2', "touch file3");
+
+rmfiles('file1', 'file2', 'file3', 'file4');
# Make sure that all jobserver FDs are closed if we need to re-exec the
# master copy.
diff --git a/tests/scripts/features/patspecific_vars b/tests/scripts/features/patspecific_vars
index 8ca228d..a530bba 100644
--- a/tests/scripts/features/patspecific_vars
+++ b/tests/scripts/features/patspecific_vars
@@ -81,7 +81,7 @@ all: bar baz
b%: pattern := good $$t
-global := orginal $$t
+global := original $$t
# normal target
@@ -103,14 +103,14 @@ else
%z: a := global: $(global) pattern: $(pattern) inherit: $(inherit)
endif
-%z: ; @echo \'pattrn: $a;\'
+%z: ; @echo \'pattern: $a;\'
global := new $$t
',
'',
-'normal: global: orginal $t pattern: inherit: ;
-pattrn: global: orginal $t pattern: inherit: ;');
+'normal: global: original $t pattern: inherit: ;
+pattern: global: original $t pattern: inherit: ;');
# TEST #7 -- test expansion of pattern-specific recursive variables
@@ -118,7 +118,7 @@ pattrn: global: orginal $t pattern: inherit: ;');
run_make_test(undef, # reuse previous makefile
'rec=1',
'normal: global: new $t pattern: good $t inherit: good $t;
-pattrn: global: new $t pattern: good $t inherit: good $t;');
+pattern: global: new $t pattern: good $t inherit: good $t;');
# TEST #8: override in pattern-specific variables
diff --git a/tests/scripts/features/patternrules b/tests/scripts/features/patternrules
index eebe7c0..0ff49a7 100644
--- a/tests/scripts/features/patternrules
+++ b/tests/scripts/features/patternrules
@@ -110,7 +110,8 @@ $(dir)/foo.bar:
',
"dir=$dir",
-"#MAKE#: *** [$dir/foo.bar] Error 1",
+"#MAKEFILE#:6: recipe for target '$dir/foo.bar' failed
+#MAKE#: *** [$dir/foo.bar] Error 1",
512);
unlink("$dir/foo.bar");
@@ -203,7 +204,7 @@ CWEAVE := :
%.tex : %.w %.ch
!,
'foo.tex',
- "#MAKE#: *** No rule to make target `foo.tex'. Stop.", 512);
+ "#MAKE#: *** No rule to make target 'foo.tex'. Stop.", 512);
unlink(@f);
diff --git a/tests/scripts/features/recursion b/tests/scripts/features/recursion
index a6b8f90..fd5e351 100644
--- a/tests/scripts/features/recursion
+++ b/tests/scripts/features/recursion
@@ -18,7 +18,7 @@ last:
',
('CFLAGS=-O -w' . ($parallel_jobs ? ' -j 2' : '')),
($vos
- ? "#MAKE#: Entering directory `#PWD#'
+ ? "#MAKE#: Entering directory '#PWD#'
make 'CFLAGS=-O' -f #MAKEFILE# foo
make CFLAGS=-O
MAKELEVEL = 0
@@ -26,20 +26,20 @@ make 'CFLAGS=-O' -f #MAKEFILE# last
make CFLAGS=-O
MAKELEVEL = 0
THE END
-#MAKE#: Leaving directory `#PWD#'"
- : "#MAKE#: Entering directory `#PWD#'
+#MAKE#: Leaving directory '#PWD#'"
+ : "#MAKE#: Entering directory '#PWD#'
#MAKEPATH# -f #MAKEFILE# foo
-#MAKE#[1]: Entering directory `#PWD#'
+#MAKE#[1]: Entering directory '#PWD#'
#MAKEPATH#
MAKELEVEL = 1
#MAKEPATH# -f #MAKEFILE# last
-#MAKE#[2]: Entering directory `#PWD#'
+#MAKE#[2]: Entering directory '#PWD#'
#MAKEPATH#
MAKELEVEL = 2
THE END
-#MAKE#[2]: Leaving directory `#PWD#'
-#MAKE#[1]: Leaving directory `#PWD#'
-#MAKE#: Leaving directory `#PWD#'"));
+#MAKE#[2]: Leaving directory '#PWD#'
+#MAKE#[1]: Leaving directory '#PWD#'
+#MAKE#: Leaving directory '#PWD#'"));
# Test command line overrides.
diff --git a/tests/scripts/features/reinvoke b/tests/scripts/features/reinvoke
index 9952ced..eb1a349 100644
--- a/tests/scripts/features/reinvoke
+++ b/tests/scripts/features/reinvoke
@@ -57,9 +57,24 @@ include $(F)',
# Now try with the file we're not updating being the actual file we're
# including: this and the previous one test different parts of the code.
-run_make_test(undef, "F=b", "[ -f b ] || echo >> b\nhello\n")
+run_make_test(undef, 'F=b', "[ -f b ] || echo >> b\nhello\n")
&rmfiles('a','b','c');
+# Ensure command line variables are preserved properly across re-exec
+# Tests for Savannah bug #30723
+
+run_make_test('
+ifdef RECURSE
+-include foo30723
+endif
+recurse: ; @$(MAKE) -f $(MAKEFILE_LIST) RECURSE=1 test
+test: ; @echo F.O=$(F.O)
+foo30723: ; @touch $@
+',
+ '--no-print-directory F.O=bar', "F.O=bar\n");
+
+unlink('foo30723');
+
# This tells the test driver that the perl test script executed properly.
1;
diff --git a/tests/scripts/features/rule_glob b/tests/scripts/features/rule_glob
new file mode 100644
index 0000000..2d377e7
--- /dev/null
+++ b/tests/scripts/features/rule_glob
@@ -0,0 +1,37 @@
+# -*-perl-*-
+
+$description = "Test globbing in targets and prerequisites.";
+
+$details = "";
+
+touch(qw(a.one a.two a.three));
+
+# Test wildcards in regular targets and prerequisites
+run_make_test(q{
+.PHONY: all a.one a.two a.three
+all: a.one* a.t[a-z0-9]o a.th[!q]ee
+a.o[Nn][Ee] a.t*: ; @echo $@
+},
+ '', "a.one\na.two\na.three");
+
+# Test wildcards in pattern targets and prerequisites
+run_make_test(q{
+.PHONY: all
+all: a.four
+%.four : %.t* ; @echo $@: $(sort $^)
+},
+ '', "a.four: a.three a.two");
+
+# Test wildcards in second expansion targets and prerequisites
+run_make_test(q{
+.PHONY: all
+all: a.four
+.SECONDEXPANSION:
+%.four : $$(sort %.t*) ; @echo $@: $(sort $^)
+},
+ '', "a.four: a.three a.two");
+
+unlink(qw(a.one a.two a.three));
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/se_explicit b/tests/scripts/features/se_explicit
index 79e0a36..790017a 100644
--- a/tests/scripts/features/se_explicit
+++ b/tests/scripts/features/se_explicit
@@ -6,6 +6,9 @@ $details = "";
# TEST #0: Test handing of '$' in prerequisites with and without second
# expansion.
+# If we don't support archives then the prerequisite is different
+my $prereq = exists $FEATURES{'archives'} ? '$' : '$(PRE)';
+
run_make_test(q!
ifdef SE
.SECONDEXPANSION:
@@ -18,7 +21,7 @@ PRE = three four
.DEFAULT: ; @echo '$@'
!,
'',
- "\$\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz");
+ "$prereq\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz");
run_make_test(undef, 'SE=1', "three\nfour\nbariz\nfoo\$bar : baraz bariz");
@@ -115,7 +118,7 @@ run_make_test(q!
.SECONDEXPANSION:
all : $$(eval $$(info test))
!,
- '', "test\n#MAKE#: Nothing to be done for `all'.\n");
+ '', "test\n#MAKE#: Nothing to be done for 'all'.\n");
# TEST #5: (NEGATIVE) catch eval in a prereq list trying to create new
# target/prereq relationships.
@@ -152,5 +155,13 @@ a%l: q1x $$+ q2x ; @echo '$+'
'', "q1x bar bar q2x bar bar\n");
-# This tells the test driver that the perl test script executed properly.
+# Allow patsubst shorthand in second expansion context.
+# Requires the colon to be quoted. Savannah bug #16545
+run_make_test(q!
+.PHONY: foo.bar
+.SECONDEXPANSION:
+foo: $$(@\\:%=%.bar); @echo '$^'
+!,
+ '', "foo.bar\n");
+
1;
diff --git a/tests/scripts/features/se_implicit b/tests/scripts/features/se_implicit
index e9acb2f..ec09d8d 100644
--- a/tests/scripts/features/se_implicit
+++ b/tests/scripts/features/se_implicit
@@ -222,5 +222,39 @@ foo.o:
!,
'', "\n");
+# Test #10: Test second expansion with second expansion prerequisites
+# Ensures pattern_search() recurses with SE prereqs.
+touch('a');
+run_make_test(q!
+.SECONDEXPANSION:
+sim_base_rgg := just_a_name
+sim_base_src := a
+sim_base_f := a a a
+sim_%.f: $${sim_$$*_f}
+ echo $@
+sim_%.src: $${sim_$$*_src}
+ echo $@
+sim_%: \
+ $$(if $$(sim_$$*_src),sim_%.src) \
+ $$(if $$(sim_$$*_f),sim_%.f) \
+ $$(if $$(sim_$$*_rgg),$$(sim_$$*_rgg).s)
+ echo $@
+!,
+ '-s sim_base', "#MAKE#: *** No rule to make target 'sim_base'. Stop.", 512);
+
+unlink('a');
+
+# Ensure that order-only tokens embedded in second expansions are parsed
+run_make_test(q!
+.SECONDEXPANSION:
+PREREQS=p1|p2
+P2=p2
+all : foo bar
+f%o: $$(PREREQS) ; @echo '$@' from '$^' and '$|'
+b%r: p1|$$(P2) ; @echo '$@' from '$^' and '$|'
+p% : ; : $@
+!,
+ "", ": p1\n: p2\nfoo from p1 and p2\nbar from p1 and p2\n");
+
# This tells the test driver that the perl test script executed properly.
1;
diff --git a/tests/scripts/features/shell_assignment b/tests/scripts/features/shell_assignment
new file mode 100644
index 0000000..686e4bd
--- /dev/null
+++ b/tests/scripts/features/shell_assignment
@@ -0,0 +1,65 @@
+# -*-perl-*-
+
+$description = "Test BSD-style shell assignments (VAR != VAL) for variables.";
+
+$details = "";
+
+# TEST 0: Basic shell assignment (!=).
+
+run_make_test('
+.POSIX:
+
+demo1!=printf \' 1 2 3\n4\n\n5 \n \n 6\n\n\n\n\'
+demo2 != printf \'7 8\n \'
+demo3 != printf \'$$(demo2)\'
+demo4 != printf \' 2 3 \n\'
+demo5 != printf \' 2 3 \n\n\'
+all: ; @echo "<$(demo1)> <$(demo2)> <$(demo3)> <$(demo4)> <${demo5}>"
+',
+ '', "< 1 2 3 4 5 6 > <7 8 > <7 8 > < 2 3 > < 2 3 >\n");
+
+# TEST 1: Handle '#' the same way as BSD make
+
+run_make_test('
+foo1!=echo bar#baz
+hash != printf \'\043\'
+foo2!= echo "bar$(hash)baz"
+
+all: ; @echo "<$(foo1)> <$(hash)> <$(foo2)>"
+',
+ '', "<bar> <#> <bar#baz>\n");
+
+# TEST 2: shell assignment variables (from !=) should be recursive.
+# Note that variables are re-evaluated later, so the shell can output
+# a value like $(XYZZY) as part of !=. The $(XYZZY) will be EVALUATED
+# when the value containing it is evaluated. On the negative side, this
+# means if you don't want this, you need to escape dollar signs as $$.
+# On the positive side, it means that shell programs can output macros
+# that are then evaluated as they are traditionally evaluated.. and that
+# you can use traditional macro evaluation semantics to implement !=.
+
+run_make_test('
+XYZZY = fiddle-dee-dee
+dollar = $$
+VAR3 != printf \'%s\' \'$(dollar)(XYZZY)\'
+
+all: ; @echo "<$(VAR3)>"
+',
+ '', "<fiddle-dee-dee>\n");
+
+
+# TEST 3: Overrides invoke shell anyway; they just don't store the result
+# in a way that is visible.
+
+run_make_test('
+
+override != echo abc > ,abc ; cat ,abc
+
+all: ; @echo "<$(override)>" ; cat ,abc
+',
+ 'override=xyz', "<xyz>\nabc\n");
+
+unlink(',abc');
+
+
+1;
diff --git a/tests/scripts/features/targetvars b/tests/scripts/features/targetvars
index ddd6c1f..a9b8dbe 100644
--- a/tests/scripts/features/targetvars
+++ b/tests/scripts/features/targetvars
@@ -237,10 +237,20 @@ a: ; @echo "$(FOO)"
run_make_test(undef, 'FOO=C', "C f1\n");
+# TEST #19: Conditional variables with command-line settings
+
+run_make_test('
+a: FOO ?= f1
+a: ; @echo "$(FOO)"
+',
+ '', "f1\n");
+
+run_make_test(undef, 'FOO=C', "C\n");
+
# TEST #20: Check for continuation after semicolons
run_make_test(q!
-a: A = 'hello; \
+a: A = 'hello;\
world'
a: ; @echo $(A)
!,
diff --git a/tests/scripts/features/utf8 b/tests/scripts/features/utf8
new file mode 100644
index 0000000..54bc471
--- /dev/null
+++ b/tests/scripts/features/utf8
@@ -0,0 +1,11 @@
+# -*-perl-*-
+
+$description = "Test support for UTF-8.";
+
+$details = "";
+
+# Verify that the UTF-8 BOM is ignored.
+run_make_test("\xEF\xBB\xBFall: ; \@echo \$\@\n", '', "all");
+
+# This tells the test driver that the perl test script executed properly.
+1;
diff --git a/tests/scripts/features/varnesting b/tests/scripts/features/varnesting
index 15d5071..d8f3ffb 100644
--- a/tests/scripts/features/varnesting
+++ b/tests/scripts/features/varnesting
@@ -1,29 +1,30 @@
-$description = "The following test creates a makefile to ...";
+# -*-perl-*-
+$description = "Test recursive variables";
$details = "";
-open(MAKEFILE,"> $makefile");
-
-# The Contents of the MAKEFILE ...
-
-print MAKEFILE "x = variable1\n"
- ."variable2 := Hello\n"
- ."y = \$(subst 1,2,\$(x))\n"
- ."z = y\n"
- ."a := \$(\$(\$(z)))\n"
- ."all: \n"
- ."\t\@echo \$(a)\n";
-
-# END of Contents of MAKEFILE
-
-close(MAKEFILE);
-
-&run_make_with_options($makefile,"",&get_logfile);
-
-# Create the answer to what should be produced by this Makefile
-$answer = "Hello\n";
-
-&compare_output($answer,&get_logfile(1));
+run_make_test('
+x = variable1
+variable2 := Hello
+y = $(subst 1,2,$(x))
+z = y
+a := $($($(z)))
+all:
+ @echo $(a)
+',
+ '', "Hello\n");
+
+# This tests resetting the value of a variable while expanding it.
+# You may only see problems with this if you're using valgrind or
+# some other memory checker that poisons freed memory.
+# See Savannah patch #7534
+
+run_make_test('
+VARIABLE = $(eval VARIABLE := echo hi)$(VARIABLE)
+wololo:
+ @$(VARIABLE)
+',
+ '', "hi\n");
1;
diff --git a/tests/scripts/features/vpath b/tests/scripts/features/vpath
index a3aebd9..ec24165 100644
--- a/tests/scripts/features/vpath
+++ b/tests/scripts/features/vpath
@@ -74,7 +74,7 @@ vpath-d/a: fail.te
vpath-d/b : fail.te
vpath-d/fail.te:
!,
- '', "#MAKE#: Nothing to be done for `default'.\n");
+ '', "#MAKE#: Nothing to be done for 'default'.\n");
rmdir('vpath-d');
diff --git a/tests/scripts/features/vpath3 b/tests/scripts/features/vpath3
index 978c5ee..c6ede28 100644
--- a/tests/scripts/features/vpath3
+++ b/tests/scripts/features/vpath3
@@ -1,50 +1,35 @@
-# -*-perl-*-
+# -*-perl-*-
$description = "Test the interaction of the -lfoo feature and vpath";
$details = "";
-open(MAKEFILE,"> $makefile");
-
-# The Contents of the MAKEFILE ...
-
-print MAKEFILE "vpath %.a a1\n";
-print MAKEFILE "vpath %.so b1\n";
-print MAKEFILE "vpath % a2 b2\n";
-print MAKEFILE "vpath % b3\n";
-print MAKEFILE "all: -l1 -l2 -l3; \@echo \$^\n";
-
-# END of Contents of MAKEFILE
-
-close(MAKEFILE);
-
-mkdir("a1", 0777);
-mkdir("b1", 0777);
-mkdir("a2", 0777);
-mkdir("b2", 0777);
-mkdir("b3", 0777);
-
-@files_to_touch = ("a1${pathsep}lib1.a",
- "b1${pathsep}lib1.so",
- "a2${pathsep}lib2.a",
- "b2${pathsep}lib2.so",
- "lib3.a",
- "b3${pathsep}lib3.so");
+my @dirs_to_make = qw(a1 b1 a2 b2 b3);
+for my $d (@dirs_to_make) {
+ mkdir($d, 0777);
+}
+my @files_to_touch = ("a1${pathsep}lib1.a",
+ "a1${pathsep}libc.a",
+ "b1${pathsep}lib1.so",
+ "a2${pathsep}lib2.a",
+ "b2${pathsep}lib2.so",
+ "lib3.a",
+ "b3${pathsep}lib3.so");
&touch(@files_to_touch);
-&run_make_with_options($makefile,"",&get_logfile);
-
-# Create the answer to what should be produced by this Makefile
-$answer = "a1${pathsep}lib1.a a2${pathsep}lib2.a lib3.a\n";
-
-if (&compare_output($answer,&get_logfile(1)))
-{
- unlink @files_to_touch;
- rmdir("a1");
- rmdir("b1");
- rmdir("a2");
- rmdir("b2");
- rmdir("b3");
+run_make_test('
+vpath %.h b3
+vpath %.a a1
+vpath %.so b1
+vpath % a2 b2
+vpath % b3
+all: -l1 -lc -l2 -l3; @echo $^
+',
+ '', "a1${pathsep}lib1.a a1${pathsep}libc.a a2${pathsep}lib2.a lib3.a\n");
+
+unlink(@files_to_touch);
+for my $d (@dirs_to_make) {
+ rmdir($d);
}
1;
diff --git a/tests/scripts/features/vpathgpath b/tests/scripts/features/vpathgpath
index f7683f5..5e6217b 100644
--- a/tests/scripts/features/vpathgpath
+++ b/tests/scripts/features/vpathgpath
@@ -57,7 +57,7 @@ sub touchfiles {
push(@touchedfiles, "bar.c");
-$answer = "$make_name: Nothing to be done for `general'.\n";
+$answer = "$make_name: Nothing to be done for 'general'.\n";
&compare_output($answer,&get_logfile(1));
diff --git a/tests/scripts/features/vpathplus b/tests/scripts/features/vpathplus
index a37fbed..361788c 100644
--- a/tests/scripts/features/vpathplus
+++ b/tests/scripts/features/vpathplus
@@ -86,6 +86,7 @@ cat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1
$answer = "not creating notarget.c from notarget.d
cat notarget.c > notarget.b 2>/dev/null || exit 1
+$makefile:16: recipe for target 'notarget.b' failed
$make_name: *** [notarget.b] Error 1
";
diff --git a/tests/scripts/functions/call b/tests/scripts/functions/call
index f3c5470..9db9da7 100644
--- a/tests/scripts/functions/call
+++ b/tests/scripts/functions/call
@@ -13,7 +13,7 @@ print MAKEFILE <<'EOMAKE';
#
reverse = $2 $1
-# A complex `map' function, using recursive `call'.
+# A complex 'map' function, using recursive 'call'.
#
map = $(foreach a,$2,$(call $1,$a))
@@ -38,7 +38,7 @@ two = $(call one,$(1),foo,$(2))
DEP_foo = bar baz quux
DEP_baz = quux blarp
rest = $(wordlist 2,$(words ${1}),${1})
-tclose = $(if $1,$(firstword $1) \
+tclose = $(if $1,$(firstword $1)\
$(call tclose,$(sort ${DEP_$(firstword $1)} $(call rest,$1))))
all: ; @echo '$(call reverse,bar,foo)'; \
@@ -96,4 +96,15 @@ close(MAKEFILE);
$answer = "1 2 3 4 5 6 7 8 9\n1 2 3 4 5\n1 2 3\n1 2 3\n";
&compare_output($answer,&get_logfile(1));
+# Ensure that variables are defined in global scope even in a $(call ...)
+
+delete $ENV{X123};
+
+run_make_test('
+tst = $(eval export X123)
+$(call tst)
+all: ; @echo "$${X123-not set}"
+',
+ '', "\n");
+
1;
diff --git a/tests/scripts/functions/file b/tests/scripts/functions/file
new file mode 100644
index 0000000..9a4cd02
--- /dev/null
+++ b/tests/scripts/functions/file
@@ -0,0 +1,101 @@
+# -*-perl-*-
+
+$description = 'Test the $(file ...) function.';
+
+# Test > and >>
+run_make_test(q!
+define A
+a
+b
+endef
+B = c d
+$(file >file.out,$(A))
+$(foreach L,$(B),$(file >> file.out,$L))
+x:;@echo hi; cat file.out
+!,
+ '', "hi\na\nb\nc\nd");
+
+unlink('file.out');
+
+# Test >> to a non-existent file
+run_make_test(q!
+define A
+a
+b
+endef
+$(file >> file.out,$(A))
+x:;@cat file.out
+!,
+ '', "a\nb");
+
+unlink('file.out');
+
+# Test > to a read-only file
+touch('file.out');
+chmod(0444, 'file.out');
+
+# Find the error that will be printed
+# This seems complicated, but we need the message from the C locale
+my $loc = undef;
+if ($has_POSIX) {
+ $loc = POSIX::setlocale(POSIX::LC_MESSAGES);
+ POSIX::setlocale(POSIX::LC_MESSAGES, 'C');
+}
+my $e;
+open(my $F, '>', 'file.out') and die "Opened read-only file!\n";
+$e = "$!";
+$loc and POSIX::setlocale(POSIX::LC_MESSAGES, $loc);
+
+run_make_test(q!
+define A
+a
+b
+endef
+$(file > file.out,$(A))
+x:;@cat file.out
+!,
+ '', "#MAKEFILE#:6: *** open: file.out: $e. Stop.",
+ 512);
+
+unlink('file.out');
+
+# Use variables for operator and filename
+run_make_test(q!
+define A
+a
+b
+endef
+OP = >
+FN = file.out
+$(file $(OP) $(FN),$(A))
+x:;@cat file.out
+!,
+ '', "a\nb");
+
+unlink('file.out');
+
+# Don't add newlines if one already exists
+run_make_test(q!
+define A
+a
+b
+
+endef
+$(file >file.out,$(A))
+x:;@cat file.out
+!,
+ '', "a\nb");
+
+unlink('file.out');
+
+# Empty text
+run_make_test(q!
+$(file >file.out,)
+$(file >>file.out,)
+x:;@cat file.out
+!,
+ '', "\n\n");
+
+unlink('file.out');
+
+1;
diff --git a/tests/scripts/functions/filter-out b/tests/scripts/functions/filter-out
index 6c8b27a..1fe4819 100644
--- a/tests/scripts/functions/filter-out
+++ b/tests/scripts/functions/filter-out
@@ -1,6 +1,6 @@
# -*-perl-*-
-$description = "Test the filter-out function.";
+$description = "Test the filter and filter-out functions.";
$details = "The makefile created in this test has two variables. The
filter-out function is first used to discard names ending in
@@ -11,18 +11,32 @@ which is only used if there are multiple literals present in both
the pattern and text arguments. The result of both filter-out
functions is the same single .elc name.\n";
-open(MAKEFILE,"> $makefile");
+# Basic test -- filter
+run_make_test(q!
+files1 := $(filter %.o, foo.elc bar.o lose.o)
+files2 := $(filter %.o foo.i, foo.i bar.i lose.i foo.elc bar.o lose.o)
+all: ; @echo '$(files1) $(files2)'
+!,
+ '', "bar.o lose.o foo.i bar.o lose.o\n");
-print MAKEFILE <<'EOF';
+# Basic test -- filter-out
+run_make_test(q!
files1 := $(filter-out %.o, foo.elc bar.o lose.o)
files2 := $(filter-out foo.i bar.i lose.i %.o, foo.i bar.i lose.i foo.elc bar.o lose.o)
-all: ; @echo $(files1) $(files2)
-EOF
+all: ; @echo '$(files1) $(files2)'
+!,
+ '', "foo.elc foo.elc\n");
-close(MAKEFILE);
+# Escaped patterns
+run_make_test(q!all:;@echo '$(filter foo\%bar,foo%bar fooXbar)'!,
+ '', "foo%bar\n");
-&run_make_with_options($makefile, "", &get_logfile, 0);
-$answer = "foo.elc foo.elc\n";
-&compare_output($answer,&get_logfile(1));
+run_make_test(q!all:;@echo '$(filter foo\%\%\\\\\%\%bar,foo%%\\%%bar fooX\\Ybar)'!,
+ '', "foo%%\\%%bar\n");
+
+run_make_test(q!
+X = $(filter foo\\\\\%bar,foo\%bar foo\Xbar)
+all:;@echo '$(X)'!,
+ '', "foo\\%bar\n");
1;
diff --git a/tests/scripts/functions/foreach b/tests/scripts/functions/foreach
index 82e99d7..4d1a11d 100644
--- a/tests/scripts/functions/foreach
+++ b/tests/scripts/functions/foreach
@@ -1,5 +1,5 @@
# -*-perl-*-
-# $Id: foreach,v 1.5 2006/03/10 02:20:46 psmith Exp $
+# $Id$
$description = "Test the foreach function.";
@@ -62,7 +62,7 @@ y = $x
all: ; @echo $y',
'',
- "#MAKEFILE#:2: *** insufficient number of arguments (1) to function `foreach'. Stop.",
+ "#MAKEFILE#:2: *** insufficient number of arguments (1) to function 'foreach'. Stop.",
512);
run_make_test('
@@ -71,7 +71,7 @@ y := $x
all: ; @echo $y',
'',
- "#MAKEFILE#:2: *** insufficient number of arguments (1) to function `foreach'. Stop.",
+ "#MAKEFILE#:2: *** insufficient number of arguments (1) to function 'foreach'. Stop.",
512);
1;
diff --git a/tests/scripts/functions/guile b/tests/scripts/functions/guile
new file mode 100644
index 0000000..c63bec9
--- /dev/null
+++ b/tests/scripts/functions/guile
@@ -0,0 +1,99 @@
+# -*-perl-*-
+
+$description = 'Test the $(guile ...) function.';
+
+$details = 'This only works on systems that support it.';
+
+# If this instance of make doesn't support GNU Guile, skip it
+# This detects if guile is loaded using the "load" directive
+# $makefile = get_tmpfile();
+# open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
+# print MAKEFILE q!
+# -load guile
+# all: ; @echo $(filter guile,$(.LOADED))
+# !;
+# close(MAKEFILE) || die "Failed to write $makefile: $!\n";
+# $cmd = subst_make_string("#MAKEPATH# -f $makefile");
+# $log = get_logfile(0);
+# $code = run_command_with_output($log, $cmd);
+# read_file_into_string ($log) eq "guile\n" and $FEATURES{guile} = 1;
+
+# If we don't have Guile support, never mind.
+exists $FEATURES{guile} or return -1;
+
+# Verify simple data type conversions
+# Currently we don't support vectors:
+# echo '$(guile (vector 1 2 3))'; \
+run_make_test(q!
+x:;@echo '$(guile #f)'; \
+ echo '$(guile #t)'; \
+ echo '$(guile #\c)'; \
+ echo '$(guile 1234)'; \
+ echo '$(guile 'foo)'; \
+ echo '$(guile "bar")'; \
+ echo '$(guile (cons 'a 'b))'; \
+ echo '$(guile '(a b (c . d) 1 (2) 3))'
+!,
+ '', "\n#t\nc\n1234\nfoo\nbar\na b\na b c d 1 2 3");
+
+# Verify the gmk-expand function
+run_make_test(q!
+VAR = $(guile (gmk-expand "$(shell echo hi)"))
+x:;@echo '$(VAR)'
+!,
+ '', "hi");
+
+# Verify the gmk-eval function
+# Prove that the string is expanded only once (by eval)
+run_make_test(q!
+TEST = bye
+EVAL = VAR = $(TEST) $(shell echo there)
+$(guile (gmk-eval "$(value EVAL)"))
+TEST = hi
+x:;@echo '$(VAR)'
+!,
+ '', "hi there");
+
+# Verify the gmk-eval function with a list
+run_make_test(q!
+$(guile (gmk-eval '(VAR = 1 (2) () 3)))
+x:;@echo '$(VAR)'
+!,
+ '', "1 2 3");
+
+# Verify the gmk-var function
+run_make_test(q!
+VALUE = hi $(shell echo there)
+VAR = $(guile (gmk-var "VALUE"))
+x:;@echo '$(VAR)'
+!,
+ '', "hi there");
+
+# Verify the gmk-var function with a symbol
+run_make_test(q!
+VALUE = hi $(shell echo there)
+VAR = $(guile (gmk-var 'VALUE))
+x:;@echo '$(VAR)'
+!,
+ '', "hi there");
+
+# Write a Guile program using define and run it
+run_make_test(q!
+# Define the "fib" function in Guile
+define fib
+;; A procedure for counting the n:th Fibonacci number
+;; See SICP, p. 37
+(define (fib n)
+ (cond ((= n 0) 0)
+ ((= n 1) 1)
+ (else (+ (fib (- n 1))
+ (fib (- n 2))))))
+endef
+$(guile $(fib))
+
+# Now run it
+x:;@echo $(guile (fib $(FIB)))
+!,
+ 'FIB=10', "55");
+
+1;
diff --git a/tests/scripts/functions/sort b/tests/scripts/functions/sort
index d472102..b558910 100644
--- a/tests/scripts/functions/sort
+++ b/tests/scripts/functions/sort
@@ -1,55 +1,47 @@
-$description = "The following test creates a makefile to verify\n"
- ."the ability of make to sort lists of object. Sort\n"
- ."will also remove any duplicate entries. This will also\n"
- ."be tested.";
-
-$details = "The make file is built with a list of object in a random order\n"
- ."and includes some duplicates. Make should sort all of the elements\n"
- ."remove all duplicates\n";
-
-open(MAKEFILE,"> $makefile");
-
-# The Contents of the MAKEFILE ...
-
-print MAKEFILE "foo := moon_light days \n"
- ."foo1:= jazz\n"
- ."bar := captured \n"
- ."bar2 = boy end, has rise A midnight \n"
- ."bar3:= \$(foo)\n"
- ."s1 := _by\n"
- ."s2 := _and_a\n"
- ."t1 := \$(addsuffix \$(s1), \$(bar) )\n"
- ."t2 := \$(addsuffix \$(s2), \$(foo1) )\n"
- ."t3 := \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \n"
- ."t4 := \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \n"
- ."t5 := \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \n"
- ."t6 := \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \n"
- ."t7 := \$(t6) \$(t6) \$(t6) \n"
- ."p1 := \$(addprefix \$(foo1), \$(s2) )\n"
- ."blank:= \n"
- ."all:\n"
- ."\t\@echo \$(sort \$(bar2) \$(foo) \$(addsuffix \$(s1), \$(bar) ) \$(t2) \$(bar2) \$(bar3))\n"
- ."\t\@echo \$(sort \$(blank) \$(foo) \$(bar2) \$(t1) \$(p1) )\n"
- ."\t\@echo \$(sort \$(foo) \$(bar2) \$(t1) \$(t4) \$(t5) \$(t7) \$(t6) )\n";
-
-
-# END of Contents of MAKEFILE
-
-close(MAKEFILE);
-
-&run_make_with_options($makefile,"",&get_logfile);
-
-# Create the answer to what should be produced by this Makefile
-$answer = "A boy captured_by days end, has jazz_and_a midnight moon_light rise\n"
- ."A boy captured_by days end, has jazz_and_a midnight moon_light rise\n"
- ."A boy captured_by days end, has jazz_and_a midnight moon_light rise\n";
-
-&compare_output($answer,&get_logfile(1));
+# -*-perl-*-
+
+$description = "The following test creates a makefile to verify
+the ability of make to sort lists of object. Sort
+will also remove any duplicate entries. This will also
+be tested.";
+
+$details = "The make file is built with a list of object in a random order
+and includes some duplicates. Make should sort all of the elements
+remove all duplicates\n";
+
+run_make_test('
+foo := moon_light days
+foo1:= jazz
+bar := captured
+bar2 = boy end, has rise A midnight
+bar3:= $(foo)
+s1 := _by
+s2 := _and_a
+t1 := $(addsuffix $(s1), $(bar) )
+t2 := $(addsuffix $(s2), $(foo1) )
+t3 := $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2) $(t2)
+t4 := $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3) $(t3)
+t5 := $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4) $(t4)
+t6 := $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5) $(t5)
+t7 := $(t6) $(t6) $(t6)
+p1 := $(addprefix $(foo1), $(s2) )
+blank:=
+all:
+ @echo $(sort $(bar2) $(foo) $(addsuffix $(s1), $(bar) ) $(t2) $(bar2) $(bar3))
+ @echo $(sort $(blank) $(foo) $(bar2) $(t1) $(p1) )
+ @echo $(sort $(foo) $(bar2) $(t1) $(t4) $(t5) $(t7) $(t6) )
+',
+ '', 'A boy captured_by days end, has jazz_and_a midnight moon_light rise
+A boy captured_by days end, has jazz_and_a midnight moon_light rise
+A boy captured_by days end, has jazz_and_a midnight moon_light rise
+');
+
+
+# Test with non-space/tab whitespace. Note that you can't see the
+# original bug except using valgrind.
+
+run_make_test("FOO = a b\tc\rd\fe \f \f \f \f \ff
+all: ; \@echo \$(words \$(sort \$(FOO)))\n",
+ '', "5\n");
1;
-
-
-
-
-
-
diff --git a/tests/scripts/functions/wildcard b/tests/scripts/functions/wildcard
index 2841f5d..bcd84ad 100644
--- a/tests/scripts/functions/wildcard
+++ b/tests/scripts/functions/wildcard
@@ -88,4 +88,16 @@ all: ; @echo $(wildcard xz--y*.7)
!,
'', "\n");
+# TEST #5: wildcard used to verify file existence
+
+touch('xxx.yyy');
+
+run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!,
+ '', "file=xxx.yyy\n");
+
+unlink('xxx.yyy');
+
+run_make_test(q!exists: ; @echo file=$(wildcard xxx.yyy)!,
+ '', "file=\n");
+
1;
diff --git a/tests/scripts/functions/word b/tests/scripts/functions/word
index 34527ea..4dcc940 100644
--- a/tests/scripts/functions/word
+++ b/tests/scripts/functions/word
@@ -56,32 +56,32 @@ wordlist-e1: ; @echo $(wordlist ,,$(FOO))
wordlist-e2: ; @echo $(wordlist abc ,,$(FOO))
wordlist-e3: ; @echo $(wordlist 1, 12a ,$(FOO))',
'word-e1',
- "#MAKEFILE#:3: *** non-numeric first argument to `word' function: ''. Stop.",
+ "#MAKEFILE#:3: *** non-numeric first argument to 'word' function: ''. Stop.",
512);
run_make_test(undef,
'word-e2',
- "#MAKEFILE#:4: *** non-numeric first argument to `word' function: 'abc '. Stop.",
+ "#MAKEFILE#:4: *** non-numeric first argument to 'word' function: 'abc '. Stop.",
512);
run_make_test(undef,
'word-e3',
- "#MAKEFILE#:5: *** non-numeric first argument to `word' function: '1a'. Stop.",
+ "#MAKEFILE#:5: *** non-numeric first argument to 'word' function: '1a'. Stop.",
512);
run_make_test(undef,
'wordlist-e1',
- "#MAKEFILE#:7: *** non-numeric first argument to `wordlist' function: ''. Stop.",
+ "#MAKEFILE#:7: *** non-numeric first argument to 'wordlist' function: ''. Stop.",
512);
run_make_test(undef,
'wordlist-e2',
- "#MAKEFILE#:8: *** non-numeric first argument to `wordlist' function: 'abc '. Stop.",
+ "#MAKEFILE#:8: *** non-numeric first argument to 'wordlist' function: 'abc '. Stop.",
512);
run_make_test(undef,
'wordlist-e3',
- "#MAKEFILE#:9: *** non-numeric second argument to `wordlist' function: ' 12a '. Stop.",
+ "#MAKEFILE#:9: *** non-numeric second argument to 'wordlist' function: ' 12a '. Stop.",
512);
# Test error conditions again, but this time in a variable reference
@@ -94,37 +94,37 @@ WL = $(wordlist $s,$e,$(FOO))
word-e: ; @echo $(W)
wordlist-e: ; @echo $(WL)',
'word-e x=',
- "#MAKEFILE#:3: *** non-numeric first argument to `word' function: ''. Stop.",
+ "#MAKEFILE#:3: *** non-numeric first argument to 'word' function: ''. Stop.",
512);
run_make_test(undef,
'word-e x=abc',
- "#MAKEFILE#:3: *** non-numeric first argument to `word' function: 'abc'. Stop.",
+ "#MAKEFILE#:3: *** non-numeric first argument to 'word' function: 'abc'. Stop.",
512);
run_make_test(undef,
'word-e x=0',
- "#MAKEFILE#:3: *** first argument to `word' function must be greater than 0. Stop.",
+ "#MAKEFILE#:3: *** first argument to 'word' function must be greater than 0. Stop.",
512);
run_make_test(undef,
'wordlist-e s= e=',
- "#MAKEFILE#:4: *** non-numeric first argument to `wordlist' function: ''. Stop.",
+ "#MAKEFILE#:4: *** non-numeric first argument to 'wordlist' function: ''. Stop.",
512);
run_make_test(undef,
'wordlist-e s=abc e=',
- "#MAKEFILE#:4: *** non-numeric first argument to `wordlist' function: 'abc'. Stop.",
+ "#MAKEFILE#:4: *** non-numeric first argument to 'wordlist' function: 'abc'. Stop.",
512);
run_make_test(undef,
'wordlist-e s=4 e=12a',
- "#MAKEFILE#:4: *** non-numeric second argument to `wordlist' function: '12a'. Stop.",
+ "#MAKEFILE#:4: *** non-numeric second argument to 'wordlist' function: '12a'. Stop.",
512);
run_make_test(undef,
'wordlist-e s=0 e=12',
- "#MAKEFILE#:4: *** invalid first argument to `wordlist' function: `0'. Stop.",
+ "#MAKEFILE#:4: *** invalid first argument to 'wordlist' function: '0'. Stop.",
512);
diff --git a/tests/scripts/misc/bs-nl b/tests/scripts/misc/bs-nl
new file mode 100644
index 0000000..4fc3f63
--- /dev/null
+++ b/tests/scripts/misc/bs-nl
@@ -0,0 +1,129 @@
+# -*-perl-*-
+$description = "Test backslash-newline handling.";
+
+$details = "";
+
+# TEST #1
+# -------
+
+# Backslash-newlines in recipes
+
+# These are basic backslash-newlines with no tricks
+run_make_test("fast:;\@echo fa\\\nst\n",
+ '', 'fast');
+
+run_make_test("slow:;\@: no-op; echo sl\\\now\n",
+ '', 'slow');
+
+run_make_test("dquote:;\@echo \"dqu\\\note\"\n",
+ '', 'dquote');
+
+run_make_test("squote:;\@echo 'squ\\\note'\n",
+ '', "squ\\\note");
+
+# Ensure that a leading prefix character is omitted
+run_make_test("fast:;\@echo fa\\\n\tst\n",
+ '', 'fast');
+
+run_make_test("slow:;\@: no-op; echo sl\\\n\tow\n",
+ '', 'slow');
+
+run_make_test("dquote:;\@echo \"dqu\\\n\tote\"\n",
+ '', 'dquote');
+
+run_make_test("squote:;\@echo 'squ\\\n\tote'\n",
+ '', "squ\\\note");
+
+# Ensure that ONLY the leading prefix character is omitted
+run_make_test("fast:;\@echo fa\\\n\t st\n",
+ '', 'fa st');
+
+run_make_test("slow:;\@: no-op; echo sl\\\n\t\tow\n",
+ '', "sl ow");
+
+run_make_test("dquote:;\@echo \"dqu\\\n\t ote\"\n",
+ '', 'dqu ote');
+
+run_make_test("squote:;\@echo 'squ\\\n\t\t ote'\n",
+ '', "squ\\\n\t ote");
+
+# Backslash-newlines in variable values
+
+# Simple
+run_make_test(q!
+var = he\
+llo
+var:;@echo '|$(var)|'!,
+ '', "|he llo|");
+
+# Condense trailing space
+run_make_test(q!
+var = he \
+llo
+var:;@echo '|$(var)|'!,
+ '', "|he llo|");
+
+# Remove leading space
+run_make_test(q!
+var = he\
+ llo
+var:;@echo '|$(var)|'!,
+ '', "|he llo|");
+
+# Multiple bs/nl condensed
+run_make_test(q!
+var = he\
+\
+\
+ llo
+var:;@echo '|$(var)|'!,
+ '', "|he llo|");
+
+# POSIX: Preserve trailing space
+run_make_test(q!
+.POSIX:
+x = y
+var = he \
+llo
+var:;@echo '|$(var)|'!,
+ '', "|he llo|");
+
+# POSIX: One space per bs-nl
+run_make_test(q!
+.POSIX:
+x = y
+var = he\
+\
+\
+ llo
+var:;@echo '|$(var)|'!,
+ '', "|he llo|");
+
+# Savannah #39035: handle whitespace in call
+run_make_test(q!
+f = echo $(1)
+t:; @$(call f,"a \
+ b"); \
+ $(call f,"a \
+ b")
+!,
+ '', "a b\na b\n");
+
+# Savannah #38945: handle backslash CRLF
+# We need our own makefile so we can set binmode
+my $m1 = get_tmpfile();
+open(MAKEFILE, "> $m1");
+binmode(MAKEFILE);
+print MAKEFILE "FOO = foo \\\r\n";
+close(MAKEFILE);
+
+my $m2 = get_tmpfile();
+open(MAKEFILE, "> $m2");
+print MAKEFILE "include $m1\ndefine BAR\nall: ; \@echo \$(FOO) bar\nendef\n\$(eval \$(BAR))\n";
+close(MAKEFILE);
+
+run_make_with_options($m2, '', get_logfile());
+compare_output("foo bar\n", get_logfile(1));
+
+
+1;
diff --git a/tests/scripts/misc/fopen-fail b/tests/scripts/misc/fopen-fail
new file mode 100644
index 0000000..6580e51
--- /dev/null
+++ b/tests/scripts/misc/fopen-fail
@@ -0,0 +1,15 @@
+# -*-perl-*-
+
+$description = "Make sure make exits with an error if fopen fails.";
+
+# Recurse infinitely until we run out of open files, and ensure we
+# fail with a non-zero exit code. Don't bother to test the output
+# since it's hard to know what it will be, exactly.
+# See Savannah bug #27374.
+
+run_make_test(q!
+include $(lastword $(MAKEFILE_LIST))
+!,
+ '', undef, 512);
+
+1;
diff --git a/tests/scripts/misc/general3 b/tests/scripts/misc/general3
index b3142c2..8ad0f8e 100644
--- a/tests/scripts/misc/general3
+++ b/tests/scripts/misc/general3
@@ -26,7 +26,7 @@ TAB = \t \# A TAB and some spaces
\$(STR)
\$(STR) \$(TAB)",
- '', "#MAKE#: Nothing to be done for `all'.");
+ '', "#MAKE#: Nothing to be done for 'all'.");
# TEST 2
diff --git a/tests/scripts/options/dash-B b/tests/scripts/options/dash-B
index e36842e..9c708b7 100644
--- a/tests/scripts/options/dash-B
+++ b/tests/scripts/options/dash-B
@@ -22,13 +22,13 @@ foo: bar.x
',
'', 'cp bar.x foo');
-run_make_test(undef, '', "#MAKE#: Nothing to be done for `all'.");
+run_make_test(undef, '', "#MAKE#: Nothing to be done for 'all'.");
run_make_test(undef, '-B', 'cp bar.x foo');
# Put the timestamp for foo into the future; it should still be remade.
utouch(1000, 'foo');
-run_make_test(undef, '', "#MAKE#: Nothing to be done for `all'.");
+run_make_test(undef, '', "#MAKE#: Nothing to be done for 'all'.");
run_make_test(undef, '-B', 'cp bar.x foo');
# Clean up
diff --git a/tests/scripts/options/dash-C b/tests/scripts/options/dash-C
index 5864ffd..42d0a8b 100644
--- a/tests/scripts/options/dash-C
+++ b/tests/scripts/options/dash-C
@@ -34,9 +34,9 @@ if (-f $example) {
}
# Create the answer to what should be produced by this Makefile
-$answer = "$make_name: Entering directory `$wpath'\n"
+$answer = "$make_name: Entering directory '$wpath'\n"
. "$delete_command EXAMPLE\n"
- . "$make_name: Leaving directory `$wpath'\n";
+ . "$make_name: Leaving directory '$wpath'\n";
&compare_output($answer,&get_logfile(1));
@@ -62,9 +62,9 @@ if (-f $example) {
}
# Create the answer to what should be produced by this Makefile
-$answer = "$make_name: Entering directory `$wpath'\n"
+$answer = "$make_name: Entering directory '$wpath'\n"
. "$delete_command EXAMPLEslash\n"
- . "$make_name: Leaving directory `$wpath'\n";
+ . "$make_name: Leaving directory '$wpath'\n";
&compare_output($answer,&get_logfile(1));
diff --git a/tests/scripts/options/dash-I b/tests/scripts/options/dash-I
index 8dc5d9b..d47a8d8 100644
--- a/tests/scripts/options/dash-I
+++ b/tests/scripts/options/dash-I
@@ -51,9 +51,9 @@ $answer = "This is another included makefile\n";
$answer = "$mkpath ANOTHER -f $makefile
-${make_name}[1]: Entering directory `$pwd'
+${make_name}[1]: Entering directory '$pwd'
This is another included makefile
-${make_name}[1]: Leaving directory `$pwd'\n";
+${make_name}[1]: Leaving directory '$pwd'\n";
&run_make_with_options($makefile,"-I $workdir recurse",&get_logfile);
&compare_output($answer,&get_logfile(1));
diff --git a/tests/scripts/options/dash-W b/tests/scripts/options/dash-W
index d3fde87..20b9f74 100644
--- a/tests/scripts/options/dash-W
+++ b/tests/scripts/options/dash-W
@@ -12,7 +12,7 @@ a.x b.x: ; echo >> $@
# Run it again: nothing should happen
-run_make_test(undef, '', "#MAKE#: `a.x' is up to date.");
+run_make_test(undef, '', "#MAKE#: 'a.x' is up to date.");
# Now run it with -W b.x: should rebuild a.x
@@ -21,7 +21,7 @@ run_make_test(undef, '-W b.x', 'echo >> a.x');
# Put the timestamp for a.x into the future; it should still be remade.
utouch(1000, 'a.x');
-run_make_test(undef, '', "#MAKE#: `a.x' is up to date.");
+run_make_test(undef, '', "#MAKE#: 'a.x' is up to date.");
run_make_test(undef, '-W b.x', 'echo >> a.x');
# Clean up
diff --git a/tests/scripts/options/dash-k b/tests/scripts/options/dash-k
index d87a786..e784e0d 100644
--- a/tests/scripts/options/dash-k
+++ b/tests/scripts/options/dash-k
@@ -57,10 +57,10 @@ else {
# Create the answer to what should be produced by this Makefile
$answer = "cc -c main.c
-$make_name: *** No rule to make target `kbd.c', needed by `kbd.o'.
+$make_name: *** No rule to make target 'kbd.c', needed by 'kbd.o'.
cc -c commands.c
cc -c display.c
-$make_name: Target `edit' not remade because of errors.\n";
+$make_name: Target 'edit' not remade because of errors.\n";
# COMPARE RESULTS
@@ -92,8 +92,9 @@ close(MAKEFILE);
&run_make_with_options($makefile2, "-k", &get_logfile, $error_code);
$answer = "exit 1
+$makefile2:9: recipe for target 'foo.o' failed
$make_name: *** [foo.o] Error 1
-$make_name: Target `all' not remade because of errors.\n";
+$make_name: Target 'all' not remade because of errors.\n";
&compare_output($answer, &get_logfile(1));
@@ -106,8 +107,8 @@ ifile: no-such-file; @false
',
'-k',
"#MAKEFILE#:2: ifile: No such file or directory
-#MAKE#: *** No rule to make target `no-such-file', needed by `ifile'.
-#MAKE#: Failed to remake makefile `ifile'.
+#MAKE#: *** No rule to make target 'no-such-file', needed by 'ifile'.
+#MAKE#: Failed to remake makefile 'ifile'.
hi\n",
512);
diff --git a/tests/scripts/options/dash-n b/tests/scripts/options/dash-n
index de19f42..dfed419 100644
--- a/tests/scripts/options/dash-n
+++ b/tests/scripts/options/dash-n
@@ -3,37 +3,24 @@ $description = "Test the -n option.\n";
$details = "Try various uses of -n and ensure they all give the correct results.\n";
-open(MAKEFILE, "> $makefile");
-
-# The Contents of the MAKEFILE ...
-
-print MAKEFILE <<'EOMAKE';
+touch('orig');
+run_make_test(q!
final: intermediate ; echo >> $@
intermediate: orig ; echo >> $@
-
-EOMAKE
-
-close(MAKEFILE);
-
-&touch('orig');
-
-# TEST 0
-
-&run_make_with_options($makefile, "", &get_logfile);
-$answer = "echo >> intermediate\necho >> final\n";
-&compare_output($answer, &get_logfile(1));
+!,
+ '', "echo >> intermediate\necho >> final\n");
# TEST 1
-&run_make_with_options($makefile, "-Worig -n", &get_logfile);
-$answer = "echo >> intermediate\necho >> final\n";
-&compare_output($answer, &get_logfile(1));
+run_make_test(undef, '-Worig -n', "echo >> intermediate\necho >> final\n");
-unlink('orig', 'intermediate', 'final');
+rmfiles(qw(orig intermediate final));
# We consider the actual updated timestamp of targets with all
-# recursive commands, even with -n.
+# recursive commands, even with -n. Switching this to the new model
+# is non-trivial because we use a trick below to change the log content
+# before we compare it ...
$makefile2 = &get_tmpfile;
@@ -56,15 +43,58 @@ close(MAKEFILE);
# TEST 2
&run_make_with_options($makefile2, "", &get_logfile);
-$answer = "$make_name: `a' is up to date.\n";
+$answer = "$make_name: 'a' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST 3
&run_make_with_options($makefile2, "-n", &get_logfile);
-$answer = "$make_name: `a' is up to date.\n";
+$answer = "$make_name: 'a' is up to date.\n";
+&compare_output($answer, &get_logfile(1));
+
+# TEST 4
+
+unlink(qw(a b));
+
+&run_make_with_options($makefile2, "-t -n", &get_logfile);
+
+open(DASH_N_LOG, ">>" . &get_logfile(1));
+print DASH_N_LOG "a exists but should not!\n" if -e 'a';
+print DASH_N_LOG "b exists but should not!\n" if -e 'b';
+close(DASH_N_LOG);
+
+&compare_output("touch b\ntouch a\n", &get_logfile(1));
+
+# CLEANUP
+
+unlink(qw(a b c));
+
+# Ensure -n continues to be included with recursive/re-execed make
+# See Savannah bug #38051
+
+$topmake = &get_tmpfile;
+$submake = &get_tmpfile;
+
+open(MAKEFILE, "> $topmake");
+print MAKEFILE <<"EOF";
+foo: ; \@\$(MAKE) -f "$submake" bar
+EOF
+close(MAKEFILE);
+
+
+# The bar target should print what would happen, but not actually run
+open(MAKEFILE, "> $submake");
+print MAKEFILE <<'EOF';
+inc: ; touch $@
+-include inc
+bar: ; @echo $(strip $(MAKEFLAGS))
+EOF
+close(MAKEFILE);
+
+&run_make_with_options($topmake, '-n --no-print-directory', &get_logfile);
+$answer = "$make_path -f \"$submake\" bar\ntouch inc\necho n --no-print-directory\n";
&compare_output($answer, &get_logfile(1));
-unlink('a', 'b', 'c');
+unlink('inc');
1;
diff --git a/tests/scripts/options/eval b/tests/scripts/options/eval
index 06a035c..0f82409 100644
--- a/tests/scripts/options/eval
+++ b/tests/scripts/options/eval
@@ -16,4 +16,14 @@ recurse: ; @$(MAKE) -f #MAKEFILE# && echo recurse!,
run_make_test(undef, '--no-print-directory --eval=\$\(info\ eval\) recurse',
"eval\neval\nall\nrecurse");
+# Make sure that --eval is handled correctly during restarting
+run_make_test(q!
+all: ; @echo $@
+-include gen.mk
+gen.mk: ; @echo > $@
+!,
+ '--eval=\$\(info\ eval\)', "eval\neval\nall");
+
+unlink('gen.mk');
+
1;
diff --git a/tests/scripts/options/print-directory b/tests/scripts/options/print-directory
new file mode 100644
index 0000000..a05bbee
--- /dev/null
+++ b/tests/scripts/options/print-directory
@@ -0,0 +1,33 @@
+# -*-perl-*-
+
+$description = "Test the -w option to GNU make.";
+
+# Simple test without -w
+run_make_test(q!
+all: ; @echo hi
+!,
+ "", "hi\n");
+
+# Simple test with -w
+run_make_test(undef, "-w",
+ "#MAKE#: Entering directory '#PWD#'\nhi\n#MAKE#: Leaving directory '#PWD#'\n");
+
+# Test makefile rebuild to ensure no enter/leave
+run_make_test(q!
+include foo
+all: ;@:
+foo: ; touch foo
+!,
+ "", "#MAKEFILE#:2: foo: No such file or directory\ntouch foo\n");
+unlink('foo');
+
+# Test makefile rebuild with -w
+run_make_test(q!
+include foo
+all: ;@:
+foo: ; touch foo
+!,
+ "-w", "#MAKE#: Entering directory '#PWD#'\n#MAKEFILE#:2: foo: No such file or directory\ntouch foo\n#MAKE#: Leaving directory '#PWD#'\n");
+unlink('foo');
+
+1;
diff --git a/tests/scripts/options/symlinks b/tests/scripts/options/symlinks
index 40d2564..a1bfce0 100644
--- a/tests/scripts/options/symlinks
+++ b/tests/scripts/options/symlinks
@@ -26,7 +26,7 @@ if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) {
# Without -L, nothing should happen
# With -L, it should update targ
run_make_test('targ: sym ; @echo make $@ from $<', '',
- "#MAKE#: `targ' is up to date.");
+ "#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "make targ from sym");
# Now update dep; in all cases targ should be out of date.
@@ -36,8 +36,8 @@ if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) {
# Now update targ; in all cases targ should be up to date.
&touch('targ');
- run_make_test(undef, '', "#MAKE#: `targ' is up to date.");
- run_make_test(undef, '-L', "#MAKE#: `targ' is up to date.");
+ run_make_test(undef, '', "#MAKE#: 'targ' is up to date.");
+ run_make_test(undef, '-L', "#MAKE#: 'targ' is up to date.");
# Add in a new link between sym and dep. Be sure it's newer than targ.
sleep(1);
@@ -46,7 +46,7 @@ if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) {
# Without -L, nothing should happen
# With -L, it should update targ
- run_make_test(undef, '', "#MAKE#: `targ' is up to date.");
+ run_make_test(undef, '', "#MAKE#: 'targ' is up to date.");
run_make_test(undef, '-L', "make targ from sym");
rmfiles('targ', 'dep', 'sym', 'dep1');
@@ -56,7 +56,7 @@ if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) {
symlink("../$dirname/dep", 'sym');
run_make_test('targ: sym ; @echo make $@ from $<', '',
- "#MAKE#: *** No rule to make target `sym', needed by `targ'. Stop.", 512);
+ "#MAKE#: *** No rule to make target 'sym', needed by 'targ'. Stop.", 512);
run_make_test('targ: sym ; @echo make $@ from $<', '-L',
'make targ from sym');
diff --git a/tests/scripts/options/warn-undefined-variables b/tests/scripts/options/warn-undefined-variables
index 34bfaea..ce15507 100644
--- a/tests/scripts/options/warn-undefined-variables
+++ b/tests/scripts/options/warn-undefined-variables
@@ -18,8 +18,8 @@ all: ; @echo ref $(EREF) $(UREF)',
# With --warn-undefined-variables, it should warn me
run_make_test(undef, '--warn-undefined-variables',
- "#MAKEFILE#:7: warning: undefined variable `UNDEFINED'
-#MAKEFILE#:9: warning: undefined variable `UNDEFINED'
+ "#MAKEFILE#:7: warning: undefined variable 'UNDEFINED'
+#MAKEFILE#:9: warning: undefined variable 'UNDEFINED'
ref");
1;
diff --git a/tests/scripts/targets/DEFAULT b/tests/scripts/targets/DEFAULT
index 0cabde9..f3d5148 100644
--- a/tests/scripts/targets/DEFAULT
+++ b/tests/scripts/targets/DEFAULT
@@ -35,9 +35,9 @@ close(MAKEFILE);
&run_make_with_options($makefile,'bar',&get_logfile);
# Create the answer to what should be produced by this Makefile
-$answer = "${make_name}[1]: Entering directory `$pwd'\n"
+$answer = "${make_name}[1]: Entering directory '$pwd'\n"
. "Executing rule BAR\n"
- . "${make_name}[1]: Leaving directory `$pwd'\n";
+ . "${make_name}[1]: Leaving directory '$pwd'\n";
# COMPARE RESULTS
diff --git a/tests/scripts/targets/INTERMEDIATE b/tests/scripts/targets/INTERMEDIATE
index 4fdd7a2..2b3021b 100644
--- a/tests/scripts/targets/INTERMEDIATE
+++ b/tests/scripts/targets/INTERMEDIATE
@@ -42,7 +42,7 @@ $answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n";
# TEST #1
&run_make_with_options($makefile,'foo.d',&get_logfile);
-$answer = "$make_name: `foo.d' is up to date.\n";
+$answer = "$make_name: 'foo.d' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST #2
@@ -63,7 +63,7 @@ $answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm bar.e foo
# TEST #4
&run_make_with_options($makefile,'foo.c',&get_logfile);
-$answer = "$make_name: `foo.c' is up to date.\n";
+$answer = "$make_name: 'foo.c' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST #5
diff --git a/tests/scripts/targets/ONESHELL b/tests/scripts/targets/ONESHELL
index 997423f..87713da 100644
--- a/tests/scripts/targets/ONESHELL
+++ b/tests/scripts/targets/ONESHELL
@@ -4,6 +4,10 @@ $description = "Test the behaviour of the .ONESHELL target.";
$details = "";
+# Some shells (*shakes fist at Solaris*) cannot handle multiple flags in
+# separate arguments.
+my $t = `/bin/sh -e -c true 2>/dev/null`;
+my $multi_ok = $? == 0;
# Simple
@@ -17,6 +21,21 @@ all:
[ 0"$a" -eq "$$" ] || echo fail
');
+# Simple but use multi-word SHELLFLAGS
+
+if ($multi_ok) {
+ run_make_test(q!
+.ONESHELL:
+.SHELLFLAGS = -e -c
+all:
+ a=$$$$
+ [ 0"$$a" -eq "$$$$" ] || echo fail
+!,
+ '', 'a=$$
+[ 0"$a" -eq "$$" ] || echo fail
+');
+}
+
# Again, but this time with inner prefix chars
run_make_test(q!
diff --git a/tests/scripts/targets/POSIX b/tests/scripts/targets/POSIX
index 9c30e18..a24e3bc 100644
--- a/tests/scripts/targets/POSIX
+++ b/tests/scripts/targets/POSIX
@@ -1,6 +1,6 @@
# -*-perl-*-
-$description = "Test the behaviour of the .PHONY target.";
+$description = "Test the behaviour of the .POSIX target.";
$details = "";
@@ -17,7 +17,8 @@ run_make_test(qq!
.POSIX:
all: ; \@$script
!,
- '', "#MAKE#: *** [all] Error $err\n", 512);
+ '', "#MAKEFILE#:3: recipe for target 'all' failed
+#MAKE#: *** [all] Error $err\n", 512);
# User settings must override .POSIX
$flags = '-xc';
@@ -29,5 +30,28 @@ all: ; \@$script
!,
'', $out);
+# Test the default value of various POSIX-specific variables
+my %POSIX = (AR => 'ar', ARFLAGS => '-rv',
+ YACC => 'yacc', YFLAGS => '',
+ LEX => 'lex', LFLAGS => '',
+ LDFLAGS => '',
+ CC => 'c99', CFLAGS => '-O',
+ FC => 'fort77', FFLAGS => '-O 1',
+ GET => 'get', GFLAGS => '',
+ SCCSFLAGS => '', SCCSGETFLAGS => '-s');
+my $make = join('', map { "\t\@echo '$_=\$($_)'\n" } sort keys %POSIX);
+my $r = join('', map { "$_=$POSIX{$_}\n"} sort keys %POSIX);
+run_make_test(qq!
+.POSIX:
+all:
+$make
+!,
+ '', $r);
+
+# Make sure that local settings take precedence
+%extraENV = map { $_ => "xx-$_" } keys %POSIX;
+$r = join('', map { "$_=xx-$_\n"} sort keys %POSIX);
+run_make_test(undef, '', $r);
+
# This tells the test driver that the perl test script executed properly.
1;
diff --git a/tests/scripts/targets/SECONDARY b/tests/scripts/targets/SECONDARY
index c954ee9..447c275 100644
--- a/tests/scripts/targets/SECONDARY
+++ b/tests/scripts/targets/SECONDARY
@@ -44,7 +44,7 @@ $answer = "cp foo.f foo.e\ncp foo.e foo.d\n";
unlink('foo.e');
&run_make_with_options($makefile,'foo.d',&get_logfile);
-$answer = "$make_name: `foo.d' is up to date.\n";
+$answer = "$make_name: 'foo.d' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST #3
@@ -67,7 +67,7 @@ $answer = "cp foo.e foo.c\n";
unlink('foo.e');
&run_make_with_options($makefile,'foo.c',&get_logfile);
-$answer = "$make_name: `foo.c' is up to date.\n";
+$answer = "$make_name: 'foo.c' is up to date.\n";
&compare_output($answer, &get_logfile(1));
# TEST #6
@@ -103,7 +103,7 @@ close(MAKEFILE);
touch('final');
&run_make_with_options($makefile2, '', &get_logfile);
-$answer = "$make_name: `final' is up to date.\n";
+$answer = "$make_name: 'final' is up to date.\n";
&compare_output($answer, &get_logfile(1));
unlink('source', 'final', 'intermediate');
@@ -129,10 +129,11 @@ touch(qw(1.a 2.a));
run_make_test('
%.c : %.b ; cp $< $@
%.b : %.a ; cp $< $@
-all : 1.c 2.c', '-rR -j',
+all : 1.c 2.c
+2.a: 1.c', '-rR -j',
'cp 1.a 1.b
-cp 2.a 2.b
cp 1.b 1.c
+cp 2.a 2.b
cp 2.b 2.c
rm 1.b 2.b');
diff --git a/tests/scripts/variables/DEFAULT_GOAL b/tests/scripts/variables/DEFAULT_GOAL
index 1c06506..8188ce7 100644
--- a/tests/scripts/variables/DEFAULT_GOAL
+++ b/tests/scripts/variables/DEFAULT_GOAL
@@ -42,7 +42,7 @@ run_make_test('
.DEFAULT_GOAL = foo
',
'',
-'#MAKE#: *** No rule to make target `foo\'. Stop.',
+"#MAKE#: *** No rule to make target 'foo'. Stop.",
512);
diff --git a/tests/scripts/variables/GNUMAKEFLAGS b/tests/scripts/variables/GNUMAKEFLAGS
new file mode 100644
index 0000000..e9c0d55
--- /dev/null
+++ b/tests/scripts/variables/GNUMAKEFLAGS
@@ -0,0 +1,42 @@
+# -*-perl-*-
+
+$description = "Test proper behavior of GNUMAKEFLAGS";
+
+# Accept flags from GNUMAKEFLAGS as well as MAKEFLAGS
+# Results always go in MAKEFLAGS
+
+$extraENV{'GNUMAKEFLAGS'} = '-e -r -R';
+
+run_make_test(q!
+all: ; @echo $(MAKEFLAGS)
+!,
+ '', 'erR');
+
+# Long arguments mean everything is prefixed with "-"
+
+$extraENV{'GNUMAKEFLAGS'} = '--no-print-directory -e -r -R --trace';
+
+run_make_test(q!
+all: ; @echo $(MAKEFLAGS)
+!,
+ '', "#MAKEFILE#:2: target 'all' does not exist
+echo erR --trace --no-print-directory
+erR --trace --no-print-directory");
+
+# Verify that re-exec / recursion doesn't duplicate flags from GNUMAKEFLAGS
+
+unlink('x.mk');
+
+$extraENV{GNUMAKEFLAGS} = '-Itst/bad -Oline';
+
+run_make_test(q!
+recurse: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS; #MAKEPATH# -f #MAKEFILE# all
+all: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS
+-include x.mk
+x.mk: ; @echo $@; echo MAKEFLAGS = $$MAKEFLAGS; echo GNUMAKEFLAGS = $$GNUMAKEFLAGS; echo > $@
+!,
+ "", "x.mk\nMAKEFLAGS = -Itst/bad -Oline\nGNUMAKEFLAGS =\nrecurse\nMAKEFLAGS = -Itst/bad -Oline\nGNUMAKEFLAGS =\n#MAKE#[1]: Entering directory '#PWD#'\nall\nMAKEFLAGS = w -Itst/bad -Oline\nGNUMAKEFLAGS =\n#MAKE#[1]: Leaving directory '#PWD#'\n");
+
+unlink('x.mk');
+
+1;
diff --git a/tests/scripts/variables/LIBPATTERNS b/tests/scripts/variables/LIBPATTERNS
index 826f2fa..9182954 100644
--- a/tests/scripts/variables/LIBPATTERNS
+++ b/tests/scripts/variables/LIBPATTERNS
@@ -20,7 +20,7 @@ run_make_test('
.LIBPATTERNS = mtest_foo.a mtest_%.a
all: -lfoo ; @echo "build $@ from $<"
',
- '', "#MAKE#: .LIBPATTERNS element `mtest_foo.a' is not a pattern
+ '', "#MAKE#: .LIBPATTERNS element 'mtest_foo.a' is not a pattern
build all from mtest_foo.a\n");
# TEST 2: target-specific override
diff --git a/tests/scripts/variables/MAKE b/tests/scripts/variables/MAKE
index d1081da..dc62160 100644
--- a/tests/scripts/variables/MAKE
+++ b/tests/scripts/variables/MAKE
@@ -16,8 +16,8 @@ foo:
!,
'',
"#MAKEPATH#\n#MAKEPATH# -f #MAKEFILE# foo\n"
- . "#MAKE#[1]: Entering directory `#PWD#'\n"
- . "#MAKEPATH#\n#MAKE#[1]: Leaving directory `#PWD#'\n");
+ . "#MAKE#[1]: Entering directory '#PWD#'\n"
+ . "#MAKEPATH#\n#MAKE#[1]: Leaving directory '#PWD#'\n");
rmfiles("foo");
diff --git a/tests/scripts/variables/MAKEFLAGS b/tests/scripts/variables/MAKEFLAGS
index 0b567e8..8a5d0f6 100644
--- a/tests/scripts/variables/MAKEFLAGS
+++ b/tests/scripts/variables/MAKEFLAGS
@@ -1,4 +1,4 @@
-# -*-perl-*-
+# -*-perl-*-
$description = "Test proper behavior of MAKEFLAGS";
@@ -8,36 +8,34 @@ $details = "DETAILS";
run_make_test(q!
all: ; @echo $(MAKEFLAGS)
!,
- '-e -r -R', 'Rre');
+ '-e -r -R', 'erR');
# Long arguments mean everything is prefixed with "-"
run_make_test(q!
all: ; @echo $(MAKEFLAGS)
!,
- '--no-print-directory -e -r -R', '--no-print-directory -Rre');
+ '--no-print-directory -e -r -R --trace', "#MAKEFILE#:2: target 'all' does not exist
+echo erR --trace --no-print-directory
+erR --trace --no-print-directory");
-if ($all_tests) {
- # Recursive invocations of make should accumulate MAKEFLAGS values.
- # Savannah bug #2216
- run_make_test(q!
+# Recursive invocations of make should accumulate MAKEFLAGS values.
+# Savannah bug #2216
+run_make_test(q!
MSG = Fails
all:
@echo '$@: MAKEFLAGS=$(MAKEFLAGS)'
@MSG=Works $(MAKE) -e -f #MAKEFILE# jump
jump:
- @echo '$@: MAKEFLAGS=$(MAKEFLAGS)'
+ @echo '$@ $(MSG): MAKEFLAGS=$(MAKEFLAGS)'
@$(MAKE) -f #MAKEFILE# print
print:
- @echo '$@: MAKEFLAGS=$(MAKEFLAGS)'
- @echo $(MSG)
+ @echo '$@ $(MSG): MAKEFLAGS=$(MAKEFLAGS)'
.PHONY: all jump print
!,
'--no-print-directory',
'all: MAKEFLAGS= --no-print-directory
-jump: MAKEFLAGS= --no-print-directory -e
-print: MAKEFLAGS= --no-print-directory -e
-Works');
-}
+jump Works: MAKEFLAGS=e --no-print-directory
+print Works: MAKEFLAGS=e --no-print-directory');
1;
diff --git a/tests/scripts/variables/MAKE_RESTARTS b/tests/scripts/variables/MAKE_RESTARTS
index 53ab738..ef8e368 100644
--- a/tests/scripts/variables/MAKE_RESTARTS
+++ b/tests/scripts/variables/MAKE_RESTARTS
@@ -52,10 +52,10 @@ MAKE_RESTARTS=1
foo.x:1: bar.x: No such file or directory
MAKE_RESTARTS=2
recurse MAKE_RESTARTS=
+#MAKE#[1]: Entering directory '#PWD#'
MAKE_RESTARTS=
-#MAKE#[1]: Entering directory `#PWD#'
all MAKE_RESTARTS=
-#MAKE#[1]: Leaving directory `#PWD#'");
+#MAKE#[1]: Leaving directory '#PWD#'");
rmfiles('foo.x', 'bar.x');
diff --git a/tests/scripts/variables/SHELL b/tests/scripts/variables/SHELL
index 7b7e7fe..1d01ba3 100644
--- a/tests/scripts/variables/SHELL
+++ b/tests/scripts/variables/SHELL
@@ -70,6 +70,22 @@ all: ; \@$script
!,
'', $out);
+# Do it again but add spaces to SHELLFLAGS
+
+# Some shells (*shakes fist at Solaris*) cannot handle multiple flags in
+# separate arguments.
+my $t = `/bin/sh -e -c true 2>/dev/null`;
+my $multi_ok = $? == 0;
+
+if ($multi_ok) {
+ $flags = '-x -c';
+ run_make_test(qq!
+.SHELLFLAGS = $flags
+all: ; \@$script
+!,
+ '', $out);
+}
+
# We can't just use "false" because on different systems it provides a
# different exit code--once again Solaris: false exits with 255 not 1
$script = 'true; false; true';
@@ -81,6 +97,7 @@ run_make_test(qq!
.SHELLFLAGS = $flags
all: ; \@$script
!,
- '', "$out#MAKE#: *** [all] Error $err\n", 512);
+ '', "$out#MAKEFILE#:3: recipe for target 'all' failed
+#MAKE#: *** [all] Error $err\n", 512);
1;
diff --git a/tests/scripts/variables/define b/tests/scripts/variables/define
index f91519e..7324cbc 100644
--- a/tests/scripts/variables/define
+++ b/tests/scripts/variables/define
@@ -30,6 +30,10 @@ define simple :=
@echo $(FOO)
endef
+define posix ::=
+@echo $(FOO)
+endef
+
append = @echo a
define append +=
@@ -49,10 +53,54 @@ FOO = there
all: ; $(multi)
$(simple)
+ $(posix)
+ $(append)
+ $(cond)
+',
+ '', "echo hi\nhi\nthere\nfoo\nfoo\na\nb\nfirst\n");
+
+# TEST 1a: Various new-style define/endef, with no spaces
+
+run_make_test('
+FOO = foo
+
+define multi=
+echo hi
+@echo $(FOO)
+endef # this is the end
+
+define simple:=
+@echo $(FOO)
+endef
+
+define posix::=
+@echo $(FOO)
+endef
+
+append = @echo a
+
+define append+=
+
+@echo b
+endef
+
+define cond?= # this is a conditional
+@echo first
+endef
+
+define cond?=
+@echo second
+endef
+
+FOO = there
+
+all: ; $(multi)
+ $(simple)
+ $(posix)
$(append)
$(cond)
',
- '', "echo hi\nhi\nthere\nfoo\na\nb\nfirst\n");
+ '', "echo hi\nhi\nthere\nfoo\nfoo\na\nb\nfirst\n");
# TEST 2: define in true section of conditional (containing conditional)
@@ -112,7 +160,7 @@ ouch
endef
all: ; @echo ok
',
- '', "#MAKEFILE#:3: extraneous text after `define' directive\nok\n");
+ '', "#MAKEFILE#:3: extraneous text after 'define' directive\nok\n");
# TEST 7: NEGATIVE: extra text after endef
@@ -123,7 +171,7 @@ ouch
endef $(NAME)
all: ; @echo ok
',
- '', "#MAKEFILE#:5: extraneous text after `endef' directive\nok\n");
+ '', "#MAKEFILE#:5: extraneous text after 'endef' directive\nok\n");
# TEST 8: NEGATIVE: missing endef
@@ -134,7 +182,7 @@ define NAME =
ouch
endef$(NAME)
',
- '', "#MAKEFILE#:4: *** missing `endef', unterminated `define'. Stop.\n", 512);
+ '', "#MAKEFILE#:4: *** missing 'endef', unterminated 'define'. Stop.\n", 512);
# -------------------------
# Make sure that prefix characters apply properly to define/endef values.
diff --git a/tests/scripts/variables/flavors b/tests/scripts/variables/flavors
index 92feed6..ba133ea 100644
--- a/tests/scripts/variables/flavors
+++ b/tests/scripts/variables/flavors
@@ -73,4 +73,24 @@ all: ; @echo $(foo)
',
'', "Hello\n");
+# TEST 6: Simple using POSIX syntax
+run_make_test('
+bar = Goodbye
+foo ::= $(bar)
+bar = ${ugh}
+ugh = Hello
+all: ; @echo $(foo)
+',
+ '', "Goodbye\n");
+
+# TEST 7: POSIX syntax no spaces
+run_make_test('
+bar = Goodbye
+foo::=$(bar)
+bar = ${ugh}
+ugh = Hello
+all: ; @echo $(foo)
+',
+ '', "Goodbye\n");
+
1;
diff --git a/tests/scripts/variables/private b/tests/scripts/variables/private
index b4baf5f..8967ffb 100644
--- a/tests/scripts/variables/private
+++ b/tests/scripts/variables/private
@@ -75,4 +75,48 @@ a b: ; @echo $@=$(private)
',
'', "b=a\na=a\n");
+# 9: make sure private suppresses inheritance
+run_make_test(q!
+DEFS = FOO
+all: bar1
+bar1: private DEFS += 1
+bar3: private DEFS += 3
+bar1: bar2
+bar2: bar3
+bar1 bar2 bar3: ; @echo '$@: $(DEFS)'
+!,
+ '', "bar3: FOO 3\nbar2: FOO\nbar1: FOO 1\n");
+
+# 10: Test append with pattern-specific variables and private
+
+run_make_test(q!
+IA = global
+PA = global
+PS = global
+S = global
+PS = global
+SV = global
+b%: IA += b%
+b%: private PA += b%
+b%: private PS = b%
+bar: all
+bar: IA += bar
+bar: private PA += bar
+bar: private PS = bar
+a%: IA += a%
+a%: private PA += a%
+a%: private PS = a%
+all: IA += all
+all: private PA += all
+all: private PS = all
+
+bar all: ; @echo '$@: IA=$(IA)'; echo '$@: PA=$(PA)'; echo '$@: PS=$(PS)'
+!,
+ '', "all: IA=global b% bar a% all
+all: PA=global a% all
+all: PS=all
+bar: IA=global b% bar
+bar: PA=global b% bar
+bar: PS=bar\n");
+
1;
diff --git a/tests/scripts/variables/special b/tests/scripts/variables/special
index a1e15c2..4637b2a 100644
--- a/tests/scripts/variables/special
+++ b/tests/scripts/variables/special
@@ -53,7 +53,7 @@ all:
# Test the .RECIPEPREFIX variable
&run_make_test('
define foo
-: foo-one \
+: foo-one\
foo-two
: foo-three
: foo-four
diff --git a/tests/test_driver.pl b/tests/test_driver.pl
index dec869d..2f83270 100644
--- a/tests/test_driver.pl
+++ b/tests/test_driver.pl
@@ -5,9 +5,7 @@
# Written 91-12-02 through 92-01-01 by Stephen McGee.
# Modified 92-02-11 through 92-02-22 by Chris Arthur to further generalize.
#
-# Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-# 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1991-2013 Free Software Foundation, Inc.
# This file is part of GNU Make.
#
# GNU Make is free software; you can redistribute it and/or modify it under
@@ -30,7 +28,7 @@
# this routine controls the whole mess; each test suite sets up a few
# variables and then calls &toplevel, which does all the real work.
-# $Id: test_driver.pl,v 1.30 2010/07/28 05:39:50 psmith Exp $
+# $Id$
# The number of test categories we've run
@@ -89,6 +87,7 @@ sub toplevel
foreach (# UNIX-specific things
'TZ', 'TMPDIR', 'HOME', 'USER', 'LOGNAME', 'PATH',
+ 'LD_LIBRARY_PATH',
# Purify things
'PURIFYOPTIONS',
# Windows NT-specific stuff
@@ -131,7 +130,7 @@ sub toplevel
&parse_command_line (@ARGV);
- print "OS name = `$osname'\n" if $debug;
+ print "OS name = '$osname'\n" if $debug;
$workpath = "$cwdslash$workdir";
$scriptpath = "$cwdslash$scriptdir";
@@ -166,7 +165,7 @@ sub toplevel
$dir = $1;
push (@rmdirs, $dir);
-d "$workpath/$dir"
- || mkdir ("$workpath/$dir", 0777)
+ || mkdir ("$workpath/$dir", 0777)
|| &error ("Couldn't mkdir $workpath/$dir: $!\n");
}
}
@@ -175,7 +174,7 @@ sub toplevel
{
print "Finding tests...\n";
opendir (SCRIPTDIR, $scriptpath)
- || &error ("Couldn't opendir $scriptpath: $!\n");
+ || &error ("Couldn't opendir $scriptpath: $!\n");
@dirs = grep (!/^(\..*|CVS|RCS)$/, readdir (SCRIPTDIR) );
closedir (SCRIPTDIR);
foreach $dir (@dirs)
@@ -185,13 +184,13 @@ sub toplevel
mkdir ("$workpath/$dir", 0777)
|| &error ("Couldn't mkdir $workpath/$dir: $!\n");
opendir (SCRIPTDIR, "$scriptpath/$dir")
- || &error ("Couldn't opendir $scriptpath/$dir: $!\n");
+ || &error ("Couldn't opendir $scriptpath/$dir: $!\n");
@files = grep (!/^(\..*|CVS|RCS|.*~)$/, readdir (SCRIPTDIR) );
closedir (SCRIPTDIR);
foreach $test (@files)
{
-d $test and next;
- push (@TESTS, "$dir/$test");
+ push (@TESTS, "$dir/$test");
}
}
}
@@ -203,7 +202,7 @@ sub toplevel
print "\n";
- &run_each_test;
+ run_all_tests();
foreach $dir (@rmdirs)
{
@@ -221,7 +220,7 @@ sub toplevel
print "s" unless $total_tests_failed == 1;
print " in $categories_failed Categor";
print ($categories_failed == 1 ? "y" : "ies");
- print " Failed (See .$diffext files in $workdir dir for details) :-(\n\n";
+ print " Failed (See .$diffext* files in $workdir dir for details) :-(\n\n";
return 0;
}
else
@@ -276,15 +275,15 @@ sub get_osname
eval "chop (\$osname = `sh -c 'uname -nmsr 2>&1'`)";
if ($osname =~ /not found/i)
{
- $osname = "(something posixy with no uname)";
+ $osname = "(something posixy with no uname)";
}
elsif ($@ ne "" || $?)
{
eval "chop (\$osname = `sh -c 'uname -a 2>&1'`)";
if ($@ ne "" || $?)
{
- $osname = "(something posixy)";
- }
+ $osname = "(something posixy)";
+ }
}
$vos = 0;
$pathsep = "/";
@@ -416,128 +415,133 @@ sub print_banner
print "\n";
}
-sub run_each_test
+sub run_all_tests
{
- $categories_run = 0;
+ $categories_run = 0;
+
+ foreach $testname (sort @TESTS) {
+ $suite_passed = 1; # reset by test on failure
+ $num_of_logfiles = 0;
+ $num_of_tmpfiles = 0;
+ $description = "";
+ $details = "";
+ $old_makefile = undef;
+ $testname =~ s/^$scriptpath$pathsep//;
+ $perl_testname = "$scriptpath$pathsep$testname";
+ $testname =~ s/(\.pl|\.perl)$//;
+ $testpath = "$workpath$pathsep$testname";
+ # Leave enough space in the extensions to append a number, even
+ # though it needs to fit into 8+3 limits.
+ if ($short_filenames) {
+ $logext = 'l';
+ $diffext = 'd';
+ $baseext = 'b';
+ $runext = 'r';
+ $extext = '';
+ } else {
+ $logext = 'log';
+ $diffext = 'diff';
+ $baseext = 'base';
+ $runext = 'run';
+ $extext = '.';
+ }
+ $log_filename = "$testpath.$logext";
+ $diff_filename = "$testpath.$diffext";
+ $base_filename = "$testpath.$baseext";
+ $run_filename = "$testpath.$runext";
+ $tmp_filename = "$testpath.$tmpfilesuffix";
- foreach $testname (sort @TESTS)
- {
- ++$categories_run;
- $suite_passed = 1; # reset by test on failure
- $num_of_logfiles = 0;
- $num_of_tmpfiles = 0;
- $description = "";
- $details = "";
- $old_makefile = undef;
- $testname =~ s/^$scriptpath$pathsep//;
- $perl_testname = "$scriptpath$pathsep$testname";
- $testname =~ s/(\.pl|\.perl)$//;
- $testpath = "$workpath$pathsep$testname";
- # Leave enough space in the extensions to append a number, even
- # though it needs to fit into 8+3 limits.
- if ($short_filenames) {
- $logext = 'l';
- $diffext = 'd';
- $baseext = 'b';
- $runext = 'r';
- $extext = '';
- } else {
- $logext = 'log';
- $diffext = 'diff';
- $baseext = 'base';
- $runext = 'run';
- $extext = '.';
- }
- $log_filename = "$testpath.$logext";
- $diff_filename = "$testpath.$diffext";
- $base_filename = "$testpath.$baseext";
- $run_filename = "$testpath.$runext";
- $tmp_filename = "$testpath.$tmpfilesuffix";
+ setup_for_test();
- &setup_for_test; # suite-defined
+ $output = "........................................................ ";
- $output = "........................................................ ";
+ substr($output,0,length($testname)) = "$testname ";
- substr($output,0,length($testname)) = "$testname ";
+ print $output;
- print $output;
+ $tests_run = 0;
+ $tests_passed = 0;
- # Run the actual test!
- $tests_run = 0;
- $tests_passed = 0;
+ # Run the test!
+ $code = do $perl_testname;
- $code = do $perl_testname;
+ ++$categories_run;
+ $total_tests_run += $tests_run;
+ $total_tests_passed += $tests_passed;
- $total_tests_run += $tests_run;
- $total_tests_passed += $tests_passed;
+ # How did it go?
+ if (!defined($code)) {
+ # Failed to parse or called die
+ if (length ($@)) {
+ warn "\n*** Test died ($testname): $@\n";
+ } else {
+ warn "\n*** Couldn't parse $perl_testname\n";
+ }
+ $status = "FAILED ($tests_passed/$tests_run passed)";
+ }
- # How did it go?
- if (!defined($code))
- {
- $suite_passed = 0;
- if (length ($@)) {
- warn "\n*** Test died ($testname): $@\n";
- } else {
- warn "\n*** Couldn't run $perl_testname\n";
- }
- }
- elsif ($code == -1) {
- $suite_passed = 0;
- }
- elsif ($code != 1 && $code != -1) {
- $suite_passed = 0;
- warn "\n*** Test returned $code\n";
- }
+ elsif ($code == -1) {
+ # Skipped... not supported
+ $status = "N/A";
+ --$categories_run;
+ }
- if ($suite_passed) {
- ++$categories_passed;
- $status = "ok ($tests_passed passed)";
- for ($i = $num_of_tmpfiles; $i; $i--)
- {
- &rmfiles ($tmp_filename . &num_suffix ($i) );
- }
+ elsif ($code != 1) {
+ # Bad result... this shouldn't really happen. Usually means that
+ # the suite forgot to end with "1;".
+ warn "\n*** Test returned $code\n";
+ $status = "FAILED ($tests_passed/$tests_run passed)";
+ }
- for ($i = $num_of_logfiles ? $num_of_logfiles : 1; $i; $i--)
- {
- &rmfiles ($log_filename . &num_suffix ($i) );
- &rmfiles ($base_filename . &num_suffix ($i) );
- }
- }
- elsif (!defined $code || $code > 0) {
- $status = "FAILED ($tests_passed/$tests_run passed)";
- }
- elsif ($code < 0) {
- $status = "N/A";
- --$categories_run;
- }
+ elsif ($tests_run == 0) {
+ # Nothing was done!!
+ $status = "FAILED (no tests found!)";
+ }
- # If the verbose option has been specified, then a short description
- # of each test is printed before displaying the results of each test
- # describing WHAT is being tested.
+ elsif ($tests_run > $tests_passed) {
+ # Lose!
+ $status = "FAILED ($tests_passed/$tests_run passed)";
+ }
- if ($verbose)
- {
- if ($detail)
- {
- print "\nWHAT IS BEING TESTED\n";
- print "--------------------";
- }
- print "\n\n$description\n\n";
- }
+ else {
+ # Win!
+ ++$categories_passed;
+ $status = "ok ($tests_passed passed)";
+
+ # Clean up
+ for ($i = $num_of_tmpfiles; $i; $i--) {
+ rmfiles($tmp_filename . num_suffix($i));
+ }
+ for ($i = $num_of_logfiles ? $num_of_logfiles : 1; $i; $i--) {
+ rmfiles($log_filename . num_suffix($i));
+ rmfiles($base_filename . num_suffix($i));
+ }
+ }
- # If the detail option has been specified, then the details of HOW
- # the test is testing what it says it is testing in the verbose output
- # will be displayed here before the results of the test are displayed.
+ # If the verbose option has been specified, then a short description
+ # of each test is printed before displaying the results of each test
+ # describing WHAT is being tested.
- if ($detail)
- {
- print "\nHOW IT IS TESTED\n";
- print "----------------";
- print "\n\n$details\n\n";
- }
+ if ($verbose) {
+ if ($detail) {
+ print "\nWHAT IS BEING TESTED\n";
+ print "--------------------";
+ }
+ print "\n\n$description\n\n";
+ }
- print "$status\n";
- }
+ # If the detail option has been specified, then the details of HOW
+ # the test is testing what it says it is testing in the verbose output
+ # will be displayed here before the results of the test are displayed.
+
+ if ($detail) {
+ print "\nHOW IT IS TESTED\n";
+ print "----------------";
+ print "\n\n$details\n\n";
+ }
+
+ print "$status\n";
+ }
}
# If the keep flag is not set, this subroutine deletes all filenames that
@@ -654,38 +658,43 @@ sub compare_output
local($answer,$logfile) = @_;
local($slurp, $answer_matched) = ('', 0);
- print "Comparing Output ........ " if $debug;
+ ++$tests_run;
- $slurp = &read_file_into_string ($logfile);
+ if (! defined $answer) {
+ print "Ignoring output ........ " if $debug;
+ $answer_matched = 1;
+ } else {
+ print "Comparing Output ........ " if $debug;
- # For make, get rid of any time skew error before comparing--too bad this
- # has to go into the "generic" driver code :-/
- $slurp =~ s/^.*modification time .*in the future.*\n//gm;
- $slurp =~ s/^.*Clock skew detected.*\n//gm;
+ $slurp = &read_file_into_string ($logfile);
- ++$tests_run;
+ # For make, get rid of any time skew error before comparing--too bad this
+ # has to go into the "generic" driver code :-/
+ $slurp =~ s/^.*modification time .*in the future.*\n//gm;
+ $slurp =~ s/^.*Clock skew detected.*\n//gm;
- if ($slurp eq $answer) {
- $answer_matched = 1;
- } else {
- # See if it is a slash or CRLF problem
- local ($answer_mod, $slurp_mod) = ($answer, $slurp);
+ if ($slurp eq $answer) {
+ $answer_matched = 1;
+ } else {
+ # See if it is a slash or CRLF problem
+ local ($answer_mod, $slurp_mod) = ($answer, $slurp);
- $answer_mod =~ tr,\\,/,;
- $answer_mod =~ s,\r\n,\n,gs;
+ $answer_mod =~ tr,\\,/,;
+ $answer_mod =~ s,\r\n,\n,gs;
- $slurp_mod =~ tr,\\,/,;
- $slurp_mod =~ s,\r\n,\n,gs;
+ $slurp_mod =~ tr,\\,/,;
+ $slurp_mod =~ s,\r\n,\n,gs;
- $answer_matched = ($slurp_mod eq $answer_mod);
+ $answer_matched = ($slurp_mod eq $answer_mod);
- # If it still doesn't match, see if the answer might be a regex.
- if (!$answer_matched && $answer =~ m,^/(.+)/$,) {
- $answer_matched = ($slurp =~ /$1/);
- if (!$answer_matched && $answer_mod =~ m,^/(.+)/$,) {
- $answer_matched = ($slurp_mod =~ /$1/);
+ # If it still doesn't match, see if the answer might be a regex.
+ if (!$answer_matched && $answer =~ m,^/(.+)/$,) {
+ $answer_matched = ($slurp =~ /$1/);
+ if (!$answer_matched && $answer_mod =~ m,^/(.+)/$,) {
+ $answer_matched = ($slurp_mod =~ /$1/);
+ }
+ }
}
- }
}
if ($answer_matched && $test_passed)
@@ -707,11 +716,8 @@ sub compare_output
local($command) = "diff -c " . &get_basefile . " " . $logfile;
&run_command_with_output(&get_difffile,$command);
- } else {
- &rmfiles ();
}
- $suite_passed = 0;
return 0;
}
@@ -731,6 +737,9 @@ sub read_file_into_string
return $slurp;
}
+my @OUTSTACK = ();
+my @ERRSTACK = ();
+
sub attach_default_output
{
local ($filename) = @_;
@@ -743,17 +752,16 @@ sub attach_default_output
return 1;
}
- open ("SAVEDOS" . $default_output_stack_level . "out", ">&STDOUT")
- || &error ("ado: $! duping STDOUT\n", 1);
- open ("SAVEDOS" . $default_output_stack_level . "err", ">&STDERR")
- || &error ("ado: $! duping STDERR\n", 1);
+ my $dup = undef;
+ open($dup, '>&', STDOUT) or error("ado: $! duping STDOUT\n", 1);
+ push @OUTSTACK, $dup;
- open (STDOUT, "> " . $filename)
- || &error ("ado: $filename: $!\n", 1);
- open (STDERR, ">&STDOUT")
- || &error ("ado: $filename: $!\n", 1);
+ $dup = undef;
+ open($dup, '>&', STDERR) or error("ado: $! duping STDERR\n", 1);
+ push @ERRSTACK, $dup;
- $default_output_stack_level++;
+ open(STDOUT, '>', $filename) or error("ado: $filename: $!\n", 1);
+ open(STDERR, ">&STDOUT") or error("ado: $filename: $!\n", 1);
}
# close the current stdout/stderr, and restore the previous ones from
@@ -770,23 +778,13 @@ sub detach_default_output
return 1;
}
- if (--$default_output_stack_level < 0)
- {
- &error ("default output stack has flown under!\n", 1);
- }
-
- close (STDOUT);
- close (STDERR);
+ @OUTSTACK or error("default output stack has flown under!\n", 1);
- open (STDOUT, ">&SAVEDOS" . $default_output_stack_level . "out")
- || &error ("ddo: $! duping STDOUT\n", 1);
- open (STDERR, ">&SAVEDOS" . $default_output_stack_level . "err")
- || &error ("ddo: $! duping STDERR\n", 1);
+ close(STDOUT);
+ close(STDERR);
- close ("SAVEDOS" . $default_output_stack_level . "out")
- || &error ("ddo: $! closing SCSDOSout\n", 1);
- close ("SAVEDOS" . $default_output_stack_level . "err")
- || &error ("ddo: $! closing SAVEDOSerr\n", 1);
+ open (STDOUT, '>&', pop @OUTSTACK) or error("ddo: $! duping STDOUT\n", 1);
+ open (STDERR, '>&', pop @ERRSTACK) or error("ddo: $! duping STDERR\n", 1);
}
# This runs a command without any debugging info.
@@ -800,14 +798,19 @@ sub _run_command
resetENV();
eval {
- local $SIG{ALRM} = sub { die "timeout\n"; };
+ my $pid = fork();
+ if (! $pid) {
+ exec(@_) or die "Cannot execute $_[0]\n";
+ }
+ local $SIG{ALRM} = sub { my $e = $ERRSTACK[0]; print $e "\nTest timed out after $test_timeout seconds\n"; die "timeout\n"; };
alarm $test_timeout;
- $code = system(@_);
+ waitpid($pid, 0) > 0 or die "No such pid: $pid\n";
+ $code = $?;
alarm 0;
};
if ($@) {
# The eval failed. If it wasn't SIGALRM then die.
- $@ eq "timeout\n" or die;
+ $@ eq "timeout\n" or die "Command failed: $@";
# Timed out. Resend the alarm to our process group to kill the children.
$SIG{ALRM} = 'IGNORE';
@@ -841,8 +844,12 @@ sub run_command_with_output
print "\nrun_command_with_output($filename,$runname): @_\n" if $debug;
&attach_default_output ($filename);
- my $code = _run_command(@_);
+ my $code = eval { _run_command(@_) };
+ my $err = $@;
&detach_default_output;
+
+ $err and die $err;
+
print "run_command_with_output returned $code.\n" if $debug;
return $code;
@@ -942,7 +949,7 @@ sub touch
foreach $file (@_) {
(open(T, ">> $file") && print(T "\n") && close(T))
- || &error("Couldn't touch $file: $!\n", 1);
+ || &error("Couldn't touch $file: $!\n", 1);
}
}