diff options
Diffstat (limited to 'tests/scripts/features')
27 files changed, 1069 insertions, 201 deletions
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 "; |