diff options
Diffstat (limited to 'tests/scripts/features')
30 files changed, 3288 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; | 
