| # -*-perl-*- | |
| $description = "This test is about grouped multiple targets indicated by &:"; | |
| $details = "Here we test for requirements like\n" | |
| ."- if multiple such targets are updated, the recipe is run once\n" | |
| ."- parsing issues related to the &: syntax itself\n"; | |
| # Parsing: &: allowed without any targets. | |
| run_make_test(q{ | |
| .PHONY: all | |
| &:; | |
| all: ;@printf '' | |
| }, | |
| '', ""); | |
| # Parsing: &: works not preceded by whitespace. | |
| run_make_test(q{ | |
| foo&:;@echo foo | |
| }, | |
| 'foo', "foo"); | |
| # Ordinary rule runs recipe four times for t1 t2 t3 t4. | |
| # Grouped target rule runs recipe once; others are considered updated. | |
| run_make_test(q{ | |
| .PHONY: t1 t2 t3 t4 g1 g2 g3 g4 | |
| t1 t2 t3 t4: ; @echo $@ | |
| g1 g2 g3 g4 &: ; @echo $@ | |
| }, | |
| 't1 t2 t3 t4 g1 g2 g3 g4', | |
| "t1\n" | |
| ."t2\n" | |
| ."t3\n" | |
| ."t4\n" | |
| ."g1\n" | |
| ."#MAKE#: Nothing to be done for 'g2'.\n" | |
| ."#MAKE#: Nothing to be done for 'g3'.\n" | |
| ."#MAKE#: Nothing to be done for 'g4'."); | |
| # Similar to previous test, but targets come from m1 phony | |
| # rather than from the command line. We don't see "Nothing to | |
| # be done for" messages. Also, note reversed order g4 g3 ... | |
| # Thus the auto variable $@ is "g4" when that rule fires. | |
| run_make_test(q{ | |
| .PHONY: m1 t1 t2 t3 t4 g1 g2 g3 g4 | |
| m1: t1 t2 t3 t4 g4 g3 g2 g1 | |
| t1 t2 t3 t4: ; @echo $@ | |
| g1 g2 g3 g4&: ; @echo $@ | |
| }, | |
| '', | |
| "t1\nt2\nt3\nt4\ng4"); | |
| # Set a grouped target recipe for existing targets | |
| run_make_test(q{ | |
| .PHONY: M a b | |
| M: a b | |
| a: | |
| a b&: ; @echo Y | |
| b: | |
| }, | |
| '', | |
| "Y"); | |
| # grouped targets require a recipe | |
| run_make_test(q{ | |
| .PHONY: M a b | |
| M: a b | |
| a b&: | |
| }, | |
| '', | |
| "#MAKEFILE#:4: *** grouped targets must provide a recipe. Stop.", 512); | |
| # Pattern rules use grouped targets anyway so it's a no-op | |
| run_make_test(q{ | |
| .PHONY: M | |
| M: a.q b.q | |
| a.% b.%&: ; @echo Y | |
| }, | |
| '', | |
| "Y"); | |
| # Double-colon grouped target rules. | |
| run_make_test(q{ | |
| .PHONY: M a b c d e f g h | |
| M: a b | |
| a b c&:: ; @echo X | |
| c d e&:: ; @echo Y | |
| f g h&:: ; @echo Z | |
| }, | |
| '', | |
| "X"); | |
| run_make_test(q{ | |
| .PHONY: M a b c d e f g h | |
| M: c | |
| a b c&:: ; @echo X | |
| c d e&:: ; @echo Y | |
| f g h&:: ; @echo Z | |
| }, | |
| '', | |
| "X\nY"); | |
| run_make_test(q{ | |
| .PHONY: M a b c d e f g h | |
| M: a b c d e | |
| a b c&:: ; @echo X | |
| c d e&:: ; @echo Y | |
| f g h&:: ; @echo Z | |
| }, | |
| '', | |
| "X\nY"); | |
| run_make_test(q{ | |
| .PHONY: M a b c d e f g h | |
| M: d e | |
| a b c&:: ; @echo X | |
| c d e&:: ; @echo Y | |
| f g h&:: ; @echo Z | |
| }, | |
| '', | |
| "Y"); | |
| run_make_test(q{ | |
| .PHONY: M a b c d e f g h | |
| M: f g h | |
| a b c&:: ; @echo X | |
| c d e&:: ; @echo Y | |
| f g h&:: ; @echo Z | |
| }, | |
| '', | |
| "Z"); | |
| # sv 60188. | |
| # Test that a file explicitly mentioned by the user and made by an implicit | |
| # rule is not considered intermediate. | |
| touch('hello.z'); | |
| touch('hello.q'); | |
| # subtest 1 | |
| # hello.x is not explicitly mentioned and thus is an intermediate file. | |
| run_make_test(q! | |
| all: hello.z | |
| %.z %.q: %.x ; touch $*.z $*.q | |
| %.x: ; | |
| !, '', "#MAKE#: Nothing to be done for 'all'.\n"); | |
| # subtest 2 | |
| # test.x is explicitly mentioned and thus is not an intermediate file. | |
| run_make_test(q! | |
| all: hello.z | |
| %.z %.q: %.x test.x ; @echo $*.z $*.q | |
| %.x: ; | |
| !, '', "hello.z hello.q\n"); | |
| # subtest 3 | |
| # hello.x is explicitly mentioned on an unrelated rule and thus is not an | |
| # intermediate file. | |
| run_make_test(q! | |
| all: hello.z | |
| %.z %.q: %.x; @echo $*.z $*.q | |
| %.x: ; | |
| unrelated: hello.x | |
| !, '', "hello.z hello.q\n"); | |
| unlink('hello.z'); | |
| unlink('hello.q'); | |
| # SV 62809: Missing grouped target peer causes remake regardless of which | |
| # target caused the rule to run. | |
| touch(qw(gta)); # but not gtb | |
| run_make_test(q! | |
| gta gtb &: ; touch gta gtb | |
| !, | |
| 'gta', "touch gta gtb\n"); | |
| unlink(qw(gta gtb)); | |
| # Ensure both goal targets are built if they depend on a grouped prereq | |
| touch(qw(gta)); # but not gtb | |
| run_make_test(q! | |
| x1 x2: ; touch $@ | |
| x1: gta | |
| x2: gtb | |
| gta gtb &: ; touch gta gtb | |
| !, | |
| 'x1 x2', "touch gta gtb\ntouch x1\ntouch x2\n"); | |
| # Now everything should be up to date | |
| run_make_test(undef, 'x1 x2', | |
| "#MAKE#: 'x1' is up to date.\n#MAKE#: 'x2' is up to date."); | |
| unlink(qw(x1 x2 gta gtb)); | |
| # If an also-make file is older than a prerequisite build both | |
| utouch(-20, 'gtb'); | |
| utouch(-10, 'pre'); | |
| touch(qw(gta)); | |
| run_make_test(q! | |
| gta gtb &: pre ; touch gta gtb | |
| !, | |
| 'gta', "touch gta gtb\n"); | |
| unlink(qw(pre gta gtb)); | |
| # This tells the test driver that the perl test script executed properly. | |
| 1; |