| # -*-mode: perl-*- | |
| $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."; | |
| create_file('incl.mk', "ANOTHER: ; \@echo This is another included makefile\n"); | |
| run_make_test(qq!#Extra space at the end of the following file name | |
| include incl.mk ! . q! | |
| 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 | |
| !, | |
| "all", "There should be no errors for this makefile.\n"); | |
| run_make_test(undef, "ANOTHER", "This is another included makefile\n"); | |
| unlink('incl.mk'); | |
| # 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 | |
| ); | |
| # The same as above with an additional include directory. | |
| mkdir('hellod', 0777); | |
| run_make_test | |
| (' | |
| -include foo.mk | |
| error: foo.mk ; @echo $@ | |
| ', | |
| '-Ihellod', | |
| "#MAKE#: *** No rule to make target 'foo.mk', needed by 'error'. Stop.\n", | |
| 512 | |
| ); | |
| rmdir('hellod'); | |
| # 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 include of make-able file doesn't show an error (Savannah #102) | |
| run_make_test(q! | |
| .PHONY: default | |
| default:; @echo DONE | |
| inc1:; echo > $@ | |
| include inc1 | |
| include inc2 | |
| inc2:; echo > $@ | |
| !, | |
| '', "echo > inc1\necho > inc2\nDONE\n"); | |
| rmfiles('inc1', 'inc2'); | |
| # Test include of make-able file doesn't show an error. | |
| # Specify an additional include directory. | |
| mkdir('hellod', 0777); | |
| run_make_test(q! | |
| .PHONY: default | |
| default:; @echo DONE | |
| inc1:; echo > $@ | |
| include inc1 | |
| include inc2 | |
| inc2:; echo > $@ | |
| !, | |
| '-Ihellod', "echo > inc1\necho > inc2\nDONE\n"); | |
| rmfiles('inc1', 'inc2'); | |
| # Test include of make-able file doesn't show an error. | |
| # inc1 and inc2 are present in the specified include directory. | |
| touch('hellod/inc1'); | |
| touch('hellod/inc2'); | |
| run_make_test(q! | |
| .PHONY: default | |
| default:; @echo DONE | |
| inc1:; echo > $@ | |
| include inc1 | |
| include inc2 | |
| inc2:; echo > $@ | |
| !, | |
| '-Ihellod', "DONE\n"); | |
| rmfiles('inc1', 'inc2', 'hellod/inc1', 'hellod/inc2'); | |
| rmdir('hellod'); | |
| # No target gets correct error | |
| run_make_test("\n", '', '#MAKE#: *** No targets. Stop.', 512); | |
| # No target in included file either, still gets correct error. | |
| touch('inc1.mk'); | |
| run_make_test('include inc1.mk', '', '#MAKE#: *** No targets. Stop.', 512); | |
| rmfiles('inc1.mk'); | |
| # Include same file multiple times | |
| run_make_test(q! | |
| default:; @echo DEFAULT | |
| include inc1 | |
| inc1:; echo > $@ | |
| include inc1 | |
| !, | |
| '', "echo > inc1\nDEFAULT\n"); | |
| rmfiles('inc1'); | |
| if (defined $ERR_no_such_file) { | |
| # 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: $ERR_no_such_file\n#MAKE#: *** No rule to make target 'end', needed by 'baz'. Stop.\n", | |
| 512); | |
| # Test include of non-make-able file does show an error (Savannah #102) | |
| run_make_test(q! | |
| .PHONY: default | |
| default:; @echo DONE | |
| inc1:; echo > $@ | |
| include inc1 | |
| include inc2 | |
| !, | |
| '', "echo > inc1\n#MAKEFILE#:7: inc2: $ERR_no_such_file\n#MAKE#: *** No rule to make target 'inc2'. Stop.\n", 512); | |
| rmfiles('inc1'); | |
| # Included file has a prerequisite that fails to build | |
| run_make_test(q! | |
| default:; @echo DEFAULT | |
| include inc1 | |
| inc1: foo; echo > $@ | |
| foo:; exit 1 | |
| !, | |
| '', "exit 1\n#MAKEFILE#:3: inc1: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:5: foo] Error 1\n", 512); | |
| rmfiles('inc1'); | |
| # Included file has a prerequisite we don't know how to build | |
| run_make_test(q! | |
| default:; @echo DEFAULT | |
| include inc1 | |
| inc1: foo; echo > $@ | |
| !, | |
| '', "#MAKEFILE#:3: inc1: $ERR_no_such_file\n#MAKE#: *** No rule to make target 'foo', needed by 'inc1'. Stop.\n", 512); | |
| rmfiles('inc1'); | |
| # Check that included double-colon targets with no prerequisites aren't | |
| # built. This should fail as hello.mk doesn't exist | |
| run_make_test(q! | |
| .PHONY: default | |
| default:;@echo 'FOO=$(FOO)' | |
| include hello.mk | |
| hello.mk:: ; echo 'FOO=bar' > $@ | |
| !, | |
| '', "#MAKEFILE#:4: hello.mk: $ERR_no_such_file", 512); | |
| # Check that included phony targets aren't built. | |
| # This should fail as hello.mk doesn't exist | |
| run_make_test(q! | |
| .PHONY: default | |
| default:;@echo 'FOO=$(FOO)' | |
| include hello.mk | |
| hello.mk: ; echo 'FOO=bar' > $@ | |
| .PHONY: hello.mk | |
| !, | |
| '', "#MAKEFILE#:4: hello.mk: $ERR_no_such_file", 512); | |
| } | |
| if (defined $ERR_unreadable_file) { | |
| # Including files that can't be read should show an error | |
| unlink('inc1'); | |
| create_file('inc1', 'FOO := foo'); | |
| chmod 0000, 'inc1'; | |
| run_make_test(q! | |
| include inc1 | |
| all:;@echo $(FOO) | |
| !, | |
| '', "#MAKEFILE#:2: inc1: $ERR_unreadable_file\n#MAKE#: *** No rule to make target 'inc1'. Stop.", 512); | |
| # Including files that can't be read should show an error, even when there | |
| # is a readable file in a subsequent include directory. | |
| mkdir('hellod', 0777); | |
| touch("hellod/inc1"); | |
| run_make_test(q! | |
| include inc1 | |
| all:;@echo $(FOO) | |
| !, | |
| '-Ihellod', "#MAKEFILE#:2: inc1: $ERR_unreadable_file\n#MAKE#: *** No rule to make target 'inc1'. Stop.", 512); | |
| # Unreadable files that we know how to successfully recreate should work | |
| run_make_test(sprintf(q! | |
| all:;@echo $(FOO) | |
| include inc1 | |
| inc1:; @%s $@ && echo FOO := bar > $@ | |
| !, $CMD_rmfile), | |
| '', "bar"); | |
| # Unreadable files that we know how to successfully recreate should work. | |
| # Even when there is a readable file in an additional include directory. | |
| unlink('inc1'); | |
| create_file('inc1', 'FOO := foo'); | |
| chmod 0000, 'inc1'; | |
| run_make_test(sprintf(q! | |
| all:;@echo $(FOO) | |
| include inc1 | |
| inc1:; @%s $@ && echo FOO := bar > $@ | |
| !, $CMD_rmfile), | |
| '-Ihellod', "bar"); | |
| rmfiles('inc1', 'hellod/inc1'); | |
| rmdir('hellod'); | |
| } | |
| # Check that the order of remaking include files is correct: should remake | |
| # them in the same order they were encountered in the makefile. SV 58735 | |
| run_make_test(q! | |
| -include i1 i2 | |
| -include i3 | |
| -include i4 | |
| %:;@echo $@ | |
| all:; | |
| !, | |
| '', "i1\ni2\ni3\ni4\n#MAKE#: 'all' is up to date.\n"); | |
| # Check that included files work if created after the first include failed | |
| # https://savannah.gnu.org/bugs/?57676 | |
| run_make_test(q! | |
| default:; @echo $(hello) | |
| -include hello.mk | |
| $(shell echo hello=world >hello.mk) | |
| include hello.mk | |
| !, | |
| '', "world\n"); | |
| unlink('hello.mk'); | |
| # Check that included double-colon targets with no prerequisites aren't built. | |
| # This should succeed since hello.mk already exists | |
| touch('hello.mk'); | |
| run_make_test(q! | |
| .PHONY: default | |
| default:;@echo 'FOO=$(FOO)' | |
| include hello.mk | |
| hello.mk:: ; echo 'FOO=bar' > $@ | |
| !, | |
| '', 'FOO='); | |
| unlink('hello.mk'); | |
| # Check that included double-colon targets with no prerequisites aren't built. | |
| # This should succeed due to -include | |
| run_make_test(q! | |
| .PHONY: default | |
| default:;@echo 'FOO=$(FOO)' | |
| -include hello.mk | |
| hello.mk:: ; echo 'FOO=bar' > $@ | |
| !, | |
| '', 'FOO='); | |
| # Check that phony targets aren't built. | |
| # This should succeed since hello.mk already exists | |
| touch('hello.mk'); | |
| run_make_test(q! | |
| .PHONY: default | |
| default:;@echo 'FOO=$(FOO)' | |
| include hello.mk | |
| hello.mk: ; echo 'FOO=bar' > $@ | |
| .PHONY: hello.mk | |
| !, | |
| '', 'FOO='); | |
| unlink('hello.mk'); | |
| # Check that included double-colon targets with no prerequisites aren't built. | |
| # This should succeed due to -include | |
| run_make_test(q! | |
| .PHONY: default | |
| default:;@echo 'FOO=$(FOO)' | |
| -include hello.mk | |
| hello.mk: ; echo 'FOO=bar' > $@ | |
| .PHONY: hello.mk | |
| !, | |
| '', 'FOO='); | |
| # SV 56301 Verify pattern rules creating optional includes. | |
| # -k shouldn't matter when creating include files. | |
| run_make_test(q! | |
| all:; @echo hello | |
| -include inc_a.mk | |
| include inc_b.mk | |
| %_a.mk %_b.mk:; exit 1 | |
| !, | |
| '', "exit 1\n#MAKEFILE#:4: failed to remake makefile 'inc_b.mk'", 512); | |
| run_make_test(undef, '-k', "exit 1\n#MAKEFILE#:4: failed to remake makefile 'inc_b.mk'", 512); | |
| # It seems wrong to me that this gives a different error message, but at | |
| # least it doesn't keep going. | |
| run_make_test(q! | |
| all:; @echo hello | |
| include inc_a.mk | |
| -include inc_b.mk | |
| %_a.mk %_b.mk:; exit 1 | |
| !, | |
| '', "exit 1\n#MAKEFILE#:3: inc_a.mk: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:5: inc_a.mk] Error 1\n", 512); | |
| run_make_test(undef, '-k', "exit 1\n#MAKEFILE#:3: inc_a.mk: $ERR_no_such_file\n#MAKE#: *** [#MAKEFILE#:5: inc_a.mk] Error 1\n#MAKEFILE#:3: failed to remake makefile 'inc_a.mk'", 512); | |
| # Check the default makefiles... this requires us to invoke make with no | |
| # arguments. Also check MAKEFILES | |
| if ($port_type eq 'W32') { | |
| $defaults = "GNUmakefile\nmakefile\nMakefile\nmakefile.mak"; | |
| } else { | |
| $defaults = "GNUmakefile\nmakefile\nMakefile"; | |
| } | |
| $ENV{MAKEFILES} = 'foobar barfoo'; | |
| run_make_with_options(undef, ['-E', '%:;@echo $@', '-E', 'all:;', '-E', '-include bizbaz', '-E', '-include bazbiz'], get_logfile(0)); | |
| $answer = "bizbaz\nbazbiz\nfoobar\nbarfoo\n$defaults\n#MAKE#: 'all' is up to date.\n"; | |
| &compare_output(subst_make_string($answer), &get_logfile(1)); | |
| # SV 63516 | |
| if (exists $FEATURES{'dospaths'}) { | |
| run_make_test(q! | |
| include C:__foobar | |
| %bar: ; @echo $@ | |
| all: ; | |
| !, | |
| '', "C:__foobar\n#MAKE#: 'all' is up to date."); | |
| } | |
| # sv 63484. | |
| # Test that included makefiles are not intermediate. | |
| # Here 'test.foo' is mentioned explicitly and cannot be considered | |
| # intermediate. | |
| utouch(-10, 'test.foo'); | |
| utouch(-5, 'test.x'); | |
| touch('test'); | |
| run_make_test(q! | |
| .PHONY: force | |
| include test.foo | |
| %.foo: force; @echo force $@ | |
| %.x: %.foo; touch $@ | |
| test: test.x; touch $@ | |
| !, '', "force test.foo\n#MAKE#: 'test' is up to date.\n"); | |
| unlink('test.foo', 'test.x', 'test'); | |
| 1; |