diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-08-26 19:24:46 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-08-26 19:24:46 +0400 |
commit | e46c9ea201b4bad8f4c6d19ee6dfb3537bc9facd (patch) | |
tree | 26ae9736985be2ef61032e7808b9fb0e2155c71f /tests/scripts | |
download | make.old-upstream.tar.gz |
Imported GNU Make 3.81upstream/3.82upstream
Diffstat (limited to 'tests/scripts')
106 files changed, 8376 insertions, 0 deletions
diff --git a/tests/scripts/features/comments b/tests/scripts/features/comments new file mode 100644 index 0000000..9257955 --- /dev/null +++ b/tests/scripts/features/comments @@ -0,0 +1,35 @@ +$description = "The following test creates a makefile to test comments\n" + ."and comment continuation to the next line using a \n" + ."backslash within makefiles."; + +$details = "To test comments within a makefile, a semi-colon was placed \n" + ."after a comment was started. This should not be reported as\n" + ."an error since it is within a comment. We then continue the \n" + ."comment to the next line using a backslash. To test whether\n" + ."the comment really continued, we place an echo command with some\n" + ."text on the line which should never execute since it should be \n" + ."within a comment\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<\EOF; +# Test comment vs semicolon parsing and line continuation +target: # this ; is just a comment \ + @echo This is within a comment. + @echo There should be no errors for this makefile. +EOF + +# 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 = "There should be no errors for this makefile.\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)) diff --git a/tests/scripts/features/conditionals b/tests/scripts/features/conditionals new file mode 100644 index 0000000..2ece60b --- /dev/null +++ b/tests/scripts/features/conditionals @@ -0,0 +1,146 @@ +# -*-perl-*- +$description = "Check GNU make conditionals."; + +$details = "Attempt various different flavors of GNU make conditionals."; + +run_make_test(' +arg1 = first +arg2 = second +arg3 = third +arg4 = cc +arg5 = second + +all: +ifeq ($(arg1),$(arg2)) + @echo arg1 equals arg2 +else + @echo arg1 NOT equal arg2 +endif + +ifeq \'$(arg2)\' "$(arg5)" + @echo arg2 equals arg5 +else + @echo arg2 NOT equal arg5 +endif + +ifneq \'$(arg3)\' \'$(arg4)\' + @echo arg3 NOT equal arg4 +else + @echo arg3 equal arg4 +endif + +ifndef undefined + @echo variable is undefined +else + @echo variable undefined is defined +endif +ifdef arg4 + @echo arg4 is defined +else + @echo arg4 is NOT defined +endif', + '', + 'arg1 NOT equal arg2 +arg2 equals arg5 +arg3 NOT equal arg4 +variable is undefined +arg4 is defined'); + + +# Test expansion of variables inside ifdef. + +run_make_test(' +foo = 1 + +FOO = foo +F = f + +DEF = no +DEF2 = no + +ifdef $(FOO) +DEF = yes +endif + +ifdef $(F)oo +DEF2 = yes +endif + + +DEF3 = no +FUNC = $1 +ifdef $(call FUNC,DEF)3 + DEF3 = yes +endif + +all:; @echo DEF=$(DEF) DEF2=$(DEF2) DEF3=$(DEF3)', + '', + 'DEF=yes DEF2=yes DEF3=yes'); + + +# Test all the different "else if..." constructs + +run_make_test(' +arg1 = first +arg2 = second +arg3 = third +arg4 = cc +arg5 = fifth + +result = + +ifeq ($(arg1),$(arg2)) + result += arg1 equals arg2 +else ifeq \'$(arg2)\' "$(arg5)" + result += arg2 equals arg5 +else ifneq \'$(arg3)\' \'$(arg3)\' + result += arg3 NOT equal arg4 +else ifndef arg5 + result += variable is undefined +else ifdef undefined + result += arg4 is defined +else + result += success +endif + + +all: ; @echo $(result)', + '', + 'success'); + + +# Test some random "else if..." construct nesting + +run_make_test(' +arg1 = first +arg2 = second +arg3 = third +arg4 = cc +arg5 = second + +ifeq ($(arg1),$(arg2)) + $(info failed 1) +else ifeq \'$(arg2)\' "$(arg2)" + ifdef undefined + $(info failed 2) + else + $(info success) + endif +else ifneq \'$(arg3)\' \'$(arg3)\' + $(info failed 3) +else ifdef arg5 + $(info failed 4) +else ifdef undefined + $(info failed 5) +else + $(info failed 6) +endif + +.PHONY: all +all: ; @:', + '', + 'success'); + + +# 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 new file mode 100644 index 0000000..e53127e --- /dev/null +++ b/tests/scripts/features/default_names @@ -0,0 +1,41 @@ +# -*-perl-*- + +$description = "This script tests to make sure that Make looks for +default makefiles in the correct order (GNUmakefile,makefile,Makefile)"; + +# Create a makefile called "GNUmakefile" +$makefile = "GNUmakefile"; + +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"; +close(MAKEFILE); + + +&run_make_with_options("","",&get_logfile); +&compare_output("It chose GNUmakefile\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"; +} + +&run_make_with_options("","",&get_logfile); +&compare_output("It chose Makefile\n",&get_logfile(1)); +unlink "Makefile"; diff --git a/tests/scripts/features/double_colon b/tests/scripts/features/double_colon new file mode 100644 index 0000000..cad605d --- /dev/null +++ b/tests/scripts/features/double_colon @@ -0,0 +1,155 @@ +# -*-perl-*- +$description = "Test handling of double-colon rules."; + +$details = "\ +We test these features: + + - Multiple commands for the same (double-colon) target + - Different prerequisites for targets: only out-of-date + ones are rebuilt. + - Double-colon targets that aren't the goal target. + +Then we do the same thing for parallel builds: double-colon +targets should always be built serially."; + +# The Contents of the MAKEFILE ... + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +all: baz + +foo:: f1.h ; @echo foo FIRST +foo:: f2.h ; @echo foo SECOND + +bar:: ; @echo aaa; sleep 1; echo aaa done +bar:: ; @echo bbb + +baz:: ; @echo aaa +baz:: ; @echo bbb + +biz:: ; @echo aaa +biz:: two ; @echo bbb + +two: ; @echo two + +f1.h f2.h: ; @echo $@ + +d :: ; @echo ok +d :: d ; @echo oops + +EOF + +close(MAKEFILE); + +# TEST 0: A simple double-colon rule that isn't the goal target. + +&run_make_with_options($makefile, "all", &get_logfile, 0); +$answer = "aaa\nbbb\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 1: As above, in parallel + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 all", &get_logfile, 0); + $answer = "aaa\nbbb\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 2: A simple double-colon rule that is the goal target + +&run_make_with_options($makefile, "bar", &get_logfile, 0); +$answer = "aaa\naaa done\nbbb\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 3: As above, in parallel + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 bar", &get_logfile, 0); + $answer = "aaa\naaa done\nbbb\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 4: Each double-colon rule is supposed to be run individually + +&utouch(-5, 'f2.h'); +&touch('foo'); + +&run_make_with_options($makefile, "foo", &get_logfile, 0); +$answer = "f1.h\nfoo FIRST\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 5: Again, in parallel. + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 foo", &get_logfile, 0); + $answer = "f1.h\nfoo FIRST\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 6: Each double-colon rule is supposed to be run individually + +&utouch(-5, 'f1.h'); +unlink('f2.h'); +&touch('foo'); + +&run_make_with_options($makefile, "foo", &get_logfile, 0); +$answer = "f2.h\nfoo SECOND\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 7: Again, in parallel. + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 foo", &get_logfile, 0); + $answer = "f2.h\nfoo SECOND\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 8: Test circular dependency check; PR/1671 + +&run_make_with_options($makefile, "d", &get_logfile, 0); +$answer = "ok\n$make_name: Circular d <- d dependency dropped.\noops\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 8: I don't grok why this is different than the above, but it is... +# +# Hmm... further testing indicates this might be timing-dependent? +# +#if ($parallel_jobs) { +# &run_make_with_options($makefile, "-j10 biz", &get_logfile, 0); +# $answer = "aaa\ntwo\nbbb\n"; +# &compare_output($answer, &get_logfile(1)); +#} + +unlink('foo','f1.h','f2.h'); + + +# TEST 9: make sure all rules in s double colon family get executed +# (Savannah bug #14334). +# + +&touch('one'); +&touch('two'); + +run_make_test(' +.PHONY: all +all: result + +result:: one + @echo $^ >>$@ + @echo $^ + +result:: two + @echo $^ >>$@ + @echo $^ + +', +'', +'one +two'); + +unlink('result','one','two'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/echoing b/tests/scripts/features/echoing new file mode 100644 index 0000000..40debf5 --- /dev/null +++ b/tests/scripts/features/echoing @@ -0,0 +1,64 @@ +# -*-perl-*- +$description = "The following test creates a makefile to test command +echoing. It tests that when a command line starts with +a '\@', the echoing of that line is suppressed. It also +tests the -n option which tells make to ONLY echo the +commands and no execution happens. In this case, even +the commands with '\@' are printed. Lastly, it tests the +-s flag which tells make to prevent all echoing, as if +all commands started with a '\@'."; + +$details = "This test is similar to the 'clean' test except that a '\@' has +been placed in front of the delete command line. Four tests +are run here. First, make is run normally and the first echo +command should be executed. In this case there is no '\@' so +we should expect make to display the command AND display the +echoed message. Secondly, make is run with the clean target, +but since there is a '\@' at the beginning of the command, we +expect no output; just the deletion of a file which we check +for. Third, we give the clean target again except this time +we give make the -n option. We now expect the command to be +displayed but not to be executed. In this case we need only +to check the output since an error message would be displayed +if it actually tried to run the delete command again and the +file didn't exist. Lastly, we run the first test again with +the -s option and check that make did not echo the echo +command before printing the message.\n"; + +$example = "EXAMPLE_FILE"; + +touch($example); + +# TEST #1 +# ------- + +run_make_test(" +all: +\techo This makefile did not clean the dir... good +clean: +\t\@$delete_command $example\n", + '', 'echo This makefile did not clean the dir... good +This makefile did not clean the dir... good'); + +# TEST #2 +# ------- + +run_make_test(undef, 'clean', ''); +if (-f $example) { + $test_passed = 0; + unlink($example); +} + +# TEST #3 +# ------- + +run_make_test(undef, '-n clean', "$delete_command $example\n"); + + +# TEST #4 +# ------- + +run_make_test(undef, '-s', "This makefile did not clean the dir... good\n"); + + +1; diff --git a/tests/scripts/features/errors b/tests/scripts/features/errors new file mode 100644 index 0000000..e372fe0 --- /dev/null +++ b/tests/scripts/features/errors @@ -0,0 +1,92 @@ +# -*-perl-*- + +$description = "The following tests the -i option and the '-' in front of \n" + ."commands to test that make ignores errors in these commands\n" + ."and continues processing."; + +$details = "This test runs two makes. The first runs on a target with a \n" + ."command that has a '-' in front of it (and a command that is \n" + ."intended to fail) and then a delete command after that is \n" + ."intended to succeed. If make ignores the failure of the first\n" + ."command as it is supposed to, then the second command should \n" + ."delete a file and this is what we check for. The second make\n" + ."that is run in this test is identical except that the make \n" + ."command is given with the -i option instead of the '-' in \n" + ."front of the command. They should run the same. "; + +if ($vos) +{ + $rm_command = "delete_file"; +} +else +{ + $rm_command = "rm"; +} + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "clean:\n" + ."\t-$rm_command cleanit\n" + ."\t$rm_command foo\n" + ."clean2: \n" + ."\t$rm_command cleanit\n" + ."\t$rm_command foo\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("foo"); + +unlink("cleanit"); +$cleanit_error = `sh -c "$rm_command cleanit 2>&1"`; +$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"; + +&run_make_with_options($makefile,"",&get_logfile); + +# If make acted as planned, it should ignore the error from the first +# command in the target and execute the second which deletes the file "foo" +# This file, therefore, should not exist if the test PASSES. +if (-f "foo") { + $test_passed = 0; +} + +# The output for this on VOS is too hard to replicate, so we only check it +# on unix. +if (!$vos) +{ + &compare_output($answer,&get_logfile(1)); +} + + +&touch("foo"); + +# TEST #2 +# ------- + +$answer = "$rm_command cleanit\n" + . $cleanit_error + ."$make_name: [clean2] Error $delete_error_code (ignored)\n" + ."$rm_command foo\n"; + +&run_make_with_options($makefile,"clean2 -i",&get_logfile); + +if (-f "foo") { + $test_passed = 0; +} + +if (!$vos) { + &compare_output($answer,&get_logfile(1)); +} + +1; diff --git a/tests/scripts/features/escape b/tests/scripts/features/escape new file mode 100644 index 0000000..97a2994 --- /dev/null +++ b/tests/scripts/features/escape @@ -0,0 +1,58 @@ +# -*-perl-*- +$description = "Test various types of escaping in makefiles."; + +$details = "\ +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); + + +# TEST 1 + +run_make_test(' +$(path)foo : ; @echo "touch ($@)" + +foo\ bar: ; @echo "touch ($@)" + +sharp: foo\#bar.ext +foo\#bar.ext: ; @echo "foo#bar.ext = ($@)"', + '', + 'touch (foo)'); + +# TEST 2: This one should fail, since the ":" is unquoted. + +run_make_test(undef, + 'path=pre:', + "#MAKEFILE#:2: *** target pattern contains no `%'. Stop.", + 512); + +# TEST 3: This one should work, since we escape the ":". + +run_make_test(undef, + "'path=pre\\:'", + 'touch (pre:foo)'); + +# TEST 4: This one should fail, since the escape char is escaped. + +run_make_test(undef, + "'path=pre\\\\:'", + "#MAKEFILE#:2: *** target pattern contains no `%'. Stop.", + 512); + +# TEST 5: This one should work + +run_make_test(undef, + "'foo bar'", + 'touch (foo bar)'); + +# TEST 6: Test escaped comments + +run_make_test(undef, + 'sharp', + 'foo#bar.ext = (foo#bar.ext)'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/export b/tests/scripts/features/export new file mode 100644 index 0000000..81bff0c --- /dev/null +++ b/tests/scripts/features/export @@ -0,0 +1,186 @@ +# -*-perl-*- +$description = "Check GNU make export/unexport commands."; + +$details = ""; + +# The test driver cleans out our environment for us so we don't have to worry +# about that here. + +&run_make_test(' +FOO = foo +BAR = bar +BOZ = boz + +export BAZ = baz +export BOZ + +BITZ = bitz +BOTZ = botz + +export BITZ BOTZ +unexport BOTZ + +ifdef EXPORT_ALL +export +endif + +ifdef UNEXPORT_ALL +unexport +endif + +ifdef EXPORT_ALL_PSEUDO +.EXPORT_ALL_VARIABLES: +endif + +all: + @echo "FOO=$(FOO) BAR=$(BAR) BAZ=$(BAZ) BOZ=$(BOZ) BITZ=$(BITZ) BOTZ=$(BOTZ)" + @echo "FOO=$$FOO BAR=$$BAR BAZ=$$BAZ BOZ=$$BOZ BITZ=$$BITZ BOTZ=$$BOTZ" +', + '', "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 1: make sure vars inherited from the parent are exported + +$extraENV{FOO} = 1; + +&run_make_test(undef, '', "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO=foo BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 2: global export. Explicit unexport takes precedence. + +run_make_test(undef, "EXPORT_ALL=1" , + "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 3: global unexport. Explicit export takes precedence. + +&run_make_test(undef, "UNEXPORT_ALL=1", + "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 4: both: in the above makefile the unexport comes last so that rules. + +&run_make_test(undef, "EXPORT_ALL=1 UNEXPORT_ALL=1", + "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 5: test the pseudo target. + +&run_make_test(undef, "EXPORT_ALL_PSEUDO=1", + "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 6: Test the expansion of variables inside export + +&run_make_test(' +foo = f-ok +bar = b-ok + +FOO = foo +F = f + +BAR = bar +B = b + +export $(FOO) +export $(B)ar + +all: + @echo foo=$(foo) bar=$(bar) + @echo foo=$$foo bar=$$bar +', + "", "foo=f-ok bar=b-ok\nfoo=f-ok bar=b-ok\n"); + +# TEST 7: Test the expansion of variables inside unexport + +&run_make_test(' +foo = f-ok +bar = b-ok + +FOO = foo +F = f + +BAR = bar +B = b + +export foo bar + +unexport $(FOO) +unexport $(B)ar + +all: + @echo foo=$(foo) bar=$(bar) + @echo foo=$$foo bar=$$bar +', + '', "foo=f-ok bar=b-ok\nfoo= bar=\n"); + +# TEST 7: Test exporting multiple variables on the same line + +&run_make_test(' +A = a +B = b +C = c +D = d +E = e +F = f +G = g +H = h +I = i +J = j + +SOME = A B C + +export F G H I J + +export D E $(SOME) + +all: ; @echo A=$$A B=$$B C=$$C D=$$D E=$$E F=$$F G=$$G H=$$H I=$$I J=$$J +', + '', "A=a B=b C=c D=d E=e F=f G=g H=h I=i J=j\n"); + +# TEST 8: Test unexporting multiple variables on the same line + +@extraENV{qw(A B C D E F G H I J)} = qw(1 2 3 4 5 6 7 8 9 10); + +&run_make_test(' +A = a +B = b +C = c +D = d +E = e +F = f +G = g +H = h +I = i +J = j + +SOME = A B C + +unexport F G H I J + +unexport D E $(SOME) + +all: ; @echo A=$$A B=$$B C=$$C D=$$D E=$$E F=$$F G=$$G H=$$H I=$$I J=$$J +', + '', "A= B= C= D= E= F= G= H= I= J=\n"); + +# TEST 9: Check setting a variable named "export" + +&run_make_test(' +export = 123 +export export +export export = 456 +a: ; @echo "\$$(export)=$(export) / \$$export=$$export" +', + '', "\$(export)=456 / \$export=456\n"); + +# TEST 9: Check "export" as a target + +&run_make_test(' +a: export +export: ; @echo "$@" +', + '', "export\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 new file mode 100644 index 0000000..ba8908c --- /dev/null +++ b/tests/scripts/features/include @@ -0,0 +1,179 @@ +# -*-mode: perl; rm-trailing-spaces: nil-*- + +$description = "Test various forms of the GNU make `include' command."; + +$details = "\ +Test include, -include, sinclude and various regressions involving them. +Test extra whitespace at the end of the include, multiple -includes and +sincludes (should not give an error) and make sure that errors are reported +for targets that were also -included."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The contents of the Makefile ... + +print MAKEFILE <<EOF; +\#Extra space at the end of the following file name +include $makefile2 +all: ; \@echo There should be no errors for this makefile. + +-include nonexistent.mk +-include nonexistent.mk +sinclude nonexistent.mk +sinclude nonexistent-2.mk +-include makeit.mk +sinclude makeit.mk + +error: makeit.mk +EOF + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE "ANOTHER: ; \@echo This is another included makefile\n"; + +close(MAKEFILE); + +# Create the answer to what should be produced by this Makefile +&run_make_with_options($makefile, "all", &get_logfile); +$answer = "There should be no errors for this makefile.\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile, "ANOTHER", &get_logfile); +$answer = "This is another included makefile\n"; +&compare_output($answer, &get_logfile(1)); + +$makefile = undef; + +# Try to build the "error" target; this will fail since we don't know +# how to create makeit.mk, but we should also get a message (even though +# the -include suppressed it during the makefile read phase, we should +# see one during the makefile run phase). + +run_make_test + (' +-include foo.mk +error: foo.mk ; @echo $@ +', + '', + "#MAKE#: *** No rule to make target `foo.mk', needed by `error'. Stop.\n", + 512 + ); + +# Make sure that target-specific variables don't impact things. This could +# happen because a file record is created when a target-specific variable is +# set. + +run_make_test + (' +bar.mk: foo := baz +-include bar.mk +hello: ; @echo hello +', + '', + "hello\n" + ); + + +# Test inheritance of dontcare flag when rebuilding makefiles. +# +run_make_test(' +.PHONY: all +all: ; @: + +-include foo + +foo: bar; @: +', '', ''); + + +# Make sure that we don't die when the command fails but we dontcare. +# (Savannah bug #13216). +# +run_make_test(' +.PHONY: all +all:; @: + +-include foo + +foo: bar; @: + +bar:; @exit 1 +', '', ''); + +# Check include, sinclude, -include with no filenames. +# (Savannah bug #1761). + +run_make_test(' +.PHONY: all +all:; @: +include +-include +sinclude', '', ''); + + +# Test that the diagnostics is issued even if the target has been +# tried before with the dontcare flag (direct dependency case). +# +run_make_test(' +-include foo + +all: bar + +foo: baz +bar: baz +', +'', +"#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 +# tried before with the dontcare flag (indirect dependency case). +# +run_make_test(' +-include foo + +all: bar + +foo: baz +bar: baz +baz: end +', +'', +"#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 +# tried before with the dontcare flag (include/-include case). +# +run_make_test(' +include bar +-include foo + +all: + +foo: baz +bar: baz +baz: end +', +'', +"#MAKEFILE#:2: bar: No such file or directory +#MAKE#: *** No rule to make target `end', needed by `baz'. Stop.\n", +512); + +if ($all_tests) { + # Test that include of a rebuild-able file doesn't show a warning + # Savannah bug #102 + run_make_test(q! +include foo +foo: ; @echo foo = bar > $@ +!, + '', "#MAKE#: `foo' is up to date.\n"); + rmfiles('foo'); +} + +1; diff --git a/tests/scripts/features/mult_rules b/tests/scripts/features/mult_rules new file mode 100644 index 0000000..6f120f1 --- /dev/null +++ b/tests/scripts/features/mult_rules @@ -0,0 +1,78 @@ +$description = "\ +The following test creates a makefile to test the presence +of multiple rules for one target. One file can be the +target of several rules if at most one rule has commands; +the other rules can only have dependencies."; + +$details = "\ +The makefile created in this test contains two hardcoded rules +for foo.o and bar.o. It then gives another multiple target rule +with the same names as above but adding more dependencies. +Additionally, another variable extradeps is listed as a +dependency but is defined to be null. It can however be defined +on the make command line as extradeps=extra.h which adds yet +another dependency to the targets."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOF; +objects = foo.o bar.o +foo.o : defs.h +bar.o : defs.h test.h +extradeps = +\$(objects) : config.h \$(extradeps) +\t\@echo EXTRA EXTRA +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("defs.h","test.h","config.h"); + +if ($vos) +{ + $error_code = 3307; +} +else +{ + $error_code = 512; +} + +&run_make_with_options($makefile, + "extradeps=extra.h", + &get_logfile, + $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"; + +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- + +&touch("extra.h"); + +&run_make_with_options($makefile, + "extradeps=extra.h", + &get_logfile, + 0); + +# Create the answer to what should be produced by this Makefile +$answer = "EXTRA EXTRA\n"; + +&compare_output($answer,&get_logfile(1)); + +unlink("defs.h","test.h","config.h","extra.h"); + +1; + + + + + + diff --git a/tests/scripts/features/mult_targets b/tests/scripts/features/mult_targets new file mode 100644 index 0000000..c8ff418 --- /dev/null +++ b/tests/scripts/features/mult_targets @@ -0,0 +1,46 @@ +$description = "The following test creates a makefile to test that a \n " + ."rule with multiple targets is equivalent to writing \n" + ."many rules, each with one target, and all identical aside\n" + ."from that."; + +$details = "A makefile is created with one rule and two targets. Make \n" + ."is called twice, once for each target, and the output which \n" + ."contains the target name with \$@ is looked at for the changes.\n" + ."This test also tests the substitute function by replacing \n" + ."the word output with nothing in the target name giving either\n" + ."an output of \"I am little\" or \"I am big\""; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "bigoutput littleoutput: test.h\n"; +print MAKEFILE "\t\@echo I am \$(subst output,,\$@)\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("test.h"); + +&run_make_with_options($makefile,"bigoutput",&get_logfile); + + +# Create the answer to what should be produced by this Makefile +$answer = "I am big\n"; + +&compare_output($answer,&get_logfile(1)); + +&run_make_with_options($makefile,"littleoutput",&get_logfile); +$answer = "I am little\n"; +&compare_output($answer,&get_logfile(1)); + +unlink "test.h"; + +1; + + + + + + diff --git a/tests/scripts/features/order_only b/tests/scripts/features/order_only new file mode 100644 index 0000000..4ebdc2b --- /dev/null +++ b/tests/scripts/features/order_only @@ -0,0 +1,118 @@ +# -*-perl-*- +$description = "Test order-only prerequisites."; + +$details = "\ +Create makefiles with various combinations of normal and order-only +prerequisites and ensure they behave properly. Test the \$| variable."; + +# TEST #0 -- Basics + +run_make_test(' +%r: | baz ; @echo $< $^ $| +bar: foo +foo:;@: +baz:;@:', + '', "foo foo baz\n"); + +# TEST #1 -- First try: the order-only prereqs need to be built. + +run_make_test(q! +foo: bar | baz + @echo '$$^ = $^' + @echo '$$| = $|' + touch $@ + +.PHONY: baz + +bar baz: + touch $@!, + '', "touch bar\ntouch baz\n\$^ = bar\n\$| = baz\ntouch foo\n"); + + +# TEST #2 -- now we do it again: baz is PHONY but foo should _NOT_ be updated + +run_make_test(undef, '', "touch baz\n"); + +unlink(qw(foo bar baz)); + +# TEST #3 -- Make sure the order-only prereq was promoted to normal. + +run_make_test(q! +foo: bar | baz + @echo '$$^ = $^' + @echo '$$| = $|' + touch $@ + +foo: baz + +.PHONY: baz + +bar baz: + touch $@!, + '', "touch bar\ntouch baz\n\$^ = bar baz\n\$| = \ntouch foo\n"); + + +# TEST #4 -- now we do it again + +run_make_test(undef, '', "touch baz\n\$^ = bar baz\n\$| = \ntouch foo\n"); + +unlink(qw(foo bar baz)); + +# Test empty normal prereqs + +# TEST #5 -- make sure the parser was correct. + +run_make_test(q! +foo:| baz + @echo '$$^ = $^' + @echo '$$| = $|' + touch $@ + +.PHONY: baz + +baz: + touch $@!, + '', "touch baz\n\$^ = \n\$| = baz\ntouch foo\n"); + +# TEST #6 -- now we do it again: this time foo won't be built + +run_make_test(undef, '', "touch baz\n"); + +unlink(qw(foo baz)); + +# Test order-only in pattern rules + +# TEST #7 -- make sure the parser was correct. + +run_make_test(q! +%.w : %.x | baz + @echo '$$^ = $^' + @echo '$$| = $|' + touch $@ + +all: foo.w + +.PHONY: baz +foo.x baz: + touch $@!, + '', + "touch foo.x\ntouch baz\n\$^ = foo.x\n\$| = baz\ntouch foo.w\n"); + +# TEST #8 -- now we do it again: this time foo.w won't be built + +run_make_test(undef, '', "touch baz\n"); + +unlink(qw(foo.w foo.x baz)); + +# TEST #9 -- make sure that $< is set correctly in the face of order-only +# prerequisites in pattern rules. + +run_make_test(' +%r: | baz ; @echo $< $^ $| +bar: foo +foo:;@: +baz:;@:', + '', "foo foo baz\n"); + + +1; diff --git a/tests/scripts/features/override b/tests/scripts/features/override new file mode 100644 index 0000000..fff6c4e --- /dev/null +++ b/tests/scripts/features/override @@ -0,0 +1,45 @@ +# -*-perl-*- + +$description = "Test the override directive on variable assignments."; + +$details = ""; + +# TEST 0: Basic override + +run_make_test(' +X = start +override recur = $(X) +override simple := $(X) +X = end +all: ; @echo "$(recur) $(simple)" +', + 'recur=I simple=J', "end start\n"); + +# TEST 1: Override with append + +run_make_test(' +X += X1 +override X += X2 +override Y += Y1 +Y += Y2 +all: ; @echo "$(X) $(Y)" +', + '', "X1 X2 Y1\n"); + +# TEST 2: Override with append to the command line + +run_make_test(undef, 'X=C Y=C', "C X2 C Y1\n"); + +# Test override of define/endef + +run_make_test(' +override define foo +@echo First comes the definition. +@echo Then comes the override. +endef +all: ; $(foo) +', + 'foo=Hello', "First comes the definition.\nThen comes the override.\n"); + + +1; diff --git a/tests/scripts/features/parallelism b/tests/scripts/features/parallelism new file mode 100644 index 0000000..cc0f84f --- /dev/null +++ b/tests/scripts/features/parallelism @@ -0,0 +1,254 @@ +# -*-perl-*- + +$description = "Test parallelism (-j) option."; + + +$details = "This test creates a makefile with two double-colon default +rules. The first rule has a series of sleep and echo commands +intended to run in series. The second and third have just an +echo statement. When make is called in this test, it is given +the -j option with a value of 4. This tells make that it may +start up to four jobs simultaneously. In this case, since the +first command is a sleep command, the output of the second +and third commands will appear before the first if indeed +make is running all of these commands in parallel."; + +if (!$parallel_jobs) { + return -1; +} + +if ($vos) { + $sleep_command = "sleep -seconds"; +} +else { + $sleep_command = "sleep"; +} + + +run_make_test(" +all : def_1 def_2 def_3 +def_1 : ; \@echo ONE; $sleep_command 3 ; echo TWO +def_2 : ; \@$sleep_command 2 ; echo THREE +def_3 : ; \@$sleep_command 1 ; echo FOUR", + '-j4', "ONE\nFOUR\nTHREE\nTWO"); + +# Test parallelism with included files. Here we sleep/echo while +# building the included files, to test that they are being built in +# parallel. +run_make_test(" +all: 1 2; \@echo success +-include 1.inc 2.inc +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"); + +rmfiles(qw(1.inc 2.inc)); + + +# Test parallelism with included files--this time recurse first and make +# sure the jobserver works. +run_make_test(" +recurse: ; \@\$(MAKE) --no-print-directory -f #MAKEFILE# INC=yes all +all: 1 2; \@echo success + +INC = no +ifeq (\$(INC),yes) +-include 1.inc 2.inc +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"); + +rmfiles(qw(1.inc 2.inc)); + +# Grant Taylor reports a problem where tokens can be lost (not written back +# to the pipe when they should be): this happened when there is a $(shell ...) +# function in an exported recursive variable. I added some code to check +# for this situation and print a message if it occurred. This test used +# to trigger this code when I added it but no longer does after the fix. +# We have to increase the timeout from the default (5s) on this test. + +run_make_test(" +export HI = \$(shell \$(\$\@.CMD)) +first.CMD = echo hi +second.CMD = $sleep_command 4; echo hi + +.PHONY: all first second +all: first second + +first second: ; \@echo \$\@; $sleep_command 1; echo \$\@", + '-j2', "first\nfirst\nsecond\nsecond", 0, 7); + +# Michael Matz <matz@suse.de> reported a bug where if make is running in +# parallel without -k and two jobs die in a row, but not too close to each +# other, then make will quit without waiting for the rest of the jobs to die. + +run_make_test(" +.PHONY: all fail.1 fail.2 fail.3 ok +all: fail.1 ok fail.2 fail.3 + +fail.1 fail.2 fail.3: + \@sleep \$(patsubst fail.%,%,\$\@) + \@echo Fail + \@exit 1 + +ok: + \@sleep 4 + \@echo Ok done", + '-rR -j5', 'Fail +#MAKE#: *** [fail.1] Error 1 +#MAKE#: *** Waiting for unfinished jobs.... +Fail +#MAKE#: *** [fail.2] Error 1 +Fail +#MAKE#: *** [fail.3] Error 1 +Ok done', + 512); + + +# Test for Savannah bug #15641. +# +run_make_test(' +.PHONY: all +all:; @: + +-include foo.d + +foo.d: comp + @echo building $@ + +comp: mod_a.o mod_b.o; @: + +mod_a.o mod_b.o: + @exit 1 +', '-j2', ''); + + +# TEST #9 -- Savannah bugs 3330 and 15919 +# In earlier versions of make this will either give the wrong answer, or hang. + +utouch(-10, 'target'); +run_make_test('target: intermed ; touch $@ + +.INTERMEDIATE: intermed +intermed: | phony ; touch $@ + +.PHONY: phony +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 + +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"); + +rmfiles('inc.mk'); + +if ($all_tests) { + # Implicit files aren't properly recreated during parallel builds + # Savannah bug #26864 + + # 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)); +} + +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 +!, + '-j2', + '#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode. +true +true +'); +} + +# Make sure that all jobserver FDs are closed if we need to re-exec the +# master copy. +# +# First, find the "default" file descriptors we normally use +# Then make sure they're still used. +# +# Right now we don't have a way to run a makefile and capture the output +# without checking it, so we can't really write this test. + +# run_make_test(' +# submake: ; @$(MAKE) --no-print-directory -f #MAKEFILE# fdprint 5>output + +# dependfile: ; @echo FOO=bar > $@ + +# INCL := true + +# FOO=foo +# ifeq ($(INCL),true) +# -include dependfile +# endif + +# fdprint: ; @echo $(filter --jobserver%,$(MAKEFLAGS)) + +# recurse: ; @$(MAKE) --no-print-directory -f #MAKEFILE# submake INCL=true', +# '-j2 INCL=false fdprint', +# 'bar'); + +# rmfiles(qw(dependfile output)); + + +# # Do it again, this time where the include is done by the non-master make. +# run_make_test(undef, '-j2 recurse INCL=false', 'bar'); + +# rmfiles(qw(dependfile output)); + +1; diff --git a/tests/scripts/features/patspecific_vars b/tests/scripts/features/patspecific_vars new file mode 100644 index 0000000..8ca228d --- /dev/null +++ b/tests/scripts/features/patspecific_vars @@ -0,0 +1,148 @@ +# -*-perl-*- +$description = "Test pattern-specific variable settings."; + +$details = "\ +Create a makefile containing various flavors of pattern-specific variable +settings, override and non-override, and using various variable expansion +rules, semicolon interference, etc."; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +all: one.x two.x three.x +FOO = foo +BAR = bar +BAZ = baz +one.x: override FOO = one +%.x: BAR = two +t%.x: BAR = four +thr% : override BAZ = three +one.x two.x three.x: ; @echo $@: $(FOO) $(BAR) $(BAZ) +four.x: baz ; @echo $@: $(FOO) $(BAR) $(BAZ) +baz: ; @echo $@: $(FOO) $(BAR) $(BAZ) + +# test matching multiple patterns +a%: AAA = aaa +%b: BBB = ccc +a%: BBB += ddd +%b: AAA ?= xxx +%b: AAA += bbb +.PHONY: ab +ab: ; @echo $(AAA); echo $(BBB) +EOF + +close(MAKEFILE); + + +# TEST #1 -- basics + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "one.x: one two baz\ntwo.x: foo four baz\nthree.x: foo four three\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 -- try the override feature + +&run_make_with_options($makefile, "BAZ=five", &get_logfile); +$answer = "one.x: one two five\ntwo.x: foo four five\nthree.x: foo four three\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 -- make sure patterns are inherited properly + +&run_make_with_options($makefile, "four.x", &get_logfile); +$answer = "baz: foo two baz\nfour.x: foo two baz\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #4 -- test multiple patterns matching the same target + +&run_make_with_options($makefile, "ab", &get_logfile); +$answer = "aaa bbb\nccc ddd\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #5 -- test pattern-specific exported variables +# +run_make_test(' +/%: export foo := foo + +/bar: + @echo $(foo) $$foo +', '', 'foo foo'); + + +# TEST #6 -- test expansion of pattern-specific simple variables +# +run_make_test(' +.PHONY: all + +all: inherit := good $$t +all: bar baz + +b%: pattern := good $$t + +global := orginal $$t + + +# normal target +# +ifdef rec +bar: a = global: $(global) pattern: $(pattern) inherit: $(inherit) +else +bar: a := global: $(global) pattern: $(pattern) inherit: $(inherit) +endif + +bar: ; @echo \'normal: $a;\' + + +# pattern target +# +ifdef rec +%z: a = global: $(global) pattern: $(pattern) inherit: $(inherit) +else +%z: a := global: $(global) pattern: $(pattern) inherit: $(inherit) +endif + +%z: ; @echo \'pattrn: $a;\' + + +global := new $$t +', +'', +'normal: global: orginal $t pattern: inherit: ; +pattrn: global: orginal $t pattern: inherit: ;'); + + +# TEST #7 -- test expansion of pattern-specific recursive variables +# +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;'); + +# TEST #8: override in pattern-specific variables + +run_make_test(' +a%: override FOO += f1 +a%: FOO += f2 +ab: ; @echo "$(FOO)" +', + '', "f1\n"); + +run_make_test(undef, 'FOO=C', "C f1\n"); + +# TEST #9: Test shortest stem selection in pattern-specific variables. + +run_make_test(' +%-mt.x: x := two +%.x: x := one + +all: foo.x foo-mt.x + +foo.x: ;@echo $x +foo-mt.x: ;@echo $x +', +'', +"one\ntwo"); + +1; diff --git a/tests/scripts/features/patternrules b/tests/scripts/features/patternrules new file mode 100644 index 0000000..eebe7c0 --- /dev/null +++ b/tests/scripts/features/patternrules @@ -0,0 +1,224 @@ +# -*-perl-*- + +$description = "Test pattern rules."; + +$details = ""; + +use Cwd; + +$dir = cwd; +$dir =~ s,.*/([^/]+)$,../$1,; + + +# TEST #0: Make sure that multiple patterns where the same target +# can be built are searched even if the first one fails +# to match properly. +# + +run_make_test(q! +.PHONY: all + +all: case.1 case.2 case.3 + +# We can't have this, due to "Implicit Rule Search Algorithm" step 5c +#xxx: void + +# 1 - existing file +%.1: void + @exit 1 +%.1: #MAKEFILE# + @exit 0 + +# 2 - phony +%.2: void + @exit 1 +%.2: 2.phony + @exit 0 +.PHONY: 2.phony + +# 3 - implicit-phony +%.3: void + @exit 1 +%.3: 3.implicit-phony + @exit 0 + +3.implicit-phony: +!, '', ''); + +# TEST #1: make sure files that are built via implicit rules are marked +# as targets (Savannah bug #12202). +# +run_make_test(' +TARGETS := foo foo.out + +.PHONY: all foo.in + +all: $(TARGETS) + +%: %.in + @echo $@ + +%.out: % + @echo $@ + +foo.in: ; @: + +', +'', +'foo +foo.out'); + + +# TEST #2: make sure intermediate files that also happened to be +# prerequisites are not removed (Savannah bug #12267). +# +run_make_test(' +$(dir)/foo.o: + +$(dir)/foo.y: + @echo $@ + +%.c: %.y + touch $@ + +%.o: %.c + @echo $@ + +.PHONY: install +install: $(dir)/foo.c + +', +"dir=$dir", +"$dir/foo.y +touch $dir/foo.c +$dir/foo.o"); + +unlink("$dir/foo.c"); + + +# TEST #3: make sure precious flag is set properly for targets +# that are built via implicit rules (Savannah bug #13218). +# +run_make_test(' +.DELETE_ON_ERROR: + +.PRECIOUS: %.bar + +%.bar:; @touch $@ && exit 1 + +$(dir)/foo.bar: + +', +"dir=$dir", +"#MAKE#: *** [$dir/foo.bar] Error 1", +512); + +unlink("$dir/foo.bar"); + + +# TEST #4: make sure targets of a matched implicit pattern rule are +# never considered intermediate (Savannah bug #13022). +# +run_make_test(' +.PHONY: all +all: foo.c foo.o + +%.h %.c: %.in + touch $*.h + touch $*.c + +%.o: %.c %.h + echo $+ >$@ + +%.o: %.c + @echo wrong rule + +foo.in: + touch $@ + +', +'', +'touch foo.in +touch foo.h +touch foo.c +echo foo.c foo.h >foo.o'); + +unlink('foo.in', 'foo.h', 'foo.c', 'foo.o'); + +# TEST #5: make sure both prefix and suffix patterns work with multiple +# target patterns (Savannah bug #26593). +# +run_make_test(' +all: foo.s1 foo.s2 p1.foo p2.foo + +p1.% p2.%: %.orig + @echo $@ +%.s1 %.s2: %.orig + @echo $@ + +.PHONY: foo.orig +', + '', "foo.s1\np1.foo\n"); + +# TEST 6: Make sure that non-target files are still eligible to be created +# as part of implicit rule chaining. Savannah bug #17752. + +run_make_test(q! +BIN = xyz +COPY = $(BIN).cp +SRC = $(BIN).c +allbroken: $(COPY) $(BIN) ; @echo ok +$(SRC): ; @echo 'main(){}' > $@ +%.cp: % ; @cp $< $@ +% : %.c ; @cp $< $@ +clean: ; @rm -rf $(SRC) $(COPY) $(BIN) +!, + '', "ok\n"); + +unlink(qw(xyz xyz.cp xyz.c)); + +# TEST 7: Make sure that all prereqs of all "also_make" targets get created +# before any of the things that depend on any of them. Savannah bug #19108. + +run_make_test(q! +final: x ; @echo $@ +x: x.t1 x.t2 ; @echo $@ +x.t2: dep +dep: ; @echo $@ +%.t1 %.t2: ; @echo $*.t1 ; echo $*.t2 +!, + '', "dep\nx.t1\nx.t2\nx\nfinal\n"); + + +# TEST 8: Verify we can remove pattern rules. Savannah bug #18622. + +my @f = (qw(foo.w foo.ch)); +touch(@f); + +run_make_test(q! +CWEAVE := : + +# Disable builtin rules +%.tex : %.w +%.tex : %.w %.ch +!, + 'foo.tex', + "#MAKE#: *** No rule to make target `foo.tex'. Stop.", 512); + +unlink(@f); + +# TEST #9: Test shortest stem selection in pattern rules. + +run_make_test(' +%.x: ;@echo one +%-mt.x: ;@echo two + +all: foo.x foo-mt.x +', +'', +"one\ntwo"); + +1; + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/quoting b/tests/scripts/features/quoting new file mode 100644 index 0000000..916681c --- /dev/null +++ b/tests/scripts/features/quoting @@ -0,0 +1,32 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test using \n" . + "quotes within makefiles."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOM'; +SHELL = /bin/sh +TEXFONTS = NICEFONT +DEFINES = -DDEFAULT_TFM_PATH=\".:$(TEXFONTS)\" +test: ; @"echo" 'DEFINES = $(DEFINES)' +EOM + +# 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 = 'DEFINES = -DDEFAULT_TFM_PATH=\".:NICEFONT\"' . "\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/features/recursion b/tests/scripts/features/recursion new file mode 100644 index 0000000..a6b8f90 --- /dev/null +++ b/tests/scripts/features/recursion @@ -0,0 +1,55 @@ +# -*-perl-*- +$description = "Test recursion."; + +$details = "DETAILS"; + +# Test some basic recursion. +run_make_test(' +all: + $(MAKE) -f #MAKEFILE# foo +foo: + @echo $(MAKE) + @echo MAKELEVEL = $(MAKELEVEL) + $(MAKE) -f #MAKEFILE# last +last: + @echo $(MAKE) + @echo MAKELEVEL = $(MAKELEVEL) + @echo THE END +', + ('CFLAGS=-O -w' . ($parallel_jobs ? ' -j 2' : '')), + ($vos + ? "#MAKE#: Entering directory `#PWD#' +make 'CFLAGS=-O' -f #MAKEFILE# foo +make CFLAGS=-O +MAKELEVEL = 0 +make 'CFLAGS=-O' -f #MAKEFILE# last +make CFLAGS=-O +MAKELEVEL = 0 +THE END +#MAKE#: Leaving directory `#PWD#'" + : "#MAKE#: Entering directory `#PWD#' +#MAKEPATH# -f #MAKEFILE# foo +#MAKE#[1]: Entering directory `#PWD#' +#MAKEPATH# +MAKELEVEL = 1 +#MAKEPATH# -f #MAKEFILE# last +#MAKE#[2]: Entering directory `#PWD#' +#MAKEPATH# +MAKELEVEL = 2 +THE END +#MAKE#[2]: Leaving directory `#PWD#' +#MAKE#[1]: Leaving directory `#PWD#' +#MAKE#: Leaving directory `#PWD#'")); + + +# Test command line overrides. +run_make_test(' +recur: all ; @$(MAKE) --no-print-directory -f #MAKEFILE# a=AA all +all: ; @echo "MAKEOVERRIDES = $(MAKEOVERRIDES)" +', + 'a=ZZ', + 'MAKEOVERRIDES = a=ZZ +MAKEOVERRIDES = a=AA +'); + +1; diff --git a/tests/scripts/features/reinvoke b/tests/scripts/features/reinvoke new file mode 100644 index 0000000..9952ced --- /dev/null +++ b/tests/scripts/features/reinvoke @@ -0,0 +1,65 @@ +# -*-mode: perl-*- + +$description = "Test GNU make's auto-reinvocation feature."; + +$details = "\ +If the makefile or one it includes can be rebuilt then it is, and make +is reinvoked. We create a rule to rebuild the makefile from a temp +file, then touch the temp file to make it newer than the makefile."; + +$omkfile = $makefile; + +&utouch(-600, 'incl.mk'); +# For some reason if we don't do this then the test fails for systems +# with sub-second timestamps, maybe + NFS? Not sure. +&utouch(-1, 'incl-1.mk'); + +run_make_test(' +all: ; @echo running rules. + +#MAKEFILE# incl.mk: incl-1.mk + @echo rebuilding $@ + @echo >> $@ + +include incl.mk', + '', "rebuilding incl.mk\nrunning rules.\n"); + +# Make sure updating the makefile itself also works + +&utouch(-600, $omkfile); + +run_make_test(undef, '', "rebuilding #MAKEFILE#\nrunning rules.\n"); + +&rmfiles('incl.mk', 'incl-1.mk'); + + +# In this test we create an included file that's out-of-date, but then +# the rule doesn't update it. Make shouldn't re-exec. + +&utouch(-600, 'b','a'); +#&utouch(-10, 'a'); +&touch('c'); + +run_make_test(' +SHELL = /bin/sh + +all: ; @echo hello + +a : b ; echo >> $@ + +b : c ; [ -f $@ ] || echo >> $@ + +c: ; echo >> $@ + +include $(F)', + 'F=a', "[ -f b ] || echo >> b\nhello\n"); + +# 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") + +&rmfiles('a','b','c'); + +# 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 new file mode 100644 index 0000000..79e0a36 --- /dev/null +++ b/tests/scripts/features/se_explicit @@ -0,0 +1,156 @@ +# -*-perl-*- +$description = "Test second expansion in ordinary rules."; + +$details = ""; + +# TEST #0: Test handing of '$' in prerequisites with and without second +# expansion. + +run_make_test(q! +ifdef SE + .SECONDEXPANSION: +endif +foo$$bar: bar$$baz bar$$biz ; @echo '$@ : $^' +PRE = one two +bar$$baz: $$(PRE) +baraz: $$(PRE) +PRE = three four +.DEFAULT: ; @echo '$@' +!, + '', + "\$\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz"); + +run_make_test(undef, 'SE=1', "three\nfour\nbariz\nfoo\$bar : baraz bariz"); + +# TEST #1: automatic variables. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +foo: bar baz + +foo: biz | buz + +foo: $$@.1 \ + $$<.2 \ + $$(addsuffix .3,$$^) \ + $$(addsuffix .4,$$+) \ + $$|.5 \ + $$*.6 + +!, +'', +'bar +baz +biz +buz +foo.1 +bar.2 +bar.3 +baz.3 +biz.3 +bar.4 +baz.4 +biz.4 +buz.5 +.6 +'); + + +# Test #2: target/pattern -specific variables. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +foo.x: $$a $$b + +foo.x: a := bar + +%.x: b := baz +!, +'', +'bar +baz +'); + + +# Test #3: order of prerequisites. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +all: foo bar baz + +# Subtest #1 +foo: foo.1; @: +foo: foo.2 +foo: foo.3 + +# Subtest #2 +bar: bar.2 +bar: bar.1; @: +bar: bar.3 + +# Subtest #3 +baz: baz.1 +baz: baz.2 +baz: ; @: +!, +'', +'foo.1 +foo.2 +foo.3 +bar.1 +bar.2 +bar.3 +baz.1 +baz.2 +'); + +# TEST #4: eval in a context where there is no reading_file +run_make_test(q! +.SECONDEXPANSION: +all : $$(eval $$(info test)) +!, + '', "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. + +run_make_test(q! +.SECONDEXPANSION: +proj1.exe : proj1.o $$(eval $$(test)) +define test +proj1.o : proj1.c +proj1.c: proj1.h +endef +!, + '', "#MAKE#: *** prerequisites cannot be defined in recipes. Stop.\n", 512); + + +# Automatic $$+ variable expansion issue. Savannah bug #25780 +run_make_test(q! +all : foo foo +.SECONDEXPANSION: +all : $$+ ; @echo '$+' +foo : ; +!, + '', "foo foo foo foo\n"); + + +# Automatic $$+ variable expansion issue. Savannah bug #25780 +run_make_test(q! +all : bar bar +bar : ; +q%x : ; +.SECONDEXPANSION: +a%l: q1x $$+ q2x ; @echo '$+' +!, + '', "q1x bar bar q2x bar bar\n"); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/se_implicit b/tests/scripts/features/se_implicit new file mode 100644 index 0000000..e9acb2f --- /dev/null +++ b/tests/scripts/features/se_implicit @@ -0,0 +1,226 @@ +# -*-perl-*- +$description = "Test second expansion in ordinary rules."; + +$details = ""; + +use Cwd; + +$dir = cwd; +$dir =~ s,.*/([^/]+)$,../$1,; + + +# Test #1: automatic variables. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +foo.a: bar baz + +foo.a: biz | buz + +foo.%: 1.$$@ \ + 2.$$< \ + $$(addprefix 3.,$$^) \ + $$(addprefix 4.,$$+) \ + 5.$$| \ + 6.$$* + @: + +1.foo.a \ +2.bar \ +3.bar \ +3.baz \ +3.biz \ +4.bar \ +4.baz \ +4.biz \ +5.buz \ +6.a: + @echo '$@' + +!, +'', +'1.foo.a +2.bar +3.bar +3.baz +3.biz +4.bar +4.baz +4.biz +5.buz +6.a +bar +baz +biz +buz +'); + + +# Test #2: target/pattern -specific variables. +# +run_make_test(q! +.SECONDEXPANSION: +foo.x: + +foo.%: $$(%_a) $$(%_b) bar + @: + +foo.x: x_a := bar + +%.x: x_b := baz + +bar baz: ; @echo '$@' +!, + '', "bar\nbaz\n"); + + +# Test #3: order of prerequisites. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +all: foo bar baz + + +# Subtest #1 +# +%oo: %oo.1; @: + +foo: foo.2 + +foo: foo.3 + +foo.1: ; @echo '$@' + + +# Subtest #2 +# +bar: bar.2 + +%ar: %ar.1; @: + +bar: bar.3 + +bar.1: ; @echo '$@' + + +# Subtest #3 +# +baz: baz.1 + +baz: baz.2 + +%az: ; @: +!, + '', +'foo.1 +foo.2 +foo.3 +bar.1 +bar.2 +bar.3 +baz.1 +baz.2 +'); + + +# Test #4: stem splitting logic. +# +run_make_test(q! +.SECONDEXPANSION: +$(dir)/tmp/bar.o: + +$(dir)/tmp/foo/bar.c: ; @echo '$@' +$(dir)/tmp/bar/bar.c: ; @echo '$@' +foo.h: ; @echo '$@' + +%.o: $$(addsuffix /%.c,foo bar) foo.h + @echo '$@: {$<} $^' +!, + "dir=$dir", "$dir/tmp/foo/bar.c +$dir/tmp/bar/bar.c +foo.h +$dir/tmp/bar.o: {$dir/tmp/foo/bar.c} $dir/tmp/foo/bar.c $dir/tmp/bar/bar.c foo.h +"); + + +# Test #5: stem splitting logic and order-only prerequisites. +# +run_make_test(q! +.SECONDEXPANSION: +$(dir)/tmp/foo.o: $(dir)/tmp/foo.c +$(dir)/tmp/foo.c: ; @echo '$@' +bar.h: ; @echo '$@' + +%.o: %.c|bar.h + @echo '$@: {$<} {$|} $^' + +!, + "dir=$dir", "$dir/tmp/foo.c +bar.h +$dir/tmp/foo.o: {$dir/tmp/foo.c} {bar.h} $dir/tmp/foo.c +"); + + +# Test #6: lack of implicit prerequisites. +# +run_make_test(q! +.SECONDEXPANSION: +foo.o: foo.c +foo.c: ; @echo '$@' + +%.o: + @echo '$@: {$<} $^' +!, + '', "foo.c\nfoo.o: {foo.c} foo.c\n"); + + +# Test #7: Test stem from the middle of the name. +# +run_make_test(q! +.SECONDEXPANSION: +foobarbaz: + +foo%baz: % $$*.1 + @echo '$*' + +bar bar.1: + @echo '$@' +!, + '', "bar\nbar.1\nbar\n"); + + +# Test #8: Make sure stem triple-expansion does not happen. +# +run_make_test(q! +.SECONDEXPANSION: +foo$$bar: + +f%r: % $$*.1 + @echo '$*' + +oo$$ba oo$$ba.1: + @echo '$@' +!, + '', 'oo$ba +oo$ba.1 +oo$ba +'); + +# Test #9: Check the value of $^ +run_make_test(q! +.SECONDEXPANSION: + +%.so: | $$(extra) ; @echo $^ + +foo.so: extra := foo.o +foo.so: +foo.o: +!, + '', "\n"); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/se_statpat b/tests/scripts/features/se_statpat new file mode 100644 index 0000000..b1e59e1 --- /dev/null +++ b/tests/scripts/features/se_statpat @@ -0,0 +1,107 @@ +# -*-perl-*- +$description = "Test second expansion in static pattern rules."; + +$details = ""; + +# Test #1: automatic variables. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +foo.a foo.b: foo.%: bar.% baz.% +foo.a foo.b: foo.%: biz.% | buz.% + +foo.a foo.b: foo.%: $$@.1 \ + $$<.2 \ + $$(addsuffix .3,$$^) \ + $$(addsuffix .4,$$+) \ + $$|.5 \ + $$*.6 +!, + '', 'bar.a +baz.a +biz.a +buz.a +foo.a.1 +bar.a.2 +bar.a.3 +baz.a.3 +biz.a.3 +bar.a.4 +baz.a.4 +biz.a.4 +buz.a.5 +a.6 +'); + + +# Test #2: target/pattern -specific variables. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +foo.x foo.y: foo.%: $$(%_a) $$($$*_b) + +foo.x: x_a := bar + +%.x: x_b := baz +!, + '', "bar\nbaz\n"); + + +# Test #3: order of prerequisites. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +all: foo.a bar.a baz.a + +# Subtest #1 +foo.a foo.b: foo.%: foo.%.1; @: +foo.a foo.b: foo.%: foo.%.2 +foo.a foo.b: foo.%: foo.%.3 + + +# Subtest #2 +bar.a bar.b: bar.%: bar.%.2 +bar.a bar.b: bar.%: bar.%.1; @: +bar.a bar.b: bar.%: bar.%.3 + + +# Subtest #3 +baz.a baz.b: baz.%: baz.%.1 +baz.a baz.b: baz.%: baz.%.2 +baz.a baz.b: ; @: +!, + '', 'foo.a.1 +foo.a.2 +foo.a.3 +bar.a.1 +bar.a.2 +bar.a.3 +baz.a.1 +baz.a.2 +'); + + +# Test #4: Make sure stem triple-expansion does not happen. +# +run_make_test(q! +.SECONDEXPANSION: +foo$$bar: f%r: % $$*.1 + @echo '$*' + +oo$$ba oo$$ba.1: + @echo '$@' +!, + '', 'oo$ba +oo$ba.1 +oo$ba +'); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/statipattrules b/tests/scripts/features/statipattrules new file mode 100644 index 0000000..3f363de --- /dev/null +++ b/tests/scripts/features/statipattrules @@ -0,0 +1,111 @@ +# -*-perl-*- +$description = "Test handling of static pattern rules."; + +$details = "\ +The makefile created in this test has three targets. The +filter command is used to get those target names ending in +.o and statically creates a compile command with the target +name and the target name with .c. It also does the same thing +for another target filtered with .elc and creates a command +to emacs a .el file"; + +&touch('bar.c', 'lose.c'); + +# TEST #0 +# ------- + +run_make_test(' +files = foo.elc bar.o lose.o + +$(filter %.o,$(files)): %.o: %.c ; @echo CC -c $(CFLAGS) $< -o $@ + +$(filter %.elc,$(files)): %.elc: %.el ; @echo emacs $< +', + '', + 'CC -c bar.c -o bar.o'); + +# TEST #1 +# ------- + +run_make_test(undef, 'lose.o', 'CC -c lose.c -o lose.o'); + + +# TEST #2 +# ------- +&touch("foo.el"); + +run_make_test(undef, 'foo.elc', 'emacs foo.el'); + +# Clean up after the first tests. +unlink('foo.el', 'bar.c', 'lose.c'); + + +# TEST #3 -- PR/1670: don't core dump on invalid static pattern rules +# ------- + +run_make_test(' +.DEFAULT: ; @echo $@ +foo: foo%: % %.x % % % y.% % ; @echo $@ +', + '', ".x\ny.\nfoo"); + + +# TEST #4 -- bug #12180: core dump on a stat pattern rule with an empty +# prerequisite list. +run_make_test(' +foo.x bar.x: %.x : ; @echo $@ + +', + '', 'foo.x'); + + +# TEST #5 -- bug #13881: double colon static pattern rule does not +# substitute %. +run_make_test(' +foo.bar:: %.bar: %.baz +foo.baz: ;@: +', + '', ''); + + +# TEST #6: make sure the second stem does not overwrite the first +# perprerequisite's stem (Savannah bug #16053). +# +run_make_test(' +all.foo.bar: %.foo.bar: %.one + +all.foo.bar: %.bar: %.two + +all.foo.bar: + @echo $* + @echo $^ + +.DEFAULT:;@: +', +'', +'all.foo +all.one all.foo.two'); + + +# TEST #7: make sure the second stem does not overwrite the first +# perprerequisite's stem when second expansion is enabled +# (Savannah bug #16053). +# +run_make_test(' +.SECONDEXPANSION: + +all.foo.bar: %.foo.bar: %.one $$*-one + +all.foo.bar: %.bar: %.two $$*-two + +all.foo.bar: + @echo $* + @echo $^ + +.DEFAULT:;@: +', +'', +'all.foo +all.one all-one all.foo.two all.foo-two'); + +1; diff --git a/tests/scripts/features/targetvars b/tests/scripts/features/targetvars new file mode 100644 index 0000000..ddd6c1f --- /dev/null +++ b/tests/scripts/features/targetvars @@ -0,0 +1,263 @@ +# -*-perl-*- +$description = "Test target-specific variable settings."; + +$details = "\ +Create a makefile containing various flavors of target-specific variable +values, override and non-override, and using various variable expansion +rules, semicolon interference, etc."; + +run_make_test(' +SHELL = /bin/sh +export FOO = foo +export BAR = bar +one: override FOO = one +one two: ; @echo $(FOO) $(BAR) +two: BAR = two +three: ; BAR=1000 + @echo $(FOO) $(BAR) +# Some things that shouldn not be target vars +funk : override +funk : override adelic +adelic override : ; echo $@ +# Test per-target recursive variables +four:FOO=x +four:VAR$(FOO)=ok +four: ; @echo "$(FOO) $(VAR$(FOO)) $(VAR) $(VARx)" +five:FOO=x +five six : VAR$(FOO)=good +five six: ;@echo "$(FOO) $(VAR$(FOO)) $(VAR) $(VARx) $(VARfoo)" +# Test per-target variable inheritance +seven: eight +seven eight: ; @echo $@: $(FOO) $(BAR) +seven: BAR = seven +seven: FOO = seven +eight: BAR = eight +# Test the export keyword with per-target variables +nine: ; @echo $(FOO) $(BAR) $$FOO $$BAR +nine: FOO = wallace +nine-a: export BAZ = baz +nine-a: ; @echo $$BAZ +# Test = escaping +EQ = = +ten: one$(EQ)two +ten: one $(EQ) two +ten one$(EQ)two $(EQ):;@echo $@ +.PHONY: one two three four five six seven eight nine ten $(EQ) one$(EQ)two +# Test target-specific vars with pattern/suffix rules +QVAR = qvar +RVAR = = +%.q : ; @echo $(QVAR) $(RVAR) +foo.q : RVAR += rvar +# Target-specific vars with multiple LHS pattern rules +%.r %.s %.t: ; @echo $(QVAR) $(RVAR) $(SVAR) $(TVAR) +foo.r : RVAR += rvar +foo.t : TVAR := $(QVAR) +', + "one two three", "one bar\nfoo two\nBAR=1000\nfoo bar\n"); + +# TEST #2 + +run_make_test(undef, "one two FOO=1 BAR=2", "one 2\n1 2\n"); + +# TEST #3 + +run_make_test(undef, "four", "x ok ok\n"); + +# TEST #4 + +run_make_test(undef, "seven", "eight: seven eight\nseven: seven seven\n"); + +# TEST #5 + +run_make_test(undef, "nine", "wallace bar wallace bar\n"); + +# TEST #5-a + +run_make_test(undef, "nine-a", "baz\n"); + +# TEST #6 + +run_make_test(undef, "ten", "one=two\none bar\n=\nfoo two\nten\n"); + +# TEST #6 + +run_make_test(undef, "foo.q bar.q", "qvar = rvar\nqvar =\n"); + +# TEST #7 + +run_make_test(undef, "foo.t bar.s", "qvar = qvar\nqvar =\n"); + + +# TEST #8 +# For PR/1378: Target-specific vars don't inherit correctly + +run_make_test(' +foo: FOO = foo +bar: BAR = bar +foo: bar +bar: baz +baz: ; @echo $(FOO) $(BAR) +', "", "foo bar\n"); + +# TEST #9 +# For PR/1380: Using += assignment in target-specific variables sometimes fails +# Also PR/1831 + +run_make_test(' +.PHONY: all one +all: FOO += baz +all: one; @echo $(FOO) + +FOO = bar + +one: FOO += biz +one: FOO += boz +one: ; @echo $(FOO) +', + '', "bar baz biz boz\nbar baz\n"); + +# Test #10 + +run_make_test(undef, 'one', "bar biz boz\n"); + +# Test #11 +# PR/1709: Test semicolons in target-specific variable values + +run_make_test(' +foo : FOO = ; ok +foo : ; @echo "$(FOO)" +', + '', "; ok\n"); + +# Test #12 +# PR/2020: More hassles with += target-specific vars. I _really_ think +# I nailed it this time :-/. + +run_make_test(' +.PHONY: a + +BLAH := foo +COMMAND = echo $(BLAH) + +a: ; @$(COMMAND) + +a: BLAH := bar +a: COMMAND += snafu $(BLAH) +', + '', "bar snafu bar\n"); + +# Test #13 +# Test double-colon rules with target-specific variable values + +run_make_test(' +W = bad +X = bad +foo: W = ok +foo:: ; @echo $(W) $(X) $(Y) $(Z) +foo:: ; @echo $(W) $(X) $(Y) $(Z) +foo: X = ok + +Y = foo +bar: foo +bar: Y = bar + +Z = nopat +ifdef PATTERN + fo% : Z = pat +endif +', + 'foo', "ok ok foo nopat\nok ok foo nopat\n"); + +# Test #14 +# Test double-colon rules with target-specific variable values and +# inheritance + +run_make_test(undef, 'bar', "ok ok bar nopat\nok ok bar nopat\n"); + +# Test #15 +# Test double-colon rules with pattern-specific variable values + +run_make_test(undef, 'foo PATTERN=yes', "ok ok foo pat\nok ok foo pat\n"); + +# Test #16 +# Test target-specific variables with very long command line +# (> make default buffer length) + +run_make_test(' +base_metals_fmd_reports.sun5 base_metals_fmd_reports CreateRealPositions CreateMarginFunds deals_changed_since : BUILD_OBJ=$(shell if [ -f "build_information.generate" ]; then echo "$(OBJ_DIR)/build_information.o"; else echo "no build information"; fi ) + +deals_changed_since: ; @echo $(BUILD_OBJ) +', + '', "no build information\n"); + +# TEST #17 + +# Test a merge of set_lists for files, where one list is much longer +# than the other. See Savannah bug #15757. + +mkdir('t1', 0777); +touch('t1/rules.mk'); + +run_make_test(' +VPATH = t1 +include rules.mk +.PHONY: all +all: foo.x +foo.x : rules.mk ; @echo MYVAR=$(MYVAR) FOOVAR=$(FOOVAR) ALLVAR=$(ALLVAR) +all: ALLVAR = xxx +foo.x: FOOVAR = bar +rules.mk : MYVAR = foo +.INTERMEDIATE: foo.x rules.mk +', + '-I t1', 'MYVAR= FOOVAR=bar ALLVAR=xxx'); + +rmfiles('t1/rules.mk'); +rmdir('t1'); + +# TEST #18 + +# Test appending to a simple variable containing a "$": avoid a +# double-expansion. See Savannah bug #15913. + +run_make_test(' +VAR := $$FOO +foo: VAR += BAR +foo: ; @echo '."'".'$(VAR)'."'".' +', + '', '$FOO BAR'); + +# TEST #19: Override with append variables + +run_make_test(' +a: override FOO += f1 +a: FOO += f2 +a: ; @echo "$(FOO)" +', + '', "f1\n"); + +run_make_test(undef, 'FOO=C', "C f1\n"); + +# TEST #20: Check for continuation after semicolons + +run_make_test(q! +a: A = 'hello; \ +world' +a: ; @echo $(A) +!, + '', "hello; world\n"); + +# TEST #19: Test define/endef variables as target-specific vars + +# run_make_test(' +# define b +# @echo global +# endef +# a: define b +# @echo local +# endef + +# a: ; $(b) +# ', +# '', "local\n"); + +1; diff --git a/tests/scripts/features/varnesting b/tests/scripts/features/varnesting new file mode 100644 index 0000000..15d5071 --- /dev/null +++ b/tests/scripts/features/varnesting @@ -0,0 +1,34 @@ +$description = "The following test creates a makefile to ..."; + +$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)); + +1; + + + + + + diff --git a/tests/scripts/features/vpath b/tests/scripts/features/vpath new file mode 100644 index 0000000..a3aebd9 --- /dev/null +++ b/tests/scripts/features/vpath @@ -0,0 +1,81 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test the \n" + ."vpath directive which allows you to specify a search \n" + ."path for a particular class of filenames, those that\n" + ."match a particular pattern."; + +$details = "This tests the vpath directive by specifying search directories\n" + ."for one class of filenames with the form: vpath pattern directories" + ."\nIn this test, we specify the working directory for all files\n" + ."that end in c or h. We also test the variables $@ (which gives\n" + ."target name) and $^ (which is a list of all dependencies \n" + ."including the directories in which they were found). It also\n" + ."uses the function firstword used to extract just the first\n" + ."dependency from the entire list."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "vpath %.c foo\n"; +print MAKEFILE "vpath %.c $workdir\n"; +print MAKEFILE "vpath %.h $workdir\n"; +print MAKEFILE "objects = main.o kbd.o commands.o display.o insert.o\n"; +print MAKEFILE "edit: \$(objects)\n"; +print MAKEFILE "\t\@echo cc -o \$@ \$^\n"; +print MAKEFILE "main.o : main.c defs.h\n"; +print MAKEFILE "\t\@echo cc -c \$(firstword \$^)\n"; +print MAKEFILE "kbd.o : kbd.c defs.h command.h\n"; +print MAKEFILE "\t\@echo cc -c kbd.c\n"; +print MAKEFILE "commands.o : command.c defs.h command.h\n"; +print MAKEFILE "\t\@echo cc -c commands.c\n"; +print MAKEFILE "display.o : display.c defs.h buffer.h\n"; +print MAKEFILE "\t\@echo cc -c display.c\n"; +print MAKEFILE "insert.o : insert.c defs.h buffer.h\n"; +print MAKEFILE "\t\@echo cc -c insert.c\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c $workdir${pathsep}main.c\ncc -c kbd.c\ncc -c commands.c\n" + ."cc -c display.c\n" + ."cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o " + ."insert.o\n"; + +if (&compare_output($answer,&get_logfile(1))) +{ + unlink @files_to_touch; +} + +# TEST 2: after vpath lookup ensure we don't get incorrect circular dependency +# warnings due to change of struct file ptr. Savannah bug #13529. + +mkdir('vpath-d', 0777); + +run_make_test(q! +vpath %.te vpath-d/ +.SECONDARY: +default: vpath-d/a vpath-d/b +vpath-d/a: fail.te +vpath-d/b : fail.te +vpath-d/fail.te: +!, + '', "#MAKE#: Nothing to be done for `default'.\n"); + +rmdir('vpath-d'); + +1; diff --git a/tests/scripts/features/vpath2 b/tests/scripts/features/vpath2 new file mode 100644 index 0000000..7e970a7 --- /dev/null +++ b/tests/scripts/features/vpath2 @@ -0,0 +1,45 @@ +$description = "This is part 2 in a series to test the vpath directive\n" + ."It tests the three forms of the directive:\n" + ." vpath pattern directive\n" + ." vpath pattern (clears path associated with pattern)\n" + ." vpath (clears all paths specified with vpath)\n"; + +$details = "This test simply adds many search paths using various vpath\n" + ."directive forms and clears them afterwards. It has a simple\n" + ."rule to print a message at the end to confirm that the makefile\n" + ."ran with no errors.\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $workdir:$sourcedir\n"; +print MAKEFILE "vpath %.c foo\n"; +print MAKEFILE "vpath %.c $workdir\n"; +print MAKEFILE "vpath %.c $sourcedir\n"; +print MAKEFILE "vpath %.h $workdir\n"; +print MAKEFILE "vpath %.c\n"; +print MAKEFILE "vpath\n"; +print MAKEFILE "all:\n"; +print MAKEFILE "\t\@echo ALL IS WELL\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 = "ALL IS WELL\n"; + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/tests/scripts/features/vpath3 b/tests/scripts/features/vpath3 new file mode 100644 index 0000000..978c5ee --- /dev/null +++ b/tests/scripts/features/vpath3 @@ -0,0 +1,50 @@ +# -*-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"); + +&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"); +} + +1; diff --git a/tests/scripts/features/vpathgpath b/tests/scripts/features/vpathgpath new file mode 100644 index 0000000..f7683f5 --- /dev/null +++ b/tests/scripts/features/vpathgpath @@ -0,0 +1,66 @@ +# -*-perl-*- +$description = "Tests VPATH+/GPATH functionality."; + +$details = ""; + +$VP = "$workdir$pathsep"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $VP\n"; + +print MAKEFILE <<'EOMAKE'; + +GPATH = $(VPATH) + +.SUFFIXES: .a .b .c .d +.PHONY: general rename notarget intermediate + +%.a: +%.b: +%.c: +%.d: + +%.a : %.b ; cat $^ > $@ +%.b : %.c ; cat $^ > $@ +%.c :: %.d ; cat $^ > $@ + +# General testing info: + +general: foo.b +foo.b: foo.c bar.c + +EOMAKE + +close(MAKEFILE); + +@touchedfiles = (); + +$off = -500; + +sub touchfiles { + foreach (@_) { + ($f = $_) =~ s,VP/,$VP,g; + &utouch($off, $f); + $off += 10; + push(@touchedfiles, $f); + } +} + +# Run the general-case test + +&touchfiles("VP/foo.d", "VP/bar.d", "VP/foo.c", "VP/bar.c", "foo.b", "bar.d"); + +&run_make_with_options($makefile,"general",&get_logfile()); + +push(@touchedfiles, "bar.c"); + +$answer = "$make_name: Nothing to be done for `general'.\n"; + +&compare_output($answer,&get_logfile(1)); + +unlink(@touchedfiles) unless $keep; + +1; diff --git a/tests/scripts/features/vpathplus b/tests/scripts/features/vpathplus new file mode 100644 index 0000000..a37fbed --- /dev/null +++ b/tests/scripts/features/vpathplus @@ -0,0 +1,128 @@ +# -*-perl-*- +$description = "Tests the new VPATH+ functionality added in 3.76."; + +$details = ""; + +$VP = "$workdir$pathsep"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $VP\n"; + +print MAKEFILE <<'EOMAKE'; + +SHELL = /bin/sh + +.SUFFIXES: .a .b .c .d +.PHONY: general rename notarget intermediate + +%.a: +%.b: +%.c: +%.d: + +%.a : %.b + cat $^ > $@ +%.b : %.c + cat $^ > $@ 2>/dev/null || exit 1 +%.c :: %.d + cat $^ > $@ + +# General testing info: + +general: foo.b +foo.b: foo.c bar.c + +# Rename testing info: + +rename: $(VPATH)/foo.c foo.d + +# Target not made testing info: + +notarget: notarget.b +notarget.c: notarget.d + -@echo "not creating $@ from $^" + +# Intermediate files: + +intermediate: inter.a + +EOMAKE + +close(MAKEFILE); + +@touchedfiles = (); + +$off = -500; + +sub touchfiles { + foreach (@_) { + &utouch($off, $_); + $off += 10; + push(@touchedfiles, $_); + } +} + +# Run the general-case test + +&touchfiles("$VP/foo.d", "$VP/bar.d", "$VP/foo.c", "$VP/bar.c", "foo.b", "bar.d"); + +&run_make_with_options($makefile,"general",&get_logfile); + +push(@touchedfiles, "bar.c"); + +$answer = "cat bar.d > bar.c +cat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1 +"; +&compare_output($answer,&get_logfile(1)); + +# Test rules that don't make the target correctly + +&touchfiles("$VP/notarget.c", "notarget.b", "notarget.d"); + +&run_make_with_options($makefile,"notarget",&get_logfile,512); + +$answer = "not creating notarget.c from notarget.d +cat notarget.c > notarget.b 2>/dev/null || exit 1 +$make_name: *** [notarget.b] Error 1 +"; + +&compare_output($answer,&get_logfile(1)); + +# Test intermediate file handling (part 1) + +&touchfiles("$VP/inter.d"); + +&run_make_with_options($makefile,"intermediate",&get_logfile); + +push(@touchedfiles, "inter.a", "inter.b"); + +$answer = "cat ${VP}inter.d > inter.c +cat inter.c > inter.b 2>/dev/null || exit 1 +cat inter.b > inter.a +rm inter.b inter.c +"; +&compare_output($answer,&get_logfile(1)); + +# Test intermediate file handling (part 2) + +&utouch(-20, "inter.a"); +&utouch(-10, "$VP/inter.b"); +&touch("$VP/inter.d"); + +push(@touchedfiles, "$VP/inter.b", "$VP/inter.d"); + +&run_make_with_options($makefile,"intermediate",&get_logfile); + +$answer = "cat ${VP}inter.d > inter.c +cat inter.c > inter.b 2>/dev/null || exit 1 +cat inter.b > inter.a +rm inter.c +"; +&compare_output($answer,&get_logfile(1)); + +unlink @touchedfiles unless $keep; + +1; diff --git a/tests/scripts/functions/abspath b/tests/scripts/functions/abspath new file mode 100644 index 0000000..84c30ab --- /dev/null +++ b/tests/scripts/functions/abspath @@ -0,0 +1,81 @@ +# -*-perl-*- +$description = "Test the abspath functions."; + +$details = ""; + +run_make_test(' +ifneq ($(realpath $(abspath .)),$(CURDIR)) + $(warning .: abs="$(abspath .)" real="$(realpath $(abspath .))" curdir="$(CURDIR)") +endif + +ifneq ($(realpath $(abspath ./)),$(CURDIR)) + $(warning ./: abs="$(abspath ./)" real="$(realpath $(abspath ./))" curdir="$(CURDIR)") +endif + +ifneq ($(realpath $(abspath .///)),$(CURDIR)) + $(warning .///: abs="$(abspath .///)" real="$(realpath $(abspath .///))" curdir="$(CURDIR)") +endif + +ifneq ($(abspath /),/) + $(warning /: abspath="$(abspath /)") +endif + +ifneq ($(abspath ///),/) + $(warning ///: abspath="$(abspath ///)") +endif + +ifneq ($(abspath /.),/) + $(warning /.: abspath="$(abspath /.)") +endif + +ifneq ($(abspath ///.),/) + $(warning ///.: abspath="$(abspath ///.)") +endif + +ifneq ($(abspath /./),/) + $(warning /./: abspath="$(abspath /./)") +endif + +ifneq ($(abspath /.///),/) + $(warning /.///: abspath="$(abspath /.///)") +endif + +ifneq ($(abspath /..),/) + $(warning /..: abspath="$(abspath /..)") +endif + +ifneq ($(abspath ///..),/) + $(warning ///..: abspath="$(abspath ///..)") +endif + +ifneq ($(abspath /../),/) + $(warning /../: abspath="$(abspath /../)") +endif + +ifneq ($(abspath /..///),/) + $(warning /..///: abspath="$(abspath /..///)") +endif + + +ifneq ($(abspath /foo/bar/..),/foo) + $(warning /foo/bar/..: abspath="$(abspath /foo/bar/..)") +endif + +ifneq ($(abspath /foo/bar/../../../baz),/baz) + $(warning /foo/bar/../../../baz: abspath="$(abspath /foo/bar/../../../baz)") +endif + +ifneq ($(abspath /foo/bar/../ /..),/foo /) + $(warning /foo/bar/../ /..: abspath="$(abspath /foo/bar/../ /..)") +endif + + +.PHONY: all +all: ; @: +', +'', +''); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/functions/addprefix b/tests/scripts/functions/addprefix new file mode 100644 index 0000000..1845552 --- /dev/null +++ b/tests/scripts/functions/addprefix @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the addprefix " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(addprefix src${pathsep},a.b.z.foo hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "src${pathsep}a.b.z.foo src${pathsep}hacks\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/addsuffix b/tests/scripts/functions/addsuffix new file mode 100644 index 0000000..da4fbb7 --- /dev/null +++ b/tests/scripts/functions/addsuffix @@ -0,0 +1,36 @@ +# -*-perl-*- +$description = "Test the addsuffix function."; + +$details = ""; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOMAKE; +string := \$(addsuffix .c,src${pathsep}a.b.z.foo hacks) +one: ; \@echo \$(string) + +two: ; \@echo \$(addsuffix foo,) +EOMAKE + +close(MAKEFILE); + + +# TEST 0 + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "src${pathsep}a.b.z.foo.c hacks.c\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST 1 + +&run_make_with_options($makefile, "two", &get_logfile); +$answer = "\n"; +&compare_output($answer,&get_logfile(1)); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/functions/andor b/tests/scripts/functions/andor new file mode 100644 index 0000000..62e0c2e --- /dev/null +++ b/tests/scripts/functions/andor @@ -0,0 +1,50 @@ +# -*-perl-*- +$description = "Test the and & or functions.\n"; + +$details = "Try various uses of and & or to ensure they all give the correct +results.\n"; + +# TEST #0 +# For $(and ...), it will either be empty or the last value +run_make_test(' +NEQ = $(subst $1,,$2) +f = +t = true + +all: + @echo 1 $(and ,$t) + @echo 2 $(and $t) + @echo 3 $(and $t,) + @echo 4 $(and z,true,$f,false) + @echo 5 $(and $t,$f,$(info bad short-circuit)) + @echo 6 $(and $(call NEQ,a,b),true) + @echo 7 $(and $(call NEQ,a,a),true) + @echo 8 $(and z,true,fal,se) hi + @echo 9 $(and ,true,fal,se)there + @echo 10 $(and $(e) ,$t)', + '', + "1\n2 true\n3\n4\n5\n6 true\n7\n8 se hi\n9 there\n10\n"); + +# TEST #1 +# For $(or ...), it will either be empty or the first true value +run_make_test(' +NEQ = $(subst $1,,$2) +f = +t = true + +all: + @echo 1 $(or , ) + @echo 2 $(or $t) + @echo 3 $(or ,$t) + @echo 4 $(or z,true,$f,false) + @echo 5 $(or $t,$(info bad short-circuit)) + @echo 6 $(or $(info short-circuit),$t) + @echo 7 $(or $(call NEQ,a,b),true) + @echo 8 $(or $(call NEQ,a,a),true) + @echo 9 $(or z,true,fal,se) hi + @echo 10 $(or ,true,fal,se)there + @echo 11 $(or $(e) ,$f)', + '', + "short-circuit\n1\n2 true\n3 true\n4 z\n5 true\n6 true\n7 b\n8 true\n9 z hi\n10 truethere\n11\n"); + +1; diff --git a/tests/scripts/functions/basename b/tests/scripts/functions/basename new file mode 100644 index 0000000..08f2ea5 --- /dev/null +++ b/tests/scripts/functions/basename @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the suffix " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(basename src${pathsep}a.b.z.foo.c src${pathsep}hacks src.bar${pathsep}a.b.z.foo.c src.bar${pathsep}hacks hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "src${pathsep}a.b.z.foo src${pathsep}hacks src.bar${pathsep}a.b.z.foo src.bar${pathsep}hacks hacks\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/call b/tests/scripts/functions/call new file mode 100644 index 0000000..f3c5470 --- /dev/null +++ b/tests/scripts/functions/call @@ -0,0 +1,99 @@ +# -*-perl-*- +$description = "Test the call function.\n"; + +$details = "Try various uses of call and ensure they all give the correct +results.\n"; + +open(MAKEFILE, "> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOMAKE'; +# Simple, just reverse two things +# +reverse = $2 $1 + +# A complex `map' function, using recursive `call'. +# +map = $(foreach a,$2,$(call $1,$a)) + +# Test using a builtin; this is silly as it's simpler to do without call +# +my-notdir = $(call notdir,$(1)) + +# Test using non-expanded builtins +# +my-foreach = $(foreach $(1),$(2),$(3)) +my-if = $(if $(1),$(2),$(3)) + +# Test recursive invocations of call with different arguments +# +one = $(1) $(2) $(3) +two = $(call one,$(1),foo,$(2)) + +# Test recursion on the user-defined function. As a special case make +# won't error due to this. +# Implement transitive closure using $(call ...) +# +DEP_foo = bar baz quux +DEP_baz = quux blarp +rest = $(wordlist 2,$(words ${1}),${1}) +tclose = $(if $1,$(firstword $1) \ + $(call tclose,$(sort ${DEP_$(firstword $1)} $(call rest,$1)))) + +all: ; @echo '$(call reverse,bar,foo)'; \ + echo '$(call map,origin,MAKE reverse map)'; \ + echo '$(call my-notdir,a/b c/d e/f)'; \ + echo '$(call my-foreach)'; \ + echo '$(call my-foreach,a,,,)'; \ + echo '$(call my-if,a,b,c)'; \ + echo '$(call two,bar,baz)'; \ + echo '$(call tclose,foo)' + + + +EOMAKE + +# These won't work until/unless PR/1527 is resolved. +# echo '$(call my-foreach,a,x y z,$(a)$(a))'; \ +# echo '$(call my-if,,$(warning don't print this),ok)' +# +# $answer = "xx yy zz\nok\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "foo bar\ndefault file file\nb d f\n\n\nb\nbar foo baz\nfoo bar baz blarp quux \n"; +&compare_output($answer, &get_logfile(1)); + + +# TEST eclipsing of arguments when invoking sub-calls + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE <<'EOF'; + +all = $1 $2 $3 $4 $5 $6 $7 $8 $9 + +level1 = $(call all,$1,$2,$3,$4,$5) +level2 = $(call level1,$1,$2,$3) +level3 = $(call level2,$1,$2,$3,$4,$5) + +all: + @echo $(call all,1,2,3,4,5,6,7,8,9,10,11) + @echo $(call level1,1,2,3,4,5,6,7,8) + @echo $(call level2,1,2,3,4,5,6,7,8) + @echo $(call level3,1,2,3,4,5,6,7,8) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, "", &get_logfile); +$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)); + +1; diff --git a/tests/scripts/functions/dir b/tests/scripts/functions/dir new file mode 100644 index 0000000..f48fb8c --- /dev/null +++ b/tests/scripts/functions/dir @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the dir " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(dir src${pathsep}foo.c hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "src${pathsep} .${pathsep}\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/error b/tests/scripts/functions/error new file mode 100644 index 0000000..0d61177 --- /dev/null +++ b/tests/scripts/functions/error @@ -0,0 +1,73 @@ +# -*-Perl-*- + +$description = "\ +The following test creates a makefile to test the error function."; + +$details = ""; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE 'err = $(error Error found!) + +ifdef ERROR1 +$(error error is $(ERROR1)) +endif + +ifdef ERROR2 +$(error error is $(ERROR2)) +endif + +ifdef ERROR3 +all: some; @echo $(error error is $(ERROR3)) +endif + +ifdef ERROR4 +all: some; @echo error is $(ERROR4) + @echo $(error error is $(ERROR4)) +endif + +some: ; @echo Some stuff + +testvar: ; @: $(err) +'; + +close(MAKEFILE); + +# Test #1 + +&run_make_with_options($makefile, "ERROR1=yes", &get_logfile, 512); +$answer = "$makefile:4: *** error is yes. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #2 + +&run_make_with_options($makefile, "ERROR2=no", &get_logfile, 512); +$answer = "$makefile:8: *** error is no. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #3 + +&run_make_with_options($makefile, "ERROR3=maybe", &get_logfile, 512); +$answer = "Some stuff\n$makefile:12: *** error is maybe. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #4 + +&run_make_with_options($makefile, "ERROR4=definitely", &get_logfile, 512); +$answer = "Some stuff\n$makefile:16: *** error is definitely. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #5 + +&run_make_with_options($makefile, "testvar", &get_logfile, 512); +$answer = "$makefile:22: *** Error found!. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/eval b/tests/scripts/functions/eval new file mode 100644 index 0000000..90513bd --- /dev/null +++ b/tests/scripts/functions/eval @@ -0,0 +1,169 @@ +# -*-perl-*- + +$description = "Test the eval function."; + +$details = "This is a test of the eval function in GNU make. +This function will evaluate inline makefile syntax and incorporate the +results into its internal database.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +define Y + all:: ; @echo $AA + A = B +endef + +X = $(eval $(value Y)) + +$(eval $(shell echo A = A)) +$(eval $(Y)) +$(eval A = C) +$(eval $(X)) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "AA\nBA\n"; + +&compare_output($answer,&get_logfile(1)); + +# Test to make sure defining variables when we have extra scope pushed works +# as expected. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE <<'EOF'; +VARS = A B + +VARSET = $(1) = $(2) + +$(foreach v,$(VARS),$(eval $(call VARSET,$v,$v))) + +all: ; @echo A = $(A) B = $(B) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, "", &get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "A = A B = B\n"; + +&compare_output($answer,&get_logfile(1)); + +# Test to make sure eval'ing inside conditionals works properly + +$makefile3 = &get_tmpfile; + +open(MAKEFILE,"> $makefile3"); + +print MAKEFILE <<'EOF'; +FOO = foo + +all:: ; @echo it + +define Y + all:: ; @echo worked +endef + +ifdef BAR +$(eval $(Y)) +endif + +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile3, "", &get_logfile); +$answer = "it\n"; +&compare_output($answer,&get_logfile(1)); + +&run_make_with_options($makefile3, "BAR=1", &get_logfile); +$answer = "it\nworked\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST very recursive invocation of eval + +$makefile3 = &get_tmpfile; + +open(MAKEFILE,"> $makefile3"); + +print MAKEFILE <<'EOF'; +..9 := 0 1 2 3 4 5 6 7 8 9 +rev=$(eval res:=)$(foreach word,$1,$(eval res:=${word} ${res}))${res} +a:=$(call rev,${..9}) +all: ; @echo '[$(a)]' + +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile3, "", &get_logfile); +$answer = "[ 9 8 7 6 5 4 3 2 1 0 ]\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST eval with no filename context. +# The trick here is that because EVAR is taken from the environment, it must +# be evaluated before every command is invoked. Make sure that works, when +# we have no file context for reading_file (bug # 6195) + +$makefile4 = &get_tmpfile; + +open(MAKEFILE,"> $makefile4"); + +print MAKEFILE <<'EOF'; +EVAR = $(eval FOBAR = 1) +all: ; @echo "OK" + +EOF + +close(MAKEFILE); + +$extraENV{EVAR} = '1'; +&run_make_with_options($makefile4, "", &get_logfile); +$answer = "OK\n"; +&compare_output($answer,&get_logfile(1)); + + +# Clean out previous information to allow new run_make_test() interface. +# If we ever convert all the above to run_make_test() we can remove this line. +$makefile = undef; + +# Test handling of backslashes in strings to be evaled. + +run_make_test(' +define FOO +all: ; @echo hello \ +world +endef +$(eval $(FOO)) +', '', 'hello world'); + +run_make_test(' +define FOO +all: ; @echo '."'".'he\llo'."'".' + @echo world +endef +$(eval $(FOO)) +', '', 'he\llo +world'); + + +# We don't allow new target/prerequisite relationships to be defined within a +# command script, because these are evaluated after snap_deps() and that +# causes lots of problems (like core dumps!) +# See Savannah bug # 12124. + +run_make_test('deps: ; $(eval deps: foo)', '', + '#MAKEFILE#:1: *** prerequisites cannot be defined in recipes. Stop.', + 512); + +1; diff --git a/tests/scripts/functions/filter-out b/tests/scripts/functions/filter-out new file mode 100644 index 0000000..6c8b27a --- /dev/null +++ b/tests/scripts/functions/filter-out @@ -0,0 +1,28 @@ +# -*-perl-*- + +$description = "Test the filter-out function."; + +$details = "The makefile created in this test has two variables. The +filter-out function is first used to discard names ending in +.o with a single simple pattern. The second filter-out function +augments the simple pattern with three literal names, which are +also added to the text argument. This tests an internal hash table +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"); + +print MAKEFILE <<'EOF'; +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 + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile, 0); +$answer = "foo.elc foo.elc\n"; +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/findstring b/tests/scripts/functions/findstring new file mode 100644 index 0000000..48abede --- /dev/null +++ b/tests/scripts/functions/findstring @@ -0,0 +1,47 @@ +$description = "The following test creates a makefile to test the findstring " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(findstring port, reporter)\n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile, + "", + &get_logfile, + 0); + +# Create the answer to what should be produced by this Makefile +$answer = "port\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/flavor b/tests/scripts/functions/flavor new file mode 100644 index 0000000..80d6be7 --- /dev/null +++ b/tests/scripts/functions/flavor @@ -0,0 +1,44 @@ +# -*-perl-*- +$description = "Test the flavor function."; + +$details = ""; + + +# Test #1: Test general logic. +# +run_make_test(' +s := s +r = r + +$(info u $(flavor u)) +$(info s $(flavor s)) +$(info r $(flavor r)) + +ra += ra +rc ?= rc + +$(info ra $(flavor ra)) +$(info rc $(flavor rc)) + +s += s +r += r + +$(info s $(flavor s)) +$(info r $(flavor r)) + + +.PHONY: all +all:;@: +', +'', +'u undefined +s simple +r recursive +ra recursive +rc recursive +s simple +r recursive'); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/functions/foreach b/tests/scripts/functions/foreach new file mode 100644 index 0000000..82e99d7 --- /dev/null +++ b/tests/scripts/functions/foreach @@ -0,0 +1,77 @@ +# -*-perl-*- +# $Id: foreach,v 1.5 2006/03/10 02:20:46 psmith Exp $ + +$description = "Test the foreach function."; + +$details = "This is a test of the foreach function in gnu make. +This function starts with a space separated list of +names and a variable. Each name in the list is subsituted +into the variable and the given text evaluated. The general +form of the command is $(foreach var,$list,$text). Several +types of foreach loops are tested\n"; + + +# TEST 0 + +# Set an environment variable that we can test in the makefile. +$extraENV{FOOFOO} = 'foo foo'; + +run_make_test("space = ' '".' +null := +auto_var = udef space CC null FOOFOO MAKE foo CFLAGS WHITE @ < +foo = bletch null @ garf +av = $(foreach var, $(auto_var), $(origin $(var)) ) +override WHITE := BLACK +for_var = $(addsuffix .c,foo $(null) $(foo) $(space) $(av) ) +fe = $(foreach var2, $(for_var),$(subst .c,.o, $(var2) ) ) +all: auto for2 +auto : ; @echo $(av) +for2: ; @echo $(fe)', + '-e WHITE=WHITE CFLAGS=', + "undefined file default file environment default file command line override automatic automatic +foo.o bletch.o null.o @.o garf.o .o .o undefined.o file.o default.o file.o environment.o default.o file.o command.o line.o override.o automatic.o automatic.o"); + +delete $extraENV{FOOFOO}; + +# TEST 1: Test that foreach variables take precedence over global +# variables in a global scope (like inside an eval). Tests bug #11913 + +run_make_test(' +.PHONY: all target +all: target + +x := BAD + +define mktarget +target: x := $(x) +target: ; @echo "$(x)" +endef + +x := GLOBAL + +$(foreach x,FOREACH,$(eval $(value mktarget)))', + '', + 'FOREACH'); + + +# TEST 2: Check some error conditions. + +run_make_test(' +x = $(foreach ) +y = $x + +all: ; @echo $y', + '', + "#MAKEFILE#:2: *** insufficient number of arguments (1) to function `foreach'. Stop.", + 512); + +run_make_test(' +x = $(foreach ) +y := $x + +all: ; @echo $y', + '', + "#MAKEFILE#:2: *** insufficient number of arguments (1) to function `foreach'. Stop.", + 512); + +1; diff --git a/tests/scripts/functions/if b/tests/scripts/functions/if new file mode 100644 index 0000000..8604e4f --- /dev/null +++ b/tests/scripts/functions/if @@ -0,0 +1,33 @@ +# -*-perl-*- +$description = "Test the if function.\n"; + +$details = "Try various uses of if and ensure they all give the correct +results.\n"; + +open(MAKEFILE, "> $makefile"); + +print MAKEFILE <<EOMAKE; +NEQ = \$(subst \$1,,\$2) +e = + +all: +\t\@echo 1 \$(if ,true,false) +\t\@echo 2 \$(if ,true,) +\t\@echo 3 \$(if ,true) +\t\@echo 4 \$(if z,true,false) +\t\@echo 5 \$(if z,true,\$(shell echo hi)) +\t\@echo 6 \$(if ,\$(shell echo hi),false) +\t\@echo 7 \$(if \$(call NEQ,a,b),true,false) +\t\@echo 8 \$(if \$(call NEQ,a,a),true,false) +\t\@echo 9 \$(if z,true,fal,se) hi +\t\@echo 10 \$(if ,true,fal,se)there +\t\@echo 11 \$(if \$(e) ,true,false) +EOMAKE + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "1 false\n2\n3\n4 true\n5 true\n6 false\n7 true\n8 false\n9 true hi\n10 fal,sethere\n11 false\n"; +&compare_output($answer, &get_logfile(1)); + +1; diff --git a/tests/scripts/functions/join b/tests/scripts/functions/join new file mode 100644 index 0000000..302c307 --- /dev/null +++ b/tests/scripts/functions/join @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the join " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(join a b c,foo hacks .pl1) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "afoo bhacks c.pl1\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/notdir b/tests/scripts/functions/notdir new file mode 100644 index 0000000..4ed8f9c --- /dev/null +++ b/tests/scripts/functions/notdir @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the notdir " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(notdir ${pathsep}src${pathsep}foo.c hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "foo.c hacks\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/origin b/tests/scripts/functions/origin new file mode 100644 index 0000000..f7b7eb8 --- /dev/null +++ b/tests/scripts/functions/origin @@ -0,0 +1,51 @@ +# -*-perl-*- + +$description = "Test the origin function."; + +$details = "This is a test of the origin function in gnu make. +This function will report on where a variable was +defined per the following list: + +'undefined' never defined +'default' default definition +'environment' environment var without -e +'environment override' environment var with -e +'file' defined in makefile +'command line' defined on the command line +'override' defined by override in makefile +'automatic' Automatic variable\n"; + +# Set an environment variable +$extraENV{MAKETEST} = 1; + +run_make_test(' +foo := bletch garf +auto_var = undefined CC MAKETEST MAKE foo CFLAGS WHITE @ +av = $(foreach var, $(auto_var), $(origin $(var)) ) +override WHITE := BLACK +all: auto + @echo $(origin undefined) + @echo $(origin CC) + @echo $(origin MAKETEST) + @echo $(origin MAKE) + @echo $(origin foo) + @echo $(origin CFLAGS) + @echo $(origin WHITE) + @echo $(origin @) +auto : + @echo $(av)', + '-e WHITE=WHITE CFLAGS=', + 'undefined default environment default file command line override automatic +undefined +default +environment +default +file +command line +override +automatic'); + +# Reset an environment variable +delete $extraENV{MAKETEST}; + +1; diff --git a/tests/scripts/functions/realpath b/tests/scripts/functions/realpath new file mode 100644 index 0000000..9b503b4 --- /dev/null +++ b/tests/scripts/functions/realpath @@ -0,0 +1,82 @@ +# -*-perl-*- +$description = "Test the realpath functions."; + +$details = ""; + +run_make_test(' +ifneq ($(realpath .),$(CURDIR)) + $(error ) +endif + +ifneq ($(realpath ./),$(CURDIR)) + $(error ) +endif + +ifneq ($(realpath .///),$(CURDIR)) + $(error ) +endif + +ifneq ($(realpath /),/) + $(error ) +endif + +ifneq ($(realpath /.),/) + $(error ) +endif + +ifneq ($(realpath /./),/) + $(error ) +endif + +ifneq ($(realpath /.///),/) + $(error ) +endif + +ifneq ($(realpath /..),/) + $(error ) +endif + +ifneq ($(realpath /../),/) + $(error ) +endif + +ifneq ($(realpath /..///),/) + $(error ) +endif + +ifneq ($(realpath . /..),$(CURDIR) /) + $(error ) +endif + +.PHONY: all +all: ; @: +', + '', + ''); + +# On Windows platforms, "//" means something special. So, don't do these +# tests there. + +if ($port_type ne 'W32') { + run_make_test(' +ifneq ($(realpath ///),/) + $(error ) +endif + +ifneq ($(realpath ///.),/) + $(error ) +endif + +ifneq ($(realpath ///..),/) + $(error ) +endif + +.PHONY: all +all: ; @:', + '', + ''); +} + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/functions/shell b/tests/scripts/functions/shell new file mode 100644 index 0000000..723cd0e --- /dev/null +++ b/tests/scripts/functions/shell @@ -0,0 +1,32 @@ +# -*-perl-*- + +$description = 'Test the $(shell ...) function.'; + +$details = ''; + + +# Test shells inside rules. +run_make_test('.PHONY: all +all: ; @echo $(shell echo hi) +','','hi'); + + +# Test unescaped comment characters in shells. Savannah bug #20513 +if ($all_tests) { + run_make_test(q! +FOO := $(shell echo '#') +foo: ; echo '$(FOO)' +!, + '', "#\n"); +} + +# Test shells inside exported environment variables. +# This is the test that fails if we try to put make exported variables into +# the environment for a $(shell ...) call. +run_make_test(' +export HI = $(shell echo hi) +.PHONY: all +all: ; @echo $$HI +','','hi'); + +1; diff --git a/tests/scripts/functions/sort b/tests/scripts/functions/sort new file mode 100644 index 0000000..d472102 --- /dev/null +++ b/tests/scripts/functions/sort @@ -0,0 +1,55 @@ +$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)); + +1; + + + + + + diff --git a/tests/scripts/functions/strip b/tests/scripts/functions/strip new file mode 100644 index 0000000..8222433 --- /dev/null +++ b/tests/scripts/functions/strip @@ -0,0 +1,57 @@ +# -*-perl-*- +$description = "The following test creates a makefile to verify +the ability of make to strip white space from lists of object.\n"; + + +$details = "The make file is built with a list of objects that contain white space +These are then run through the strip command to remove it. This is then +verified by echoing the result.\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOMAKE'; +TEST1 := "Is this TERMINAL fun? What makes you believe is this terminal fun? JAPAN is a WONDERFUL planet -- I wonder if we will ever reach their level of COMPARATIVE SHOPPING..." +E := +TEST2 := $E try this and this $E + +define TEST3 + +and these test out + + +some +blank lines + + + +endef + +.PHONY: all +all: + @echo '$(strip $(TEST1) )' + @echo '$(strip $(TEST2) )' + @echo '$(strip $(TEST3) )' + +space: ; @echo '$(strip ) $(strip )' + +EOMAKE + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); +$answer = "\"Is this TERMINAL fun? What makes you believe is this terminal fun? JAPAN is a WONDERFUL planet -- I wonder if we will ever reach their level of COMPARATIVE SHOPPING...\" +try this and this +and these test out some blank lines +"; +&compare_output($answer,&get_logfile(1)); + + +&run_make_with_options($makefile,"space",&get_logfile); +$answer = " \n"; +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/substitution b/tests/scripts/functions/substitution new file mode 100644 index 0000000..0d2f6a2 --- /dev/null +++ b/tests/scripts/functions/substitution @@ -0,0 +1,38 @@ +# -*-perl-*- + +$description = "Test the subst and patsubst functions"; + +$details = ""; + +# Generic patsubst test: test both the function and variable form. + +run_make_test(' +foo := a.o b.o c.o +bar := $(foo:.o=.c) +bar2:= $(foo:%.o=%.c) +bar3:= $(patsubst %.c,%.o,x.c.c bar.c) +all:;@echo $(bar); echo $(bar2); echo $(bar3)', +'', +'a.c b.c c.c +a.c b.c c.c +x.c.o bar.o'); + +# Patsubst without '%'--shouldn't match because the whole word has to match +# in patsubst. Based on a bug report by Markus Mauhart <qwe123@chello.at> + +run_make_test('all:;@echo $(patsubst Foo,Repl,FooFoo)', '', 'FooFoo'); + +# Variable subst where a pattern matches multiple times in a single word. +# Based on a bug report by Markus Mauhart <qwe123@chello.at> + +run_make_test(' +A := fooBARfooBARfoo +all:;@echo $(A:fooBARfoo=REPL)', '', 'fooBARREPL'); + +1; + + + + + + diff --git a/tests/scripts/functions/suffix b/tests/scripts/functions/suffix new file mode 100644 index 0000000..0c4f919 --- /dev/null +++ b/tests/scripts/functions/suffix @@ -0,0 +1,57 @@ +$description = "The following test creates a makefile to test the suffix\n" + ."function. \n"; + +$details = "The suffix function will return the string following the last _._\n" + ."the list provided. It will provide all of the unique suffixes found\n" + ."in the list. The long strings are sorted to remove duplicates.\n"; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := word.pl general_test2.pl1 FORCE.pl word.pl3 generic_test.perl /tmp.c/bar foo.baz/bar.c MAKEFILES_variable.c\n" + ."string2 := \$(string) \$(string) \$(string) \$(string) \$(string) \$(string) \$(string)\n" + ."string3 := \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2)\n" + ."string4 := \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3)\n" + ."all: \n" + ."\t\@echo \$(suffix \$(string)) \n" + ."\t\@echo \$(sort \$(suffix \$(string4))) \n" + ."\t\@echo \$(suffix \$(string) a.out) \n" + ."\t\@echo \$(sort \$(suffix \$(string3))) \n"; + + + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile + +# COMPARE RESULTS +$answer = ".pl .pl1 .pl .pl3 .perl .c .c\n" + .".c .perl .pl .pl1 .pl3\n" + .".pl .pl1 .pl .pl3 .perl .c .c .out\n" + .".c .perl .pl .pl1 .pl3\n"; + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/value b/tests/scripts/functions/value new file mode 100644 index 0000000..8e1a6f0 --- /dev/null +++ b/tests/scripts/functions/value @@ -0,0 +1,30 @@ +# -*-perl-*- + +$description = "Test the value function."; + +$details = "This is a test of the value function in GNU make. +This function will evaluate to the value of the named variable with no +further expansion performed on it.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +export FOO = foo + +recurse = FOO = $FOO +static := FOO = $(value FOO) + +all: ; @echo $(recurse) $(value recurse) $(static) $(value static) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "FOO = OO FOO = foo FOO = foo FOO = foo\n"; + + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/warning b/tests/scripts/functions/warning new file mode 100644 index 0000000..cd452d4 --- /dev/null +++ b/tests/scripts/functions/warning @@ -0,0 +1,65 @@ +# -*-Perl-*- + +$description = "\ +The following test creates a makefile to test the warning function."; + +$details = ""; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +ifdef WARNING1 +$(warning warning is $(WARNING1)) +endif + +ifdef WARNING2 +$(warning warning is $(WARNING2)) +endif + +ifdef WARNING3 +all: some; @echo hi $(warning warning is $(WARNING3)) +endif + +ifdef WARNING4 +all: some; @echo hi + @echo there $(warning warning is $(WARNING4)) +endif + +some: ; @echo Some stuff + +EOF + +close(MAKEFILE); + +# Test #1 + +&run_make_with_options($makefile, "WARNING1=yes", &get_logfile, 0); +$answer = "$makefile:2: warning is yes\nSome stuff\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #2 + +&run_make_with_options($makefile, "WARNING2=no", &get_logfile, 0); +$answer = "$makefile:6: warning is no\nSome stuff\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #3 + +&run_make_with_options($makefile, "WARNING3=maybe", &get_logfile, 0); +$answer = "Some stuff\n$makefile:10: warning is maybe\nhi\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #4 + +&run_make_with_options($makefile, "WARNING4=definitely", &get_logfile, 0); +$answer = "Some stuff\n$makefile:14: warning is definitely\nhi\nthere\n"; +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/wildcard b/tests/scripts/functions/wildcard new file mode 100644 index 0000000..2841f5d --- /dev/null +++ b/tests/scripts/functions/wildcard @@ -0,0 +1,91 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test wildcard +expansions and the ability to put a command on the same +line as the target name separated by a semi-colon."; + +$details = "\ +This test creates 4 files by the names of 1.example, +two.example and 3.example. We execute three tests. The first +executes the print1 target which tests the '*' wildcard by +echoing all filenames by the name of '*.example'. The second +test echo's all files which match '?.example' and +[a-z0-9].example. Lastly we clean up all of the files using +the '*' wildcard as in the first test"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOM; +.PHONY: print1 print2 clean +print1: ;\@echo \$(sort \$(wildcard example.*)) +print2: +\t\@echo \$(sort \$(wildcard example.?)) +\t\@echo \$(sort \$(wildcard example.[a-z0-9])) +\t\@echo \$(sort \$(wildcard example.[!A-Za-z_\\!])) +clean: +\t$delete_command \$(sort \$(wildcard example.*)) +EOM + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("example.1"); +&touch("example.two"); +&touch("example.3"); +&touch("example.for"); +&touch("example._"); + +# TEST #1 +# ------- + +$answer = "example.1 example.3 example._ example.for example.two\n"; + +&run_make_with_options($makefile,"print1",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- + +$answer = "example.1 example.3 example._\n" + ."example.1 example.3\n" + ."example.1 example.3\n"; + +&run_make_with_options($makefile,"print2",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 +# ------- + +$answer = "$delete_command example.1 example.3 example._ example.for example.two"; +if ($vos) +{ + $answer .= " \n"; +} +else +{ + $answer .= "\n"; +} + +&run_make_with_options($makefile,"clean",&get_logfile); + +if ((-f "example.1")||(-f "example.two")||(-f "example.3")||(-f "example.for")) { + $test_passed = 0; +} + +&compare_output($answer,&get_logfile(1)); + +# TEST #4: Verify that failed wildcards don't return the pattern + +run_make_test(q! +all: ; @echo $(wildcard xz--y*.7) +!, + '', "\n"); + +1; diff --git a/tests/scripts/functions/word b/tests/scripts/functions/word new file mode 100644 index 0000000..34527ea --- /dev/null +++ b/tests/scripts/functions/word @@ -0,0 +1,167 @@ +# -*-perl-*- +$description = "\ +Test the word, words, wordlist, firstword, and lastword functions.\n"; + +$details = "\ +Produce a variable with a large number of words in it, +determine the number of words, and then read each one back.\n"; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE <<'EOF'; +string := word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl +string2 := $(string) $(string) $(string) $(string) $(string) $(string) $(string) +string3 := $(string2) $(string2) $(string2) $(string2) $(string2) $(string2) $(string2) +string4 := $(string3) $(string3) $(string3) $(string3) $(string3) $(string3) $(string3) +all: + @echo $(words $(string)) + @echo $(words $(string4)) + @echo $(word 1, $(string)) + @echo $(word 100, $(string)) + @echo $(word 1, $(string)) + @echo $(word 1000, $(string3)) + @echo $(wordlist 3, 4, $(string)) + @echo $(wordlist 4, 3, $(string)) + @echo $(wordlist 1, 6, $(string)) + @echo $(wordlist 5, 7, $(string)) + @echo $(wordlist 100, 110, $(string)) + @echo $(wordlist 7, 10, $(string2)) +EOF +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "6\n" + ."2058\n" + ."word.pl\n" + ."\n" + ."word.pl\n" + ."\n" + ."FORCE.pl word.pl\n" + ."\n" + ."word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl\n" + ."generic_test.perl MAKEFILES_variable.pl\n" + ."\n" + ."word.pl general_test2.pl FORCE.pl word.pl\n"; +&compare_output($answer, &get_logfile(1)); + + +# Test error conditions + +run_make_test('FOO = foo bar biz baz + +word-e1: ; @echo $(word ,$(FOO)) +word-e2: ; @echo $(word abc ,$(FOO)) +word-e3: ; @echo $(word 1a,$(FOO)) + +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.", + 512); + +run_make_test(undef, + 'word-e2', + "#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.", + 512); + +run_make_test(undef, + 'wordlist-e1', + "#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.", + 512); + +run_make_test(undef, + 'wordlist-e3', + "#MAKEFILE#:9: *** non-numeric second argument to `wordlist' function: ' 12a '. Stop.", + 512); + +# Test error conditions again, but this time in a variable reference + +run_make_test('FOO = foo bar biz baz + +W = $(word $x,$(FOO)) +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.", + 512); + +run_make_test(undef, + 'word-e x=abc', + "#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.", + 512); + +run_make_test(undef, + 'wordlist-e s= e=', + "#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.", + 512); + +run_make_test(undef, + 'wordlist-e s=4 e=12a', + "#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.", + 512); + + +# TEST #8 -- test $(firstword ) +# +run_make_test(' +void := +list := $(void) foo bar baz # + +a := $(word 1,$(list)) +b := $(firstword $(list)) + +.PHONY: all + +all: + @test "$a" = "$b" && echo $a +', +'', +'foo'); + + +# TEST #9 -- test $(lastword ) +# +run_make_test(' +void := +list := $(void) foo bar baz # + +a := $(word $(words $(list)),$(list)) +b := $(lastword $(list)) + +.PHONY: all + +all: + @test "$a" = "$b" && echo $a +', +'', +'baz'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/misc/close_stdout b/tests/scripts/misc/close_stdout new file mode 100644 index 0000000..18606c3 --- /dev/null +++ b/tests/scripts/misc/close_stdout @@ -0,0 +1,9 @@ +# -*-perl-*- + +$description = "Make sure make exits with an error if stdout is full."; + +if (-e '/dev/full') { + run_make_test('', '-v > /dev/full', '/^#MAKE#: write error/', 256); +} + +1; diff --git a/tests/scripts/misc/general1 b/tests/scripts/misc/general1 new file mode 100644 index 0000000..352fc6a --- /dev/null +++ b/tests/scripts/misc/general1 @@ -0,0 +1,51 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test the +simple functionality of make. It mimics the +rebuilding of a product with dependencies. +It also tests the simple definition of VPATH."; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<EOF; +VPATH = $workdir +edit: main.o kbd.o commands.o display.o \\ + insert.o +\t\@echo cc -o edit main.o kbd.o commands.o display.o \\ + insert.o +main.o : main.c defs.h +\t\@echo cc -c main.c +kbd.o : kbd.c defs.h command.h +\t\@echo cc -c kbd.c +commands.o : command.c defs.h command.h +\t\@echo cc -c commands.c +display.o : display.c defs.h buffer.h +\t\@echo cc -c display.c +insert.o : insert.c defs.h buffer.h +\t\@echo cc -c insert.c +EOF + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c main.c\ncc -c kbd.c\ncc -c commands.c\ncc -c display.c +cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o insert.o\n"; + +# COMPARE RESULTS + +if (&compare_output($answer,&get_logfile(1))) { + unlink @files_to_touch; +} + +1; diff --git a/tests/scripts/misc/general2 b/tests/scripts/misc/general2 new file mode 100644 index 0000000..fb5c3aa --- /dev/null +++ b/tests/scripts/misc/general2 @@ -0,0 +1,50 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test the +simple functionality of make. It is the same as +general_test1 except that this one tests the +definition of a variable to hold the object filenames."; + +open(MAKEFILE,"> $makefile"); + +# The contents of the Makefile ... + +print MAKEFILE <<EOF; +VPATH = $workdir +objects = main.o kbd.o commands.o display.o insert.o +edit: \$(objects) +\t\@echo cc -o edit \$(objects) +main.o : main.c defs.h +\t\@echo cc -c main.c +kbd.o : kbd.c defs.h command.h +\t\@echo cc -c kbd.c +commands.o : command.c defs.h command.h +\t\@echo cc -c commands.c +display.o : display.c defs.h buffer.h +\t\@echo cc -c display.c +insert.o : insert.c defs.h buffer.h +\t\@echo cc -c insert.c +EOF + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c main.c\ncc -c kbd.c\ncc -c commands.c\ncc -c display.c +cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o insert.o\n"; + +if (&compare_output($answer,&get_logfile(1))) { + unlink @files_to_touch; +} + +1; diff --git a/tests/scripts/misc/general3 b/tests/scripts/misc/general3 new file mode 100644 index 0000000..b3142c2 --- /dev/null +++ b/tests/scripts/misc/general3 @@ -0,0 +1,313 @@ +# -*-perl-*- + +$description = "\ +This tests random features of the parser that need to be supported, and +which have either broken at some point in the past or seem likely to +break."; + +run_make_test(" +# We want to allow both empty commands _and_ commands that resolve to empty. +EMPTY = + +.PHONY: all a1 a2 a3 a4 +all: a1 a2 a3 a4 + +a1:; +a2: +\t +a3:;\$(EMPTY) +a4: +\t\$(EMPTY) + +\# Non-empty lines that expand to nothing should also be ignored. +STR = \# Some spaces +TAB = \t \# A TAB and some spaces + +\$(STR) + +\$(STR) \$(TAB)", + '', "#MAKE#: Nothing to be done for `all'."); + +# TEST 2 + +# Make sure files without trailing newlines are handled properly. +# Have to use the old style invocation to test this. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); +print MAKEFILE "all:;\@echo FOO = \$(FOO)\nFOO = foo"; +close(MAKEFILE); + +&run_make_with_options($makefile2,"",&get_logfile); +$answer = "FOO = foo\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST 3 + +# Check semicolons in variable references + +run_make_test(' +$(if true,$(info true; true)) +all: ; @: +', + '', 'true; true'); + +# TEST 4 + +# Check that backslashes in command scripts are handled according to POSIX. +# Checks Savannah bug # 1332. + +# Test the fastpath / no quotes +run_make_test(' +all: + @echo foo\ +bar + @echo foo\ + bar + @echo foo\ + bar + @echo foo\ + bar + @echo foo \ +bar + @echo foo \ + bar + @echo foo \ + bar + @echo foo \ + bar +', + '', 'foobar +foobar +foo bar +foo bar +foo bar +foo bar +foo bar +foo bar'); + +# Test the fastpath / single quotes +run_make_test(" +all: + \@echo 'foo\\ +bar' + \@echo 'foo\\ + bar' + \@echo 'foo\\ + bar' + \@echo 'foo\\ + bar' + \@echo 'foo \\ +bar' + \@echo 'foo \\ + bar' + \@echo 'foo \\ + bar' + \@echo 'foo \\ + bar' +", + '', 'foo\ +bar +foo\ +bar +foo\ + bar +foo\ + bar +foo \ +bar +foo \ +bar +foo \ + bar +foo \ + bar'); + +# Test the fastpath / double quotes +run_make_test(' +all: + @echo "foo\ +bar" + @echo "foo\ + bar" + @echo "foo\ + bar" + @echo "foo\ + bar" + @echo "foo \ +bar" + @echo "foo \ + bar" + @echo "foo \ + bar" + @echo "foo \ + bar" +', + '', 'foobar +foobar +foo bar +foo bar +foo bar +foo bar +foo bar +foo bar'); + +# Test the slow path / no quotes +run_make_test(' +all: + @echo hi; echo foo\ +bar + @echo hi; echo foo\ + bar + @echo hi; echo foo\ + bar + @echo hi; echo foo\ + bar + @echo hi; echo foo \ +bar + @echo hi; echo foo \ + bar + @echo hi; echo foo \ + bar + @echo hi; echo foo \ + bar +', + '', 'hi +foobar +hi +foobar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar'); + +# Test the slow path / no quotes. This time we put the slow path +# determination _after_ the backslash-newline handling. +run_make_test(' +all: + @echo foo\ +bar; echo hi + @echo foo\ + bar; echo hi + @echo foo\ + bar; echo hi + @echo foo\ + bar; echo hi + @echo foo \ +bar; echo hi + @echo foo \ + bar; echo hi + @echo foo \ + bar; echo hi + @echo foo \ + bar; echo hi +', + '', 'foobar +hi +foobar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi'); + +# Test the slow path / single quotes +run_make_test(" +all: + \@echo hi; echo 'foo\\ +bar' + \@echo hi; echo 'foo\\ + bar' + \@echo hi; echo 'foo\\ + bar' + \@echo hi; echo 'foo\\ + bar' + \@echo hi; echo 'foo \\ +bar' + \@echo hi; echo 'foo \\ + bar' + \@echo hi; echo 'foo \\ + bar' + \@echo hi; echo 'foo \\ + bar' +", + '', 'hi +foo\ +bar +hi +foo\ +bar +hi +foo\ + bar +hi +foo\ + bar +hi +foo \ +bar +hi +foo \ +bar +hi +foo \ + bar +hi +foo \ + bar'); + +# Test the slow path / double quotes +run_make_test(' +all: + @echo hi; echo "foo\ +bar" + @echo hi; echo "foo\ + bar" + @echo hi; echo "foo\ + bar" + @echo hi; echo "foo\ + bar" + @echo hi; echo "foo \ +bar" + @echo hi; echo "foo \ + bar" + @echo hi; echo "foo \ + bar" + @echo hi; echo "foo \ + bar" +', + '', 'hi +foobar +hi +foobar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar'); + +1; diff --git a/tests/scripts/misc/general4 b/tests/scripts/misc/general4 new file mode 100644 index 0000000..6d42a16 --- /dev/null +++ b/tests/scripts/misc/general4 @@ -0,0 +1,82 @@ +# -*-perl-*- + +$description = "\ +This tests random features of make's algorithms, often somewhat obscure, +which have either broken at some point in the past or seem likely to +break."; + +run_make_test(' +# Make sure that subdirectories built as prerequisites are actually handled +# properly. + +all: dir/subdir/file.a + +dir/subdir: ; @echo mkdir -p dir/subdir + +dir/subdir/file.b: dir/subdir ; @echo touch dir/subdir/file.b + +dir/subdir/%.a: dir/subdir/%.b ; @echo cp $< $@', + '', "mkdir -p dir/subdir\ntouch dir/subdir/file.b\ncp dir/subdir/file.b dir/subdir/file.a\n"); + +# Test implicit rules + +&touch('foo.c'); +run_make_test('foo: foo.o', + 'CC="@echo cc" OUTPUT_OPTION=', + 'cc -c foo.c +cc foo.o -o foo'); +unlink('foo.c'); + + +# Test implicit rules with '$' in the name (see se_implicit) + +run_make_test(q! +%.foo : baz$$bar ; @echo 'done $<' +%.foo : bar$$baz ; @echo 'done $<' +test.foo: +baz$$bar bar$$baz: ; @echo '$@' +!, + '', + "baz\$bar\ndone baz\$bar"); + + +# Test implicit rules with '$' in the name (see se_implicit) +# Use the '$' in the pattern. + +run_make_test(q! +%.foo : %$$bar ; @echo 'done $<' +test.foo: +test$$bar: ; @echo '$@' +!, + '', + "test\$bar\ndone test\$bar"); + +# Make sure that subdirectories built as prerequisites are actually handled +# properly... this time with '$' + +run_make_test(q! + +all: dir/subdir/file.$$a + +dir/subdir: ; @echo mkdir -p '$@' + +dir/subdir/file.$$b: dir/subdir ; @echo touch '$@' + +dir/subdir/%.$$a: dir/subdir/%.$$b ; @echo 'cp $< $@' +!, + '', "mkdir -p dir/subdir\ntouch dir/subdir/file.\$b\ncp dir/subdir/file.\$b dir/subdir/file.\$a\n"); + +# Test odd whitespace at the beginning of a line + +run_make_test(" +all: + \f + + \\ + \f \\ + \013 \\ +all: ; \@echo hi +", + '', "hi\n"); + +1; diff --git a/tests/scripts/options/dash-B b/tests/scripts/options/dash-B new file mode 100644 index 0000000..e36842e --- /dev/null +++ b/tests/scripts/options/dash-B @@ -0,0 +1,85 @@ +# -*-perl-*- + +$description = "Test make -B (always remake) option.\n"; + +$details = "\ +Construct a simple makefile that builds a target. +Invoke make once, so it builds everything. Invoke it again and verify +that nothing is built. Then invoke it with -B and verify that everything +is built again."; + +&touch('bar.x'); + +run_make_test(' +.SUFFIXES: + +.PHONY: all +all: foo + +foo: bar.x + @echo cp $< $@ + @echo "" > $@ +', + '', 'cp bar.x foo'); + +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, '-B', 'cp bar.x foo'); + +# Clean up + +rmfiles('bar.x', 'foo'); + +# Test -B with the re-exec feature: we don't want to re-exec forever +# Savannah bug # 7566 + +run_make_test(' +all: ; @: +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @touch $@ +', + '-B', 'MAKE_RESTARTS= +#MAKEFILE#:4: foo.x: No such file or directory +MAKE_RESTARTS=1'); + +rmfiles('foo.x'); + +# Test -B with the re-exec feature: we DO want -B in the "normal" part of the +# makefile. + +&touch('blah.x'); + +run_make_test(' +all: blah.x ; @echo $@ +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @touch $@ +blah.x: ; @echo $@ +', + '-B', 'MAKE_RESTARTS= +#MAKEFILE#:4: foo.x: No such file or directory +MAKE_RESTARTS=1 +blah.x +all'); + +rmfiles('foo.x', 'blah.x'); + +# Test that $? is set properly with -B; all prerequisites will be newer! + +utouch(-10, 'x.b'); +touch('x.a'); + +run_make_test(q! +x.a: x.b ; @echo $? +!, + '-B', "x.b\n"); + +unlink(qw(x.a x.b)); + +1; diff --git a/tests/scripts/options/dash-C b/tests/scripts/options/dash-C new file mode 100644 index 0000000..5864ffd --- /dev/null +++ b/tests/scripts/options/dash-C @@ -0,0 +1,71 @@ +# -*-perl-*- + +$description = "Test the -C option to GNU make."; + +$details = "\ +This test is similar to the clean test except that this test creates the file +to delete in the work directory instead of the current directory. Make is +called from another directory using the -C workdir option so that it can both +find the makefile and the file to delete in the work directory."; + +$example = $workdir . $pathsep . "EXAMPLE"; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE <<EOF; +all: ; \@echo This makefile did not clean the dir ... good +clean: ; $delete_command EXAMPLE\$(ext) +EOF +close(MAKEFILE); + +# TEST #1 +# ------- +&touch($example); + +&run_make_with_options("${testname}.mk", + "-C $workdir clean", + &get_logfile); + +chdir $workdir; +$wpath = &get_this_pwd; +chdir $pwd; + +if (-f $example) { + $test_passed = 0; +} + +# Create the answer to what should be produced by this Makefile +$answer = "$make_name: Entering directory `$wpath'\n" + . "$delete_command EXAMPLE\n" + . "$make_name: Leaving directory `$wpath'\n"; + +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- +# Do it again with trailing "/"; this should work the same + +$example .= "slash"; + +&touch($example); + +&run_make_with_options("${testname}.mk", + "-C $workdir/ clean ext=slash", + &get_logfile); + +chdir $workdir; +$wpath = &get_this_pwd; +chdir $pwd; + +if (-f $example) { + $test_passed = 0; +} + +# Create the answer to what should be produced by this Makefile +$answer = "$make_name: Entering directory `$wpath'\n" + . "$delete_command EXAMPLEslash\n" + . "$make_name: Leaving directory `$wpath'\n"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/options/dash-I b/tests/scripts/options/dash-I new file mode 100644 index 0000000..8dc5d9b --- /dev/null +++ b/tests/scripts/options/dash-I @@ -0,0 +1,59 @@ +# -*-perl-*- + +$description ="The following test creates a makefile to test the -I option."; + +$details = "\ +This test tests the -I option by including a filename in +another directory and giving make that directory name +under -I in the command line. Without this option, the make +would fail to find the included file. It also checks to make +sure that the -I option gets passed to recursive makes."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +$mf2 = substr ($makefile2, index ($makefile2, $pathsep) + 1); +print MAKEFILE <<EOF; +include $mf2 +all: +\t\@echo There should be no errors for this makefile. +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE <<EOF; +ANOTHER: +\t\@echo This is another included makefile +recurse: +\t\$(MAKE) ANOTHER -f $makefile +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile,"-I $workdir all",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "There should be no errors for this makefile.\n"; +&compare_output($answer,&get_logfile(1)); + + +$answer = "This is another included makefile\n"; +&run_make_with_options($makefile,"-I $workdir ANOTHER",&get_logfile); +&compare_output($answer,&get_logfile(1)); + + +$answer = "$mkpath ANOTHER -f $makefile +${make_name}[1]: Entering directory `$pwd' +This is another included makefile +${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 new file mode 100644 index 0000000..d3fde87 --- /dev/null +++ b/tests/scripts/options/dash-W @@ -0,0 +1,88 @@ +# -*-perl-*- + +$description = "Test make -W (what if) option.\n"; + +# Basic build + +run_make_test(' +a.x: b.x +a.x b.x: ; echo >> $@ +', + '', "echo >> b.x\necho >> a.x"); + +# Run it again: nothing should happen + +run_make_test(undef, '', "#MAKE#: `a.x' is up to date."); + +# Now run it with -W b.x: should rebuild a.x + +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, '-W b.x', 'echo >> a.x'); + +# Clean up + +rmfiles('a.x', 'b.x'); + +# Test -W with the re-exec feature: we don't want to re-exec forever +# Savannah bug # 7566 + +# First set it up with a normal build + +run_make_test(' +all: baz.x ; @: +include foo.x +foo.x: bar.x + @echo "\$$(info restarts=\$$(MAKE_RESTARTS))" > $@ + @echo "touch $@" +bar.x: ; echo >> $@ +baz.x: bar.x ; @echo "touch $@" +', + '', '#MAKEFILE#:3: foo.x: No such file or directory +echo >> bar.x +touch foo.x +restarts=1 +touch baz.x'); + +# Now run with -W bar.x + +# Tweak foo.x's timestamp so the update will change it. +&utouch(1000, 'foo.x'); + +run_make_test(undef, '-W bar.x', "restarts=\ntouch foo.x\nrestarts=1\ntouch baz.x"); + +rmfiles('foo.x', 'bar.x'); + +# Test -W on vpath-found files: it should take effect. +# Savannah bug # 15341 + +mkdir('x-dir', 0777); +utouch(-20, 'x-dir/x'); +touch('y'); + +run_make_test(' +y: x ; @echo cp $< $@ +', + '-W x-dir/x VPATH=x-dir', + 'cp x-dir/x y'); + +# Make sure ./ stripping doesn't interfere with the match. + +run_make_test(' +y: x ; @echo cp $< $@ +', + '-W ./x-dir/x VPATH=x-dir', + 'cp x-dir/x y'); + +run_make_test(undef, + '-W x-dir/x VPATH=./x-dir', + 'cp ./x-dir/x y'); + +unlink(qw(y x-dir/x)); +rmdir('x-dir'); + +1; diff --git a/tests/scripts/options/dash-e b/tests/scripts/options/dash-e new file mode 100644 index 0000000..17c3fc8 --- /dev/null +++ b/tests/scripts/options/dash-e @@ -0,0 +1,24 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to ..."; + +$details = ""; + +$extraENV{GOOGLE} = 'boggle'; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +GOOGLE = bazzle +all:; @echo "$(GOOGLE)" +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, '-e' ,&get_logfile); + +$answer = "boggle\n"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/options/dash-f b/tests/scripts/options/dash-f new file mode 100644 index 0000000..3aa4746 --- /dev/null +++ b/tests/scripts/options/dash-f @@ -0,0 +1,85 @@ +$description = "The following test tests that if you specify greater \n" + ."than one '-f makefilename' on the command line, \n" + ."that make concatenates them. This test creates three \n" + ."makefiles and specifies all of them with the -f option \n" + ."on the command line. To make sure they were concatenated, \n" + ."we then call make with the rules from the concatenated \n" + ."makefiles one at a time. Finally, it calls all three \n" + ."rules in one call to make and checks that the output\n" + ."is in the correct order."; + +$makefile2 = &get_tmpfile; +$makefile3 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This is the output from the original makefile\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +# Create a second makefile +open(MAKEFILE,"> $makefile2"); +print MAKEFILE "TWO: \n"; +print MAKEFILE "\t\@echo This is the output from makefile 2\n"; +close(MAKEFILE); + +# Create a third makefile +open(MAKEFILE,"> $makefile3"); +print MAKEFILE "THREE: \n"; +print MAKEFILE "\t\@echo This is the output from makefile 3\n"; +close(MAKEFILE); + + +# Create the answer to what should be produced by this Makefile +$answer = "This is the output from the original makefile\n"; + +# Run make to catch the default rule +&run_make_with_options($makefile,"-f $makefile2 -f $makefile3",&get_logfile,0); + +&compare_output($answer,&get_logfile(1)); + + +# Run Make again with the rule from the second makefile: TWO +$answer = "This is the output from makefile 2\n"; + +&run_make_with_options($makefile,"-f $makefile2 -f $makefile3 TWO",&get_logfile,0); + +&compare_output($answer,&get_logfile(1)); + + +# Run Make again with the rule from the third makefile: THREE + +$answer = "This is the output from makefile 3\n"; +&run_make_with_options($makefile, + "-f $makefile2 -f $makefile3 THREE", + &get_logfile, + 0); +&compare_output($answer,&get_logfile(1)); + + +# Run Make again with ALL three rules in the order 2 1 3 to make sure +# that all rules are executed in the proper order + +$answer = "This is the output from makefile 2\n"; +$answer .= "This is the output from the original makefile\n"; +$answer .= "This is the output from makefile 3\n"; +&run_make_with_options($makefile, + "-f $makefile2 -f $makefile3 TWO all THREE", + &get_logfile, + 0); +&compare_output($answer,&get_logfile(1)); + + + + + + + + + + diff --git a/tests/scripts/options/dash-k b/tests/scripts/options/dash-k new file mode 100644 index 0000000..d87a786 --- /dev/null +++ b/tests/scripts/options/dash-k @@ -0,0 +1,114 @@ +# -*-perl-*- + +$description = "Test the make -k (don't stop on error) option.\n"; + +$details = "\ +The makefile created in this test is a simulation of building +a small product. However, the trick to this one is that one +of the dependencies of the main target does not exist. +Without the -k option, make would fail immediately and not +build any part of the target. What we are looking for here, +is that make builds the rest of the dependencies even though +it knows that at the end it will fail to rebuild the main target."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOF; +VPATH = $workdir +edit: main.o kbd.o commands.o display.o +\t\@echo cc -o edit main.o kbd.o commands.o display.o + +main.o : main.c defs.h +\t\@echo cc -c main.c + +kbd.o : kbd.c defs.h command.h +\t\@echo cc -c kbd.c + +commands.o : command.c defs.h command.h +\t\@echo cc -c commands.c + +display.o : display.c defs.h buffer.h +\t\@echo cc -c display.c +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +if ($vos) { + $error_code = 3307; +} +else { + $error_code = 512; +} + +&run_make_with_options($makefile, "-k", &get_logfile, $error_code); + +# 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'. +cc -c commands.c +cc -c display.c +$make_name: Target `edit' not remade because of errors.\n"; + +# COMPARE RESULTS + +&compare_output($answer, &get_logfile(1)); + +unlink(@files_to_touch) unless $keep; + + +# TEST 1: Make sure that top-level targets that depend on targets that +# previously failed to build, aren't attempted. Regression for PR/1634. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); +print MAKEFILE <<'EOF'; +.SUFFIXES: + +all: exe1 exe2; @echo making $@ + +exe1 exe2: lib; @echo cp $^ $@ + +lib: foo.o; @echo cp $^ $@ + +foo.o: ; exit 1 +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, "-k", &get_logfile, $error_code); + +$answer = "exit 1 +$make_name: *** [foo.o] Error 1 +$make_name: Target `all' not remade because of errors.\n"; + +&compare_output($answer, &get_logfile(1)); + +# TEST -- make sure we keep the error code if we can't create an included +# makefile. + +run_make_test('all: ; @echo hi +include ifile +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'. +hi\n", + 512); + +1; diff --git a/tests/scripts/options/dash-l b/tests/scripts/options/dash-l new file mode 100644 index 0000000..0b0f196 --- /dev/null +++ b/tests/scripts/options/dash-l @@ -0,0 +1,56 @@ +# -*-perl-*- +# Date: Tue, 11 Aug 1992 09:34:26 -0400 +# From: pds@lemming.webo.dg.com (Paul D. Smith) + +$description = "Test load balancing (-l) option."; + +$details = "\ +This test creates a makefile where all depends on three rules +which contain the same body. Each rule checks for the existence +of a temporary file; if it exists an error is generated. If it +doesn't exist then it is created, the rule sleeps, then deletes +the temp file again. Thus if any of the rules are run in +parallel the test will fail. When make is called in this test, +it is given the -l option with a value of 0.0001. This ensures +that the load will be above this number and make will therefore +decide that it cannot run more than one job even though -j 4 was +also specified on the command line."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOF'; +SHELL = /bin/sh + +define test +if [ ! -f test-file ]; then \ + echo >> test-file; sleep 2; rm -f test-file; \ +else \ + echo $@ FAILED; \ +fi +endef + +all : ONE TWO THREE +ONE : ; @$(test) +TWO : ; @$(test) +THREE : ; @$(test) +EOF + + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +$mkoptions = "-l 0.0001"; +$mkoptions .= " -j 4" if ($parallel_jobs); + +# We have to wait longer than the default (5s). +&run_make_with_options($makefile, $mkoptions, &get_logfile, 0, 8); + +$slurp = &read_file_into_string (&get_logfile(1)); +if ($slurp !~ /cannot enforce load limit/) { + &compare_output("", &get_logfile(1)); +} + +1; diff --git a/tests/scripts/options/dash-n b/tests/scripts/options/dash-n new file mode 100644 index 0000000..de19f42 --- /dev/null +++ b/tests/scripts/options/dash-n @@ -0,0 +1,70 @@ +# -*-perl-*- +$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'; + +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)); + +# TEST 1 + +&run_make_with_options($makefile, "-Worig -n", &get_logfile); +$answer = "echo >> intermediate\necho >> final\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('orig', 'intermediate', 'final'); + +# We consider the actual updated timestamp of targets with all +# recursive commands, even with -n. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); + +print MAKEFILE <<'EOF'; +.SUFFIXES: +BAR = # nothing +FOO = +$(BAR) +a: b; echo > $@ +b: c; $(FOO) +EOF + +close(MAKEFILE); + +&utouch(-20, 'b'); +&utouch(-10, 'a'); +&touch('c'); + +# TEST 2 + +&run_make_with_options($makefile2, "", &get_logfile); +$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"; +&compare_output($answer, &get_logfile(1)); + +unlink('a', 'b', 'c'); + +1; diff --git a/tests/scripts/options/dash-q b/tests/scripts/options/dash-q new file mode 100644 index 0000000..56f04a1 --- /dev/null +++ b/tests/scripts/options/dash-q @@ -0,0 +1,57 @@ +# -*-perl-*- +$description = "Test the -q option.\n"; + +$details = "Try various uses of -q and ensure they all give the correct results.\n"; + +# TEST 0 + +run_make_test(' +one: +two: ; +three: ; : +four: ; $(.XY) +five: ; \ + $(.XY) +six: ; \ + $(.XY) + $(.XY) +seven: ; \ + $(.XY) + : foo + $(.XY) +', + '-q one', ''); + +# TEST 1 + +run_make_test(undef, '-q two', ''); + +# TEST 2 + +run_make_test(undef, '-q three', '', 256); + +# TEST 3 + +run_make_test(undef, '-q four', ''); + +# TEST 4 + +run_make_test(undef, '-q five', ''); + +# TEST 5 + +run_make_test(undef, '-q six', ''); + +# TEST 6 + +run_make_test(undef, '-q seven', '', 256); + +# TEST 7 : Savannah bug # 7144 + +run_make_test(' +one:: ; @echo one +one:: ; @echo two +', + '-q', '', 256); + +1; diff --git a/tests/scripts/options/dash-t b/tests/scripts/options/dash-t new file mode 100644 index 0000000..ec27d7a --- /dev/null +++ b/tests/scripts/options/dash-t @@ -0,0 +1,58 @@ +# -*-perl-*- + +$description = "Test the -t option.\n"; + +$details = "Look out for regressions of prior bugs related to -t.\n"; +# That means, nobody has even tried to make the tests below comprehensive + +# TEST 0 +# bug reported by Henning Makholm <henning@makholm.net> on 2001-11-03: +# make 3.79.1 touches only interm-[ab] but reports final-[a] as +# 'up to date' without touching them. +# The 'obvious' fix didn't work for double-colon rules, so pay special +# attention to them. + +open(MAKEFILE, "> $makefile"); +print MAKEFILE <<'EOMAKE'; +final-a: interm-a ; echo >> $@ +final-b: interm-b ; echo >> $@ +interm-a:: orig1-a ; echo >> $@ +interm-a:: orig2-a ; echo >> $@ +interm-b:: orig1-b ; echo >> $@ +interm-b:: orig2-b ; echo >> $@ +EOMAKE +close(MAKEFILE); + +&utouch(-30, 'orig1-a','orig2-b'); +&utouch(-20, 'interm-a','interm-b'); +&utouch(-10, 'final-a','final-b'); +&touch('orig2-a','orig1-b'); + +&run_make_with_options($makefile, "-t final-a final-b", &get_logfile); +$answer = "touch interm-a\ntouch final-a\ntouch interm-b\ntouch final-b\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('orig1-a', 'orig2-a', 'interm-a', 'final-a'); +unlink('orig1-b', 'orig2-b', 'interm-b', 'final-b'); + +# TEST 1 +# -t should not touch files with no commands. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); +print MAKEFILE <<'EOMAKE'; + +PHOOEY: xxx +xxx: ; @: + +EOMAKE +close(MAKEFILE); + +&run_make_with_options($makefile2, "-t", &get_logfile); +$answer = "touch xxx\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('xxx'); + +1; diff --git a/tests/scripts/options/eval b/tests/scripts/options/eval new file mode 100644 index 0000000..06a035c --- /dev/null +++ b/tests/scripts/options/eval @@ -0,0 +1,19 @@ +# -*-perl-*- + +$description = "Test the --eval option."; + +$details = "Verify that --eval options take effect, +and are passed to sub-makes."; + +# Verify that --eval is evaluated first +run_make_test(q! +BAR = bar +all: ; @echo all +recurse: ; @$(MAKE) -f #MAKEFILE# && echo recurse!, + '--eval=\$\(info\ eval\) FOO=\$\(BAR\)', "eval\nall"); + +# Make sure that --eval is handled correctly during recursion +run_make_test(undef, '--no-print-directory --eval=\$\(info\ eval\) recurse', + "eval\neval\nall\nrecurse"); + +1; diff --git a/tests/scripts/options/general b/tests/scripts/options/general new file mode 100644 index 0000000..d35bb35 --- /dev/null +++ b/tests/scripts/options/general @@ -0,0 +1,35 @@ +# -*-perl-*- +$description = "Test generic option processing.\n"; + +open(MAKEFILE, "> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo 1foo: ; \@echo \$\@\n"; + +close(MAKEFILE); + +# TEST 0 + +&run_make_with_options($makefile, "-j 1foo", &get_logfile); +if (!$parallel_jobs) { + $answer = "$make_name: Parallel jobs (-j) are not supported on this platform.\n$make_name: Resetting to single job (-j1) mode.\n1foo\n"; +} +else { + $answer = "1foo\n"; +} + +# TEST 1 + +# This test prints the usage string; I don't really know a good way to +# test it. I guess I could invoke make with a known-bad option to see +# what the usage looks like, then compare it to what I get here... :( + +# If I were always on UNIX, I could invoke it with 2>/dev/null, then +# just check the error code. + +&run_make_with_options($makefile, "-j1foo 2>/dev/null", &get_logfile, 512); +$answer = ""; +&compare_output($answer, &get_logfile(1)); + +1; diff --git a/tests/scripts/options/symlinks b/tests/scripts/options/symlinks new file mode 100644 index 0000000..40d2564 --- /dev/null +++ b/tests/scripts/options/symlinks @@ -0,0 +1,68 @@ +# -*-perl-*- + +$description = "Test the -L option."; + +$details = "Verify that symlink handling with and without -L works properly."; + +# Only run these tests if the system sypports symlinks + +# Apparently the Windows port of Perl reports that it does support symlinks +# (in that the symlink() function doesn't fail) but it really doesn't, so +# check for it explicitly. + +if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) { + # This test is N/A + -1; +} else { + + # Set up a symlink sym -> dep + # We'll make both dep and targ older than sym + $pwd =~ m%/([^/]+)$%; + $dirnm = $1; + &utouch(-10, 'dep'); + &utouch(-5, 'targ'); + symlink("../$dirnm/dep", 'sym'); + + # 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."); + run_make_test(undef, '-L', "make targ from sym"); + + # Now update dep; in all cases targ should be out of date. + &touch('dep'); + run_make_test(undef, '', "make targ from sym"); + run_make_test(undef, '-L', "make targ from sym"); + + # 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."); + + # Add in a new link between sym and dep. Be sure it's newer than targ. + sleep(1); + rename('dep', 'dep1'); + symlink('dep1', 'dep'); + + # 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, '-L', "make targ from sym"); + + rmfiles('targ', 'dep', 'sym', 'dep1'); + + # Check handling when symlinks point to non-existent files. Without -L we + # should get an error: with -L we should use the timestamp of the symlink. + + symlink("../$dirname/dep", 'sym'); + run_make_test('targ: sym ; @echo make $@ from $<', '', + "#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'); + + + rmfiles('targ', 'sym'); + + 1; +} diff --git a/tests/scripts/options/warn-undefined-variables b/tests/scripts/options/warn-undefined-variables new file mode 100644 index 0000000..34bfaea --- /dev/null +++ b/tests/scripts/options/warn-undefined-variables @@ -0,0 +1,25 @@ +# -*-perl-*- + +$description = "Test the --warn-undefined-variables option."; + +$details = "Verify that warnings are printed for referencing undefined variables."; + +# Without --warn-undefined-variables, nothing should happen +run_make_test(' +EMPTY = +EREF = $(EMPTY) +UREF = $(UNDEFINED) + +SEREF := $(EREF) +SUREF := $(UREF) + +all: ; @echo ref $(EREF) $(UREF)', + '', 'ref'); + +# 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' +ref"); + +1; diff --git a/tests/scripts/targets/DEFAULT b/tests/scripts/targets/DEFAULT new file mode 100644 index 0000000..0cabde9 --- /dev/null +++ b/tests/scripts/targets/DEFAULT @@ -0,0 +1,53 @@ +$description = "The following test creates a makefile to override part\n" + ."of one Makefile with Another Makefile with the .DEFAULT\n" + ."rule."; + +$details = "This tests the use of the .DEFAULT special target to say that \n" + ."to remake any target that cannot be made fram the information\n" + ."in the containing makefile, make should look in another makefile\n" + ."This test gives this makefile the target bar which is not \n" + ."defined here but passes the target bar on to another makefile\n" + ."which does have the target bar defined.\n"; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo:\n"; +print MAKEFILE "\t\@echo Executing rule FOO\n\n"; +print MAKEFILE ".DEFAULT:\n"; +print MAKEFILE "\t\@\$(MAKE) -f $makefile2 \$\@ \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE "bar:\n"; +print MAKEFILE "\t\@echo Executing rule BAR\n\n"; + +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" + . "Executing rule BAR\n" + . "${make_name}[1]: Leaving directory `$pwd'\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/targets/FORCE b/tests/scripts/targets/FORCE new file mode 100644 index 0000000..eb8f251 --- /dev/null +++ b/tests/scripts/targets/FORCE @@ -0,0 +1,40 @@ +# -*-perl-*- + +$description = "The following tests rules without Commands or Dependencies."; + +$details = "If the rule ...\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".IGNORE :\n"; +print MAKEFILE "clean: FORCE\n"; +print MAKEFILE "\t$delete_command clean\n"; +print MAKEFILE "FORCE:\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +# Create a file named "clean". This is the same name as the target clean +# and tricks the target into thinking that it is up to date. (Unless you +# use the .PHONY target. +&touch("clean"); + +$answer = "$delete_command clean\n"; +&run_make_with_options($makefile,"clean",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/tests/scripts/targets/INTERMEDIATE b/tests/scripts/targets/INTERMEDIATE new file mode 100644 index 0000000..4fdd7a2 --- /dev/null +++ b/tests/scripts/targets/INTERMEDIATE @@ -0,0 +1,108 @@ +# -*-perl-*- + +$description = "Test the behaviour of the .INTERMEDIATE target."; + +$details = "\ +Test the behavior of the .INTERMEDIATE special target. +Create a makefile where a file would not normally be considered +intermediate, then specify it as .INTERMEDIATE. Build and ensure it's +deleted properly. Rebuild to ensure that it's not created if it doesn't +exist but doesn't need to be built. Change the original and ensure +that the intermediate file and the ultimate target are both rebuilt, and +that the intermediate file is again deleted. + +Try this with implicit rules and explicit rules: both should work.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +.INTERMEDIATE: foo.e bar.e + +# Implicit rule test +%.d : %.e ; cp $< $@ +%.e : %.f ; cp $< $@ + +foo.d: foo.e + +# Explicit rule test +foo.c: foo.e bar.e; cat $^ > $@ +EOF + +close(MAKEFILE); + +# TEST #0 + +&utouch(-20, 'foo.f', 'bar.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #1 + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "$make_name: `foo.d' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 + +&utouch(-10, 'foo.d'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #3 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm bar.e foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #4 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "$make_name: `foo.c' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #5 + +&utouch(-10, 'foo.c'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm bar.e foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #6 -- added for PR/1669: don't remove files mentioned on the cmd line. + +&run_make_with_options($makefile,'foo.e',&get_logfile); +$answer = "cp foo.f foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo.f', 'foo.e', 'foo.d', 'foo.c', 'bar.f', 'bar.e', 'bar.d', 'bar.c'); + +# TEST #7 -- added for PR/1423 + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); + +print MAKEFILE <<'EOF'; +all: foo +foo.a: ; touch $@ +%: %.a ; touch $@ +.INTERMEDIATE: foo.a +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, '-R', &get_logfile); +$answer = "touch foo.a\ntouch foo\nrm foo.a\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/targets/ONESHELL b/tests/scripts/targets/ONESHELL new file mode 100644 index 0000000..997423f --- /dev/null +++ b/tests/scripts/targets/ONESHELL @@ -0,0 +1,69 @@ +# -*-perl-*- + +$description = "Test the behaviour of the .ONESHELL target."; + +$details = ""; + + +# Simple + +run_make_test(q! +.ONESHELL: +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! +.ONESHELL: +all: + a=$$$$ + @-+ [ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', 'a=$$ +[ 0"$a" -eq "$$" ] || echo fail +'); + +# This time with outer prefix chars + +run_make_test(q! +.ONESHELL: +all: + @a=$$$$ + [ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', ''); + + +# This time with outer and inner prefix chars + +run_make_test(q! +.ONESHELL: +all: + @a=$$$$ + -@ +[ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', ''); + + +# Now try using a different interpreter + +run_make_test(q! +.RECIPEPREFIX = > +.ONESHELL: +SHELL = #PERL# +.SHELLFLAGS = -e +all: +> @$$a=5 +> +7; +> @y=qw(a b c); +>print "a = $$a, y = (@y)\n"; +!, + '', "a = 12, y = (a b c)\n"); + +1; diff --git a/tests/scripts/targets/PHONY b/tests/scripts/targets/PHONY new file mode 100644 index 0000000..c8e2110 --- /dev/null +++ b/tests/scripts/targets/PHONY @@ -0,0 +1,54 @@ +# -*-perl-*- + +$description = "The following tests the use of a PHONY target. It makes\n" + ."sure that the rules under a target get executed even if\n" + ."a filename of the same name of the target exists in the\n" + ."directory.\n"; + +$details = "This makefile in this test declares the target clean to be a \n" + ."PHONY target. We then create a file named \"clean\" in the \n" + ."directory. Although this file exists, the rule under the target\n" + ."clean should still execute because of it's phony status."; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".PHONY : clean \n"; +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This makefile did not clean the dir ... good\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command $example clean\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + +# Create a file named "clean". This is the same name as the target clean +# and tricks the target into thinking that it is up to date. (Unless you +# use the .PHONY target. +&touch("clean"); + +$answer = "$delete_command $example clean\n"; +&run_make_with_options($makefile,"clean",&get_logfile); + +if (-f $example) { + $test_passed = 0; +} + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/tests/scripts/targets/POSIX b/tests/scripts/targets/POSIX new file mode 100644 index 0000000..9c30e18 --- /dev/null +++ b/tests/scripts/targets/POSIX @@ -0,0 +1,33 @@ +# -*-perl-*- + +$description = "Test the behaviour of the .PHONY target."; + +$details = ""; + + +# Ensure turning on .POSIX enables the -e flag for the shell +# We can't assume the exit value of "false" because on different systems it's +# different. + +my $script = 'false; true'; +my $flags = '-ec'; +my $out = `/bin/sh $flags '$script' 2>&1`; +my $err = $? >> 8; +run_make_test(qq! +.POSIX: +all: ; \@$script +!, + '', "#MAKE#: *** [all] Error $err\n", 512); + +# User settings must override .POSIX +$flags = '-xc'; +$out = `/bin/sh $flags '$script' 2>&1`; +run_make_test(qq! +.SHELLFLAGS = $flags +.POSIX: +all: ; \@$script +!, + '', $out); + +# 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 new file mode 100644 index 0000000..c954ee9 --- /dev/null +++ b/tests/scripts/targets/SECONDARY @@ -0,0 +1,189 @@ +#! -*-perl-*- + +$description = "Test the behaviour of the .SECONDARY target."; + +$details = "\ +Test the behavior of the .SECONDARY special target. +Create a makefile where a file would not normally be considered +intermediate, then specify it as .SECONDARY. Build and note that it's +not automatically deleted. Delete the file. Rebuild to ensure that +it's not created if it doesn't exist but doesn't need to be built. +Change the original and ensure that the secondary file and the ultimate +target are both rebuilt, and that the secondary file is not deleted. + +Try this with implicit rules and explicit rules: both should work.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +.SECONDARY: foo.e + +# Implicit rule test +%.d : %.e ; cp $< $@ +%.e : %.f ; cp $< $@ + +foo.d: foo.e + +# Explicit rule test +foo.c: foo.e ; cp $< $@ +EOF + +close(MAKEFILE); + +# TEST #1 + +&utouch(-20, 'foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 + +unlink('foo.e'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "$make_name: `foo.d' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #3 + +&utouch(-10, 'foo.d'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #4 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.e foo.c\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #5 + +unlink('foo.e'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "$make_name: `foo.c' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #6 + +&utouch(-10, 'foo.c'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.c\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo.f', 'foo.e', 'foo.d', 'foo.c'); + +# TEST #7 -- test the "global" .SECONDARY, with no targets. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); + +print MAKEFILE <<'EOF'; +.SECONDARY: + +final: intermediate +intermediate: source + +final intermediate source: + echo $< > $@ +EOF + +close(MAKEFILE); + +&utouch(-10, 'source'); +touch('final'); + +&run_make_with_options($makefile2, '', &get_logfile); +$answer = "$make_name: `final' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('source', 'final', 'intermediate'); + + +# TEST #8 -- test the "global" .SECONDARY, with .PHONY. + +touch('version2'); +run_make_test(' +.PHONY: version +.SECONDARY: +version2: version ; @echo GOOD +all: version2', + 'all', 'GOOD'); + +unlink('version2'); + +# TEST #9 -- Savannah bug #15919 +# The original fix for this bug caused a new bug, shown here. + +touch(qw(1.a 2.a)); + +run_make_test(' +%.c : %.b ; cp $< $@ +%.b : %.a ; cp $< $@ +all : 1.c 2.c', '-rR -j', +'cp 1.a 1.b +cp 2.a 2.b +cp 1.b 1.c +cp 2.b 2.c +rm 1.b 2.b'); + +unlink(qw(1.a 2.a 1.c 2.c)); + +# TEST #10 -- Savannah bug #15919 +touch('test.0'); +run_make_test(' +.SECONDARY : test.1 test.2 test.3 + +test : test.4 + +%.4 : %.int %.3 ; touch $@ + +%.int : %.3 %.2 ; touch $@ + +%.3 : | %.2 ; touch $@ + +%.2 : %.1 ; touch $@ + +%.1 : %.0 ; touch $@', '-rR -j 2', +'touch test.1 +touch test.2 +touch test.3 +touch test.int +touch test.4 +rm test.int'); + +# After a touch of test.0 it should give the same output, except we don't need +# to rebuild test.3 (order-only) +sleep(1); +touch('test.0'); +run_make_test(undef, '-rR -j 2', +'touch test.1 +touch test.2 +touch test.int +touch test.4 +rm test.int'); + +# With both test.0 and test.3 updated it should still build everything except +# test.3 +sleep(1); +touch('test.0', 'test.3'); +run_make_test(undef, '-rR -j 2', +'touch test.1 +touch test.2 +touch test.int +touch test.4 +rm test.int'); + +unlink(qw(test.0 test.1 test.2 test.3 test.4)); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/targets/SILENT b/tests/scripts/targets/SILENT new file mode 100644 index 0000000..4bb0a0f --- /dev/null +++ b/tests/scripts/targets/SILENT @@ -0,0 +1,42 @@ +# -*-perl-*- + +$description = "The following tests the special target .SILENT. By simply\n" + ."mentioning this as a target, it tells make not to print\n" + ."commands before executing them."; + +$details = "This test is the same as the clean test except that it should\n" + ."not echo its command before deleting the specified file.\n"; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".SILENT : clean\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + +$answer = ""; +&run_make_with_options($makefile,"clean",&get_logfile,0); +if (-f $example) { + $test_passed = 0; +} +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/tests/scripts/targets/clean b/tests/scripts/targets/clean new file mode 100644 index 0000000..b32c976 --- /dev/null +++ b/tests/scripts/targets/clean @@ -0,0 +1,50 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to delete a \n" + ."file in the directory. It tests to see if make will \n" + ."NOT execute the command unless the rule is given in \n" + ."the make command line."; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This makefile did not clean the dir... good\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "This makefile did not clean the dir... good\n"; + +&compare_output($answer,&get_logfile(1)) || &error ("abort"); + + +$answer = "$delete_command $example\n"; +&run_make_with_options($makefile,"clean",&get_logfile,0); +if (-f $example) { + $test_passed = 0; +} +&compare_output($answer,&get_logfile(1)) || &error ("abort"); + +1; + + + + + + + + + diff --git a/tests/scripts/test_template b/tests/scripts/test_template new file mode 100644 index 0000000..3fd3f95 --- /dev/null +++ b/tests/scripts/test_template @@ -0,0 +1,29 @@ +# -*-perl-*- + +$description = "<FILL IN SHORT DESCRIPTION HERE>"; +$details = "<FILL IN DETAILS OF HOW YOU TEST WHAT YOU SAY YOU ARE TESTING>"; + +# Run a make test. See the documentation of run_make_test() in +# run_make_tests.pl, but briefly the first argument is a string with the +# contents of a makefile to be tested, the second is a string containing the +# arguments to be passed to the make invocation, the third is a string +# containing the expected output. The fourth is the expected exit code for +# make. If not specified, it's assumed that the make program should succeed +# (exit with 0). + +run_make_test('Your test makefile goes here', + 'Arguments to pass to make go here', + 'Expected output from the invocation goes here'); + +# There are various special tokens, options, etc. See the full documentation +# in run_make_tests.pl. + + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/variables/CURDIR b/tests/scripts/variables/CURDIR new file mode 100644 index 0000000..ee7cacb --- /dev/null +++ b/tests/scripts/variables/CURDIR @@ -0,0 +1,20 @@ +# -*-perl-*- + +$description = "This tests the CURDIR varaible."; + +$details = "Echo CURDIR both with and without -C. Also ensure overrides work."; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE "all: ; \@echo \$(CURDIR)\n"; +close(MAKEFILE); + + +# TEST #1 +# ------- + +&run_make_with_options($makefile,"",&get_logfile); +$answer = "$pwd\n"; +&compare_output($answer,&get_logfile(1)); + + +1; diff --git a/tests/scripts/variables/DEFAULT_GOAL b/tests/scripts/variables/DEFAULT_GOAL new file mode 100644 index 0000000..1c06506 --- /dev/null +++ b/tests/scripts/variables/DEFAULT_GOAL @@ -0,0 +1,87 @@ +# -*-perl-*- +$description = "Test the .DEFAULT_GOAL special variable."; + +$details = ""; + + +# Test #1: basic logic. +# +run_make_test(' +# Basics. +# +foo: ; @: + +ifneq ($(.DEFAULT_GOAL),foo) +$(error ) +endif + +# Reset to empty. +# +.DEFAULT_GOAL := + +bar: ; @: + +ifneq ($(.DEFAULT_GOAL),bar) +$(error ) +endif + +# Change to a different goal. +# + +.DEFAULT_GOAL := baz + +baz: ; @echo $@ +', +'', +'baz'); + + +# Test #2: unknown goal. +# +run_make_test(' +.DEFAULT_GOAL = foo +', +'', +'#MAKE#: *** No rule to make target `foo\'. Stop.', +512); + + +# Test #3: more than one goal. +# +run_make_test(' +.DEFAULT_GOAL := foo bar +', +'', +'#MAKE#: *** .DEFAULT_GOAL contains more than one target. Stop.', +512); + + +# Test #4: Savannah bug #12226. +# +run_make_test(' +define rule +foo: ; @echo $$@ +endef + +define make-rule +$(eval $(rule)) +endef + +$(call make-rule) + +', +'', +'foo'); + +# TEST #5: .DEFAULT_GOAL containing just whitespace (Savannah bug #25697) + +run_make_test(' +N = +.DEFAULT_GOAL = $N $N # Just whitespace + +foo: ; @echo "boo" +', + '', "#MAKE#: *** No targets. Stop.\n", 512); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/variables/INCLUDE_DIRS b/tests/scripts/variables/INCLUDE_DIRS new file mode 100644 index 0000000..c9662e9 --- /dev/null +++ b/tests/scripts/variables/INCLUDE_DIRS @@ -0,0 +1,46 @@ +# -*-perl-*- +$description = "Test the .INCLUDE_DIRS special variable."; + +$details = ""; + +use Cwd; + +$dir = cwd; +$dir =~ s,.*/([^/]+)$,../$1,; + +# Test #1: The content of .INCLUDE_DIRS depends on the platform for which +# make was built. What we know for sure is that it shouldn't be +# empty. +# +run_make_test(' +ifeq ($(.INCLUDE_DIRS),) +$(warning .INCLUDE_DIRS is empty) +endif + +.PHONY: all +all:;@: +', +'', +''); + + +# Test #2: Make sure -I paths end up in .INCLUDE_DIRS. +# +run_make_test(' +ifeq ($(dir),) +$(warning dir is empty) +endif + +ifeq ($(filter $(dir),$(.INCLUDE_DIRS)),) +$(warning .INCLUDE_DIRS does not contain $(dir)) +endif + +.PHONY: all +all:;@: +', +"-I$dir dir=$dir", +''); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/variables/LIBPATTERNS b/tests/scripts/variables/LIBPATTERNS new file mode 100644 index 0000000..826f2fa --- /dev/null +++ b/tests/scripts/variables/LIBPATTERNS @@ -0,0 +1,38 @@ +# -*-perl-*- + +$description = "Test .LIBPATTERNS special variable."; + +$details = ""; + +# TEST 0: basics + +touch('mtest_foo.a'); + +run_make_test(' +.LIBPATTERNS = mtest_%.a +all: -lfoo ; @echo "build $@ from $<" +', + '', "build all from mtest_foo.a\n"); + +# TEST 1: Handle elements that are not patterns. + +run_make_test(' +.LIBPATTERNS = mtest_foo.a mtest_%.a +all: -lfoo ; @echo "build $@ from $<" +', + '', "#MAKE#: .LIBPATTERNS element `mtest_foo.a' is not a pattern +build all from mtest_foo.a\n"); + +# TEST 2: target-specific override + +# Uncomment this when we add support, see Savannah bug #25703 +# run_make_test(' +# .LIBPATTERNS = mbad_%.a +# all: .LIBPATTERNS += mtest_%.a +# all: -lfoo ; @echo "build $@ from $<" +# ', +# '', "build all from mtest_foo.a\n"); + +unlink('mtest_foo.a'); + +1; diff --git a/tests/scripts/variables/MAKE b/tests/scripts/variables/MAKE new file mode 100644 index 0000000..d1081da --- /dev/null +++ b/tests/scripts/variables/MAKE @@ -0,0 +1,24 @@ +# -*-perl-*- + +$description = "Test proper behavior of the MAKE variable"; + +$details = "DETAILS"; + +run_make_test(q! +TMP := $(MAKE) +MAKE := $(subst X=$(X),,$(MAKE)) +all: + @echo $(TMP) + $(MAKE) -f #MAKEFILE# foo + +foo: + @echo $(MAKE) +!, + '', + "#MAKEPATH#\n#MAKEPATH# -f #MAKEFILE# foo\n" + . "#MAKE#[1]: Entering directory `#PWD#'\n" + . "#MAKEPATH#\n#MAKE#[1]: Leaving directory `#PWD#'\n"); + +rmfiles("foo"); + +1; diff --git a/tests/scripts/variables/MAKECMDGOALS b/tests/scripts/variables/MAKECMDGOALS new file mode 100644 index 0000000..879283b --- /dev/null +++ b/tests/scripts/variables/MAKECMDGOALS @@ -0,0 +1,52 @@ +# -*-perl-*- + +$description = "Test the MAKECMDGOALS variable."; + +$details = "\ +We construct a makefile with various targets, all of which print out +\$(MAKECMDGOALS), then call it different ways."; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE "\ +.DEFAULT all: + \@echo \$(MAKECMDGOALS) +"; +close(MAKEFILE); + +# TEST #1 + +&run_make_with_options($makefile, + "", + &get_logfile, + 0); +$answer = "\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #2 + +&run_make_with_options($makefile, + "all", + &get_logfile, + 0); +$answer = "all\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 + +&run_make_with_options($makefile, + "foo bar baz yaz", + &get_logfile, + 0); +$answer = "foo bar baz yaz\nfoo bar baz yaz\nfoo bar baz yaz\nfoo bar baz yaz\n"; +&compare_output($answer,&get_logfile(1)); + + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/variables/MAKEFILES b/tests/scripts/variables/MAKEFILES new file mode 100644 index 0000000..b23da8e --- /dev/null +++ b/tests/scripts/variables/MAKEFILES @@ -0,0 +1,53 @@ +# -*-perl-*- + +$description = "Test the MAKEFILES variable."; + +$makefile2 = &get_tmpfile; +$makefile3 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE 'all: ; @echo DEFAULT RULE: M2=$(M2) M3=$(M3)', "\n"; +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); +print MAKEFILE <<EOF; +M2 = m2 +NDEF: ; \@echo RULE FROM MAKEFILE 2 +EOF +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile3"); +print MAKEFILE <<EOF; +M3 = m3 +NDEF3: ; \@echo RULE FROM MAKEFILE 3 +EOF +close(MAKEFILE); + + +&run_make_with_options($makefile, "MAKEFILES='$makefile2 $makefile3'", + &get_logfile); +$answer = "DEFAULT RULE: M2=m2 M3=m3\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST 2: Verify that included makefiles don't set the default goal. +# See Savannah bug #13401. + +create_file('xx-inc.mk', ' +include_goal: ; @echo $@ +include xx-ind.mk +'); + +create_file('xx-ind.mk', ' +indirect_goal: ; @echo $@ +'); + +run_make_test(q! +top: ; @echo $@ +!, + 'MAKEFILES=xx-inc.mk', "top\n"); + +unlink(qw(xx-inc.mk xx-ind.mk)); + +1; diff --git a/tests/scripts/variables/MAKEFLAGS b/tests/scripts/variables/MAKEFLAGS new file mode 100644 index 0000000..0b567e8 --- /dev/null +++ b/tests/scripts/variables/MAKEFLAGS @@ -0,0 +1,43 @@ +# -*-perl-*- + +$description = "Test proper behavior of MAKEFLAGS"; + +$details = "DETAILS"; + +# Normal flags aren't prefixed with "-" +run_make_test(q! +all: ; @echo $(MAKEFLAGS) +!, + '-e -r -R', 'Rre'); + +# Long arguments mean everything is prefixed with "-" +run_make_test(q! +all: ; @echo $(MAKEFLAGS) +!, + '--no-print-directory -e -r -R', '--no-print-directory -Rre'); + + +if ($all_tests) { + # 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)' + @$(MAKE) -f #MAKEFILE# print +print: + @echo '$@: MAKEFLAGS=$(MAKEFLAGS)' + @echo $(MSG) +.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'); +} + +1; diff --git a/tests/scripts/variables/MAKELEVEL b/tests/scripts/variables/MAKELEVEL new file mode 100644 index 0000000..96a4e74 --- /dev/null +++ b/tests/scripts/variables/MAKELEVEL @@ -0,0 +1,33 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test +makelevels in Make. It prints \$(MAKELEVEL) and then +prints the environment variable MAKELEVEL"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOF; +all: +\t\@echo MAKELEVEL is \$(MAKELEVEL) +\techo \$\$MAKELEVEL +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +# RUN MAKE + +&run_make_with_options($makefile,"",&get_logfile); + +# SET ANSWER + +$answer = "MAKELEVEL is 0\necho \$MAKELEVEL\n1\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/variables/MAKE_RESTARTS b/tests/scripts/variables/MAKE_RESTARTS new file mode 100644 index 0000000..53ab738 --- /dev/null +++ b/tests/scripts/variables/MAKE_RESTARTS @@ -0,0 +1,62 @@ +# -*-perl-*- + +$description = "Test the MAKE_RESTARTS variable."; + +# Test basic capability + +run_make_test(' +all: ; @: +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @touch $@ +', + '', 'MAKE_RESTARTS= +#MAKEFILE#:4: foo.x: No such file or directory +MAKE_RESTARTS=1'); + +rmfiles('foo.x'); + +# Test multiple restarts + +run_make_test(' +all: ; @: +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @echo "include bar.x" > $@ +bar.x: ; @touch $@ +', + '', 'MAKE_RESTARTS= +#MAKEFILE#:4: foo.x: No such file or directory +MAKE_RESTARTS=1 +foo.x:1: bar.x: No such file or directory +MAKE_RESTARTS=2'); + +rmfiles('foo.x', 'bar.x'); + +# Test multiple restarts and make sure the variable is cleaned up + +run_make_test(' +recurse: + @echo recurse MAKE_RESTARTS=$$MAKE_RESTARTS + @$(MAKE) -f #MAKEFILE# all +all: + @echo all MAKE_RESTARTS=$$MAKE_RESTARTS +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @echo "include bar.x" > $@ +bar.x: ; @touch $@ +', + '', "MAKE_RESTARTS= +#MAKEFILE#:8: foo.x: No such file or directory +MAKE_RESTARTS=1 +foo.x:1: bar.x: No such file or directory +MAKE_RESTARTS=2 +recurse MAKE_RESTARTS= +MAKE_RESTARTS= +#MAKE#[1]: Entering directory `#PWD#' +all MAKE_RESTARTS= +#MAKE#[1]: Leaving directory `#PWD#'"); + +rmfiles('foo.x', 'bar.x'); + +1; diff --git a/tests/scripts/variables/MFILE_LIST b/tests/scripts/variables/MFILE_LIST new file mode 100644 index 0000000..076e42d --- /dev/null +++ b/tests/scripts/variables/MFILE_LIST @@ -0,0 +1,30 @@ +# -*-perl-*- + +$description = "Test the MAKEFILE_LIST variable."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE <<EOF; +m1 := \$(MAKEFILE_LIST) +include $makefile2 +m3 := \$(MAKEFILE_LIST) + +all: +\t\@echo \$(m1) +\t\@echo \$(m2) +\t\@echo \$(m3) +EOF +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); +print MAKEFILE "m2 := \$(MAKEFILE_LIST)\n"; +close(MAKEFILE); + + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "$makefile\n$makefile $makefile2\n$makefile $makefile2\n"; +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/variables/SHELL b/tests/scripts/variables/SHELL new file mode 100644 index 0000000..7b7e7fe --- /dev/null +++ b/tests/scripts/variables/SHELL @@ -0,0 +1,86 @@ +# -*-perl-*- + +$description = "Test proper handling of SHELL."; + +# Find the default value when SHELL is not set. On UNIX it will be /bin/sh, +# but on other platforms who knows? +resetENV(); +delete $ENV{SHELL}; +$mshell = `echo 'all:;\@echo \$(SHELL)' | $make_path -f-`; +chop $mshell; + +# According to POSIX, the value of SHELL in the environment has no impact on +# the value in the makefile. +# Note %extraENV takes precedence over the default value for the shell. + +$extraENV{SHELL} = '/dev/null'; +run_make_test('all:;@echo "$(SHELL)"', '', $mshell); + +# According to POSIX, any value of SHELL set in the makefile should _NOT_ be +# exported to the subshell! I wanted to set SHELL to be $^X (perl) in the +# makefile, but make runs $(SHELL) -c 'commandline' and that doesn't work at +# all when $(SHELL) is perl :-/. So, we just add an extra initial /./ which +# works well on UNIX and seems to work OK on at least some non-UNIX systems. + +$extraENV{SHELL} = $mshell; + +run_make_test("SHELL := /./$mshell\n".' +all:;@echo "$(SHELL) $$SHELL" +', '', "/./$mshell $mshell"); + +# As a GNU make extension, if make's SHELL variable is explicitly exported, +# then we really _DO_ export it. + +$extraENV{SHELL} = $mshell; + +run_make_test("export SHELL := /./$mshell\n".' +all:;@echo "$(SHELL) $$SHELL" +', '', "/./$mshell /./$mshell"); + + +# Test out setting of SHELL, both exported and not, as a target-specific +# variable. + +$extraENV{SHELL} = $mshell; + +run_make_test("all: SHELL := /./$mshell\n".' +all:;@echo "$(SHELL) $$SHELL" +', '', "/./$mshell $mshell"); + +$extraENV{SHELL} = $mshell; + +run_make_test(" +SHELL := /././$mshell +one: two +two: export SHELL := /./$mshell\n".' +one two:;@echo "$@: $(SHELL) $$SHELL" +', '', "two: /./$mshell /./$mshell\none: /././$mshell $mshell\n"); + +# Test .SHELLFLAGS + +# We don't know the output here: on Solaris for example, every line printed +# by the shell in -x mode has a trailing space (!!) +my $script = 'true; true'; +my $flags = '-xc'; +my $out = `/bin/sh $flags '$script' 2>&1`; + +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'; +$flags = '-xec'; +$out = `/bin/sh $flags '$script' 2>&1`; +my $err = $? >> 8; + +run_make_test(qq! +.SHELLFLAGS = $flags +all: ; \@$script +!, + '', "$out#MAKE#: *** [all] Error $err\n", 512); + +1; diff --git a/tests/scripts/variables/automatic b/tests/scripts/variables/automatic new file mode 100644 index 0000000..33c482d --- /dev/null +++ b/tests/scripts/variables/automatic @@ -0,0 +1,122 @@ +# -*-perl-*- + +$description = "Test automatic variable setting."; + +$details = ""; + +use Cwd; + +$dir = cwd; +$dir =~ s,.*/([^/]+)$,../$1,; + +open(MAKEFILE, "> $makefile"); +print MAKEFILE "dir = $dir\n"; +print MAKEFILE <<'EOF'; +.SUFFIXES: +.SUFFIXES: .x .y .z +$(dir)/foo.x : baz.z $(dir)/bar.y baz.z + @echo '$$@ = $@, $$(@D) = $(@D), $$(@F) = $(@F)' + @echo '$$* = $*, $$(*D) = $(*D), $$(*F) = $(*F)' + @echo '$$< = $<, $$(<D) = $(<D), $$(<F) = $(<F)' + @echo '$$^ = $^, $$(^D) = $(^D), $$(^F) = $(^F)' + @echo '$$+ = $+, $$(+D) = $(+D), $$(+F) = $(+F)' + @echo '$$? = $?, $$(?D) = $(?D), $$(?F) = $(?F)' + touch $@ + +$(dir)/bar.y baz.z : ; touch $@ +EOF +close(MAKEFILE); + +# TEST #0 -- simple test +# ------- + +# Touch these into the past +&utouch(-10, qw(foo.x baz.z)); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "touch $dir/bar.y +\$\@ = $dir/foo.x, \$(\@D) = $dir, \$(\@F) = foo.x +\$* = $dir/foo, \$(*D) = $dir, \$(*F) = foo +\$< = baz.z, \$(<D) = ., \$(<F) = baz.z +\$^ = baz.z $dir/bar.y, \$(^D) = . $dir, \$(^F) = baz.z bar.y +\$+ = baz.z $dir/bar.y baz.z, \$(+D) = . $dir ., \$(+F) = baz.z bar.y baz.z +\$? = $dir/bar.y, \$(?D) = $dir, \$(?F) = bar.y +touch $dir/foo.x\n"; +&compare_output($answer, &get_logfile(1)); + +unlink(qw(foo.x bar.y baz.z)); + +# TEST #1 -- test the SysV emulation of $$@ etc. +# ------- + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); +print MAKEFILE "dir = $dir\n"; +print MAKEFILE <<'EOF'; +.SECONDEXPANSION: +.SUFFIXES: +.DEFAULT: ; @echo '$@' + +$(dir)/foo $(dir)/bar: $@.x $$@.x $$$@.x $$$$@.x $$(@D).x $$(@F).x + +$(dir)/x.z $(dir)/y.z: $(dir)/%.z : $@.% $$@.% $$$@.% $$$$@.% $$(@D).% $$(@F).% + +$(dir)/biz: $$(@).x $${@}.x $${@D}.x $${@F}.x +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, "$dir/foo $dir/bar", &get_logfile); +$answer = ".x\n$dir/foo.x\nx\n\$@.x\n$dir.x\nfoo.x\n$dir/bar.x\nbar.x\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile2, "$dir/x.z $dir/y.z", &get_logfile); +$answer = ".x\n$dir/x.z.x\nx\n\$@.x\n$dir.x\nx.z.x\n.y\n$dir/y.z.y\n\y\n\$@.y\n$dir.y\ny.z.y\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile2, "$dir/biz", &get_logfile); +$answer = "$dir/biz.x\n$dir.x\nbiz.x\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 -- test for Savannah bug #12320. +# +run_make_test(' +.SUFFIXES: .b .src + +mbr.b: mbr.src + @echo $* + +mbr.src: ; @:', + '', + 'mbr'); + +# TEST #3 -- test for Savannah bug #8154 +# Make sure that nonexistent prerequisites are listed in $?, since they are +# considered reasons for the target to be rebuilt. +# +# See also Savannah bugs #16002 and #16051. + +touch('foo'); + +run_make_test(' +foo: bar ; @echo "\$$? = $?" +bar: ;', + '', + '$? = bar'); + +unlink('foo'); + +# TEST #4: ensure prereq ordering is correct when the commmand target has none +# See Savannah bug #21198 + +run_make_test(' +all : A B +all : ; @echo $@ -- $^ -- $< +all : C D +all : E F +A B C D E F G H : ; @: +', + '', "all -- A B C D E F -- A\n"); + +1; diff --git a/tests/scripts/variables/define b/tests/scripts/variables/define new file mode 100644 index 0000000..f91519e --- /dev/null +++ b/tests/scripts/variables/define @@ -0,0 +1,234 @@ +# -*-perl-*- + +$description = "Test define/endef variable assignments."; + +$details = ""; + +# TEST 0: old-style basic define/endef + +run_make_test(' +define multi +@echo hi +echo there +endef + +all: ; $(multi) +', + '', "hi\necho there\nthere\n"); + +# TEST 1: Various new-style define/endef + +run_make_test(' +FOO = foo + +define multi = +echo hi +@echo $(FOO) +endef # this is the end + +define simple := +@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) + $(append) + $(cond) +', + '', "echo hi\nhi\nthere\nfoo\na\nb\nfirst\n"); + +# TEST 2: define in true section of conditional (containing conditional) + +run_make_test(' +FOO = foo +NAME = def +def = +ifdef BOGUS + define $(subst e,e,$(NAME)) = + ifeq (1,1) + FOO = bar + endif + endef +endif + +$(eval $(def)) +all: ; @echo $(FOO) +', + 'BOGUS=1', "bar\n"); + +# TEST 3: define in false section of conditional (containing conditional) + +run_make_test(undef, '', "foo\n"); + +# TEST 4: nested define (supported?) + +run_make_test(' +define outer + define inner + A = B + endef +endef + +$(eval $(outer)) + +outer: ; @echo $(inner) +', + '', "A = B\n"); + +# TEST 5: NEGATIVE: Missing variable name + +run_make_test(' +NAME = +define $(NAME) = +ouch +endef +all: ; @echo ouch +', + '', "#MAKEFILE#:3: *** empty variable name. Stop.\n", 512); + +# TEST 6: NEGATIVE: extra text after define + +run_make_test(' +NAME = +define NAME = $(NAME) +ouch +endef +all: ; @echo ok +', + '', "#MAKEFILE#:3: extraneous text after `define' directive\nok\n"); + +# TEST 7: NEGATIVE: extra text after endef + +run_make_test(' +NAME = +define NAME = +ouch +endef $(NAME) +all: ; @echo ok +', + '', "#MAKEFILE#:5: extraneous text after `endef' directive\nok\n"); + +# TEST 8: NEGATIVE: missing endef + +run_make_test(' +NAME = +all: ; @echo ok +define NAME = +ouch +endef$(NAME) +', + '', "#MAKEFILE#:4: *** missing `endef', unterminated `define'. Stop.\n", 512); + +# ------------------------- +# Make sure that prefix characters apply properly to define/endef values. +# +# There's a bit of oddness here if you try to use a variable to hold the +# prefix character for a define. Even though something like this: +# +# define foo +# echo bar +# endef +# +# all: ; $(V)$(foo) +# +# (where V=@) can be seen by the user to be obviously different than this: +# +# define foo +# $(V)echo bar +# endef +# +# all: ; $(foo) +# +# and the user thinks it should behave the same as when the "@" is literal +# instead of in a variable, that can't happen because by the time make +# expands the variables for the command line and sees it begins with a "@" it +# can't know anymore whether the prefix character came before the variable +# reference or was included in the first line of the variable reference. + +# TEST #5 +# ------- + +run_make_test(' +define FOO +$(V1)echo hello +$(V2)echo world +endef +all: ; @$(FOO) +', '', 'hello +world'); + +# TEST #6 +# ------- + +run_make_test(undef, 'V1=@ V2=@', 'hello +world'); + +# TEST #7 +# ------- + +run_make_test(' +define FOO +$(V1)echo hello +$(V2)echo world +endef +all: ; $(FOO) +', 'V1=@', 'hello +echo world +world'); + +# TEST #8 +# ------- + +run_make_test(undef, 'V2=@', 'echo hello +hello +world'); + +# TEST #9 +# ------- + +run_make_test(undef, 'V1=@ V2=@', 'hello +world'); + +# TEST #10 +# ------- +# Test the basics; a "@" internally to the variable applies to only one line. +# A "@" before the variable applies to the entire variable. + +run_make_test(' +define FOO +@echo hello +echo world +endef +define BAR +echo hello +echo world +endef + +all: foo bar +foo: ; $(FOO) +bar: ; @$(BAR) +', '', 'hello +echo world +world +hello +world +'); + +1; diff --git a/tests/scripts/variables/flavors b/tests/scripts/variables/flavors new file mode 100644 index 0000000..92feed6 --- /dev/null +++ b/tests/scripts/variables/flavors @@ -0,0 +1,76 @@ +# -*-perl-*- + +$description = "Test various flavors of make variable setting."; + +$details = ""; + +# TEST 0: Recursive + +run_make_test(' +ugh = Goodbye +foo = $(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello\n"); + +# TEST 1: Simple + +run_make_test(' +bar = Goodbye +foo := $(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Goodbye\n"); + +# TEST 2: Append to recursive + +run_make_test(' +foo = Hello +ugh = Goodbye +foo += $(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello Hello\n"); + +# TEST 3: Append to simple + +run_make_test(' +foo := Hello +ugh = Goodbye +bar = ${ugh} +foo += $(bar) +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello Goodbye\n"); + +# TEST 4: Conditional pre-set + +run_make_test(' +foo = Hello +ugh = Goodbye +bar = ${ugh} +foo ?= $(bar) +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello\n"); + +# TEST 5: Conditional unset + +run_make_test(' +ugh = Goodbye +bar = ${ugh} +foo ?= $(bar) +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello\n"); + +1; diff --git a/tests/scripts/variables/negative b/tests/scripts/variables/negative new file mode 100644 index 0000000..16a72b8 --- /dev/null +++ b/tests/scripts/variables/negative @@ -0,0 +1,46 @@ +# -*-perl-*- + +$description = "Run some negative tests (things that should fail)."; + +# TEST #0 +# Check that non-terminated variable references are detected (and +# reported using the best filename/lineno info +run_make_test(' +foo = bar +x = $(foo +y = $x + +all: ; @echo $y +', + '', '#MAKEFILE#:3: *** unterminated variable reference. Stop.', + 512); + +# TEST #1 +# Bogus variable value passed on the command line. +run_make_test(undef, + 'x=\$\(other', + '#MAKEFILE#:4: *** unterminated variable reference. Stop.', + 512); + +# TEST #2 +# Again, but this time while reading the makefile. +run_make_test(' +foo = bar +x = $(foo +y = $x + +z := $y + +all: ; @echo $y +', + '', '#MAKEFILE#:3: *** unterminated variable reference. Stop.', + 512); + +# TEST #3 +# Bogus variable value passed on the command line. +run_make_test(undef, + 'x=\$\(other', + '#MAKEFILE#:4: *** unterminated variable reference. Stop.', + 512); + +1; diff --git a/tests/scripts/variables/private b/tests/scripts/variables/private new file mode 100644 index 0000000..b4baf5f --- /dev/null +++ b/tests/scripts/variables/private @@ -0,0 +1,78 @@ +# -*-perl-*- + +$description = "Test 'private' variables."; + +$details = ""; + +# 1: Simple verification that private variables are not inherited +&run_make_test(' +a: +F = g +a: F = a +b: private F = b + +a b c: ; @echo $@: F=$(F) +a: b +b: c +', + '', "c: F=a\nb: F=b\na: F=a\n"); + +# 2: Again, but this time we start with "b" so "a"'s variable is not in scope +&run_make_test(undef, 'b', "c: F=g\nb: F=b\n"); + +# 3: Verification with pattern-specific variables +&run_make_test(' +t.a: + +F1 = g +F2 = g +%.a: private F1 = a +%.a: F2 = a + +t.a t.b: ; @echo $@: F1=$(F1) / F2=$(F2) +t.a: t.b +', + '', "t.b: F1=g / F2=a\nt.a: F1=a / F2=a\n"); + +# 4: Test private global variables +&run_make_test(' +a: +private F = g +G := $(F) +a: +b: F = b + +a b: ; @echo $@: F=$(F) / G=$(G) +a: b +', + '', "b: F=b / G=g\na: F= / G=g\n"); + +# 5: Multiple conditions on the same variable. Test export. +delete $ENV{'_X'}; +&run_make_test(' +_X = x +a: export override private _X = a +a: ; @echo _X=$(_X) / _X=$$_X +', + '', "_X=a / _X=a"); + +# 6: Test override. +&run_make_test(undef, '_X=c', "_X=a / _X=a\n"); + +# 7: Ensure keywords still work as targets +&run_make_test(' +a: export override private foo bar +foo bar export override private: ; @echo $@ +', + '', "export\noverride\nprivate\nfoo\nbar\n"); + +# 8: Ensure keywords still work as variables +&run_make_test(' +private = g +a: private = a +a: b +a b: ; @echo $@=$(private) +', + '', "b=a\na=a\n"); + +1; diff --git a/tests/scripts/variables/special b/tests/scripts/variables/special new file mode 100644 index 0000000..a1e15c2 --- /dev/null +++ b/tests/scripts/variables/special @@ -0,0 +1,117 @@ +# -*-perl-*- + +$description = "Test special GNU make variables."; + +$details = ""; + +&run_make_test(' + +X1 := $(sort $(filter FOO BAR,$(.VARIABLES))) + +FOO := foo + +X2 := $(sort $(filter FOO BAR,$(.VARIABLES))) + +BAR := bar + +all: + @echo X1 = $(X1) + @echo X2 = $(X2) + @echo LAST = $(sort $(filter FOO BAR,$(.VARIABLES))) +', + '', "X1 =\nX2 = FOO\nLAST = BAR FOO\n"); + + + +# $makefile2 = &get_tmpfile; +# open(MAKEFILE, "> $makefile2"); + +# print MAKEFILE <<'EOF'; + +# X1 := $(sort $(.TARGETS)) + +# all: foo +# @echo X1 = $(X1) +# @echo X2 = $(X2) +# @echo LAST = $(sort $(.TARGETS)) + +# X2 := $(sort $(.TARGETS)) + +# foo: + +# EOF + +# close(MAKEFILE); + +# # TEST #2 +# # ------- + +# &run_make_with_options($makefile2, "", &get_logfile); +# $answer = "X1 =\nX2 = all\nLAST = all foo\n"; +# &compare_output($answer, &get_logfile(1)); + +# Test the .RECIPEPREFIX variable +&run_make_test(' +define foo +: foo-one \ +foo-two +: foo-three + : foo-four +endef + +orig: ; : orig-one + : orig-two \ +orig-three \ + orig-four \ + orig-five \\\\ + : orig-six + $(foo) + +.RECIPEPREFIX = > +test: ; : test-one +>: test-two \ +test-three \ +>test-four \ +> test-five \\\\ +>: test-six +>$(foo) + +.RECIPEPREFIX = +reset: ; : reset-one + : reset-two \ +reset-three \ + reset-four \ + reset-five \\\\ + : reset-six + $(foo) +', + 'orig test reset', + ': orig-one +: orig-two \ +orig-three \ +orig-four \ + orig-five \\\\ +: orig-six +: foo-one foo-two +: foo-three +: foo-four +: test-one +: test-two \ +test-three \ +test-four \ + test-five \\\\ +: test-six +: foo-one foo-two +: foo-three +: foo-four +: reset-one +: reset-two \ +reset-three \ +reset-four \ + reset-five \\\\ +: reset-six +: foo-one foo-two +: foo-three +: foo-four'); + +1; diff --git a/tests/scripts/variables/undefine b/tests/scripts/variables/undefine new file mode 100644 index 0000000..38707b8 --- /dev/null +++ b/tests/scripts/variables/undefine @@ -0,0 +1,73 @@ +# -*-perl-*- + +$description = "Test variable undefine."; + +$details = ""; + +# TEST 0: basic undefine functionality + +run_make_test(' +a = a +b := b +define c +c +endef + +$(info $(flavor a) $(flavor b) $(flavor c)) + +n := b + +undefine a +undefine $n +undefine c + +$(info $(flavor a) $(flavor b) $(flavor c)) + + +all: ;@: +', +'', "recursive simple recursive\nundefined undefined undefined"); + + +# TEST 1: override + +run_make_test(' +undefine a +override undefine b + +$(info $(flavor a) $(flavor b)) + + +all: ;@: +', +'a=a b=b', "recursive undefined"); + +1; + +# TEST 2: undefine in eval (make sure we undefine from the global var set) + +run_make_test(' +define undef +$(eval undefine $$1) +endef + +a := a +$(call undef,a) +$(info $(flavor a)) + + +all: ;@: +', +'', "undefined"); + + +# TEST 3: Missing variable name + +run_make_test(' +a = +undefine $a +all: ;@echo ouch +', +'', "#MAKEFILE#:3: *** empty variable name. Stop.\n", 512); + +1; |