diff options
author | Dmitry Goncharov <dgoncharov@users.sf.net> | 2022-07-24 18:16:50 -0400 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2022-07-30 18:40:28 -0400 |
commit | 07eea3aa496184bb763b7306e9de6a40a94605c9 (patch) | |
tree | f0b5e2b330b6ef40627b7050738c603aec4cd79b /tests | |
parent | 16e14b4114c0c9cc14d15e818bf22588a79e39da (diff) | |
download | make-git-07eea3aa496184bb763b7306e9de6a40a94605c9.tar.gz |
[SV 62706] Only second-expand targets that might be built
Second-expand only the prerequisites of the targets being built.
Defer second-expanding the prerequisites of targets until we need
to decide if they should be built.
* NEWS: Mention the change in behavior.
* doc/make.texi (Secondary Expansion): Document the new behavior.
* src/filedef.h (struct file): Add flag snapped.
(expand_deps): Declare a function to second expand the
prerequisites of a target.
* src/file.c (rehash_file): Merge flag snapped.
(expand_deps): Remove qualifier static. Check flag snapped.
(snap_deps): Remove the loop which performed second expansion for all
targets.
* src/remake.c (update_file_1): Second expand the prerequisites of
the considered target.
* tests/scripts/features/se_explicit: Add tests.
* tests/scripts/features/se_implicit: Ditto.
* tests/scripts/features/se_statpat: Ditto.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/scripts/features/se_explicit | 203 | ||||
-rw-r--r-- | tests/scripts/features/se_implicit | 67 | ||||
-rw-r--r-- | tests/scripts/features/se_statpat | 127 |
3 files changed, 390 insertions, 7 deletions
diff --git a/tests/scripts/features/se_explicit b/tests/scripts/features/se_explicit index 35418274..ee5a89de 100644 --- a/tests/scripts/features/se_explicit +++ b/tests/scripts/features/se_explicit @@ -299,4 +299,207 @@ all: bye.x bye.x: $$(firstword bye.1; !, '', "#MAKEFILE#:4: *** unterminated call to function 'firstword': missing ')'. Stop.", 512); +unlink('hello.tsk', 'test.o', 'bye.tsk', 'hello.o', 'hello.h', 'hello.q', 'bye.c', 'bye.o'); + +# sv 62706. +# Test that makes avoids second expanding prerequisites of the targets which +# are not built. +# Here, hello.tsk is built and its prerequisites are second expanded. +# bye.tsk is not built and its prerequisites are not second expanded. +run_make_test(q! +.SECONDEXPANSION: +hello.tsk: hello.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +bye.tsk: bye.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +hello.o: $$(info second expansion of $$@ prereqs); $(info $@) +bye.o: $$(info second expansion of $$@ prereqs); $(info $@) +!, 'hello.tsk', +"second expansion of hello.tsk prereqs +second expansion of hello.o prereqs +hello.o +hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Multipe rules per target. +run_make_test(q! +.SECONDEXPANSION: + +all: hello.tsk +dep1:=hello.o +dep2:=hello.h +hello.tsk: $$(dep1) +hello.tsk: $$(dep2); $(info $@ from $^) +hello.o:; $(info $@) +hello.h:; $(info $@) +!, 'hello.tsk', +"hello.h +hello.o +hello.tsk from hello.h hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Multiple targets per rule. +run_make_test(q! +.SECONDEXPANSION: +hello.tsk bye.tsk: hello.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +bye.tsk: bye.o $$(info second expansion of $$@ prereqs) +hello.o: $$(info second expansion of $$@ prereqs); $(info $@) +bye.o: $$(info second expansion of $$@ prereqs); $(info $@) +!, 'hello.tsk', +"second expansion of hello.tsk prereqs +second expansion of hello.o prereqs +hello.o +hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Grouped targets. +run_make_test(q! +.SECONDEXPANSION: +world.tsk: world.o $$(info 1 second expansion of $$@ prereqs) +hello.tsk world.tsk &: hello.o $$(info 2 second expansion of $$@ prereqs); $(info $@ from $<) +bye.tsk: bye.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +hello.o: $$(info second expansion of $$@ prereqs); $(info $@) +world.o: $$(info second expansion of $$@ prereqs); $(info $@) +bye.o: $$(info second expansion of $$@ prereqs); $(info $@) +!, 'hello.tsk', +"2 second expansion of hello.tsk prereqs +second expansion of hello.o prereqs +hello.o +2 second expansion of world.tsk prereqs +1 second expansion of world.tsk prereqs +second expansion of world.o prereqs +world.o +hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Order only. +run_make_test(q! +.SECONDEXPANSION: +hello.tsk:| hello.o $$(info second expansion of $$@ prereqs); $(info $@ from $|) +bye.tsk:| bye.o $$(info second expansion of $$@ prereqs); $(info $@ from $|) +hello.o:| $$(info second expansion of $$@ prereqs); $(info $@) +bye.o:| $$(info second expansion of $$@ prereqs); $(info $@) +!, 'hello.tsk', +"second expansion of hello.tsk prereqs +second expansion of hello.o prereqs +hello.o +hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Double colon. 1 rule per target. +run_make_test(q! +.SECONDEXPANSION: +hello.tsk:: hello.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +bye.tsk:: bye.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +hello.o:: $$(info second expansion of $$@ prereqs); $(info $@) +bye.o:: $$(info second expansion of $$@ prereqs); $(info $@) +!, 'hello.tsk', +"second expansion of hello.tsk prereqs +second expansion of hello.o prereqs +hello.o +hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Double colon. 2 rules per targets. +run_make_test(q! +.SECONDEXPANSION: +hello.tsk:: hello.o $$(info 1 second expansion of $$@ prereqs); $(info 1 $@ from $<) +hello.tsk:: hello.o $$(info 2 second expansion of $$@ prereqs); $(info 2 $@ from $<) +bye.tsk:: bye.o $$(info 1 second expansion of $$@ prereqs); $(info 1 $@ from $<) +bye.tsk:: bye.o $$(info 2 second expansion of $$@ prereqs); $(info 2 $@ from $<) +hello.o:: $$(info 1 second expansion of $$@ prereqs); $(info 1 $@) +hello.o:: $$(info 2 second expansion of $$@ prereqs); $(info 2 $@) +bye.o:: $$(info 1 second expansion of $$@ prereqs); $(info 1 $@) +bye.o:: $$(info 2 second expansion of $$@ prereqs); $(info 2 $@) +!, 'hello.tsk', +"1 second expansion of hello.tsk prereqs +1 second expansion of hello.o prereqs +1 hello.o +2 second expansion of hello.o prereqs +2 hello.o +1 hello.tsk from hello.o +2 second expansion of hello.tsk prereqs +2 hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Test that the prerequisites of 'hello.tsk' are second expanded once. +run_make_test(q! +.SECONDEXPANSION: +all: hello.tsk hello.q +hello.tsk: hello.o $$(info second expansion of $$@ prereqs); $(info $@ from $^) +hello.o: $$(info second expansion of $$@ prereqs); $(info $@) +hello.q: hello.tsk $$(info second expansion of $$@ prereqs); $(info $@ from $^) +!, '', +"second expansion of hello.tsk prereqs +second expansion of hello.o prereqs +hello.o +hello.tsk from hello.o +second expansion of hello.q prereqs +hello.q from hello.tsk +#MAKE#: Nothing to be done for 'all'.\n"); + +# sv 62706. +# Merge vpath file and local file. +# Test that both sets of prerequisites from 'hello.c' rule and from +# 'src/hello.c' rule are second expanded. +run_make_test(q! +.SECONDEXPANSION: +vpath hello.c src +all: hello.c; $(info $@ from $^) +hello.c: $$(info second expansion of hello.c prereqs); $(info 1 $@) +src/hello.c: $$(info second expansion of src/hello.c prereqs); $(info 2 $@) +!, '', +"#MAKEFILE#:5: Recipe was specified for file 'hello.c' at #MAKEFILE#:5, +#MAKEFILE#:5: but 'hello.c' is now considered the same file as 'src/hello.c'. +#MAKEFILE#:5: Recipe for 'hello.c' will be ignored in favor of the one for 'src/hello.c'. +second expansion of src/hello.c prereqs +second expansion of hello.c prereqs +2 src/hello.c +all from src/hello.c +#MAKE#: 'all' is up to date.\n"); + +# sv 62706. +# .DEFAULT. +run_make_test(q! +.SECONDEXPANSION: +bye:=bye.c +all: hello.o +.DEFAULT: $$(info second expansion of prereqs of default recipe @ = $$@) ; $(info default recipe $@) +!, '', +"default recipe hello.o +#MAKE#: Nothing to be done for 'all'.\n"); + +unlink('hello.1'); + +# sv 62706. +# No side effects from second expansion of unrelated rules. +run_make_test(q! +.SECONDEXPANSION: +hello.tsk:; cp hello.1 $@ +unrelated: $$(shell touch hello.1); +!, '', +"cp hello.1 hello.tsk +cp: cannot stat 'hello.1': $ERR_no_such_file +#MAKE#: *** [#MAKEFILE#:3: hello.tsk] Error 1\n", 512); + +# sv 62706. +# Second expansion of intermediate prerequisites. +# The rule to build hello.x is explicit. +# .SECONDARY marks hello.x as intermediate. +# Test that $$(deps) is secondary expanded. +run_make_test(q! +deps:=hello.h +.SECONDEXPANSION: +.SECONDARY: hello.x +all: hello.x +hello.x: $$(deps); $(info $@) +hello.h:; $(info $@) +!, '', "hello.h\nhello.x\n#MAKE#: Nothing to be done for 'all'.\n"); + + 1; diff --git a/tests/scripts/features/se_implicit b/tests/scripts/features/se_implicit index e7d88468..58775631 100644 --- a/tests/scripts/features/se_implicit +++ b/tests/scripts/features/se_implicit @@ -292,8 +292,11 @@ all: hello.z !, '', "hello.z\n"); # subtest 3. -# hello.x is explicitly mentioned on an unrelated rule and thus is not an -# intermediate file. +# make is building hello.z and does not second expand the prerequisites of rule +# 'unrelated: $$(dep)'. '$$(dep)' stays not expanded and 'hello.x' is never +# entered to the database. Make considers 'hello.x' intermediate while building +# 'hello.z'. Because 'hello.z' is present and 'hello.x' is missing and +# 'hello.x' is intermediate, there is no need to rebuild 'hello.z'. run_make_test(q! .SECONDEXPANSION: dep:=hello.x @@ -301,7 +304,19 @@ all: hello.z %.z: %.x; @echo $@ %.x: ; unrelated: $$(dep) -!, '', "hello.z\n"); +!, '', "#MAKE#: Nothing to be done for 'all'.\n"); + +# subtest 4. +# Just like subtest 3. $$(dep) is not second expanded. 'hello.x' is +# intermediate. +run_make_test(q! +.SECONDEXPANSION: +dep:=hello.x +all: hello.z +%.z: %.x; @echo $@ +%.x: ; +%.q: $$(dep) +!, '', "#MAKE#: Nothing to be done for 'all'.\n"); unlink('hello.z'); @@ -442,5 +457,51 @@ all: bye.x %.x: $$(firstword %.1; !, '', "#MAKE#: *** unterminated call to function 'firstword': missing ')'. Stop.", 512); +# sv 62706. +# Test that makes avoids second expanding prerequisites of the rules which are +# not tried during implicit search. +# Here, make tries rules '%.tsk: %.o' and '%.o' and their prerequisites are +# second expanded. +# Rules '%.bin: %.x' and '%.x:' are not used in implicit search for 'hello.tsk' +# and 'hello.o' and their prerequisites are not expanded. +run_make_test(q! +.SECONDEXPANSION: +%.bin: %.x $$(info second expansion of $$@ prereqs); $(info $@ from $<) +%.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +%.x: $$(info second expansion of $$@ prereqs); $(info $@) +%.o: $$(info second expansion of $$@ prereqs); $(info $@) +!, '-R hello.tsk', +"second expansion of hello.o prereqs +second expansion of hello.tsk prereqs +hello.o +hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# No side effects from second expansion of unrelated rules. +run_make_test(q! +.SECONDEXPANSION: +all: hello.tsk +%.tsk: %.o; cp hello.1 $@ +hello.o:; +%.q: $$(shell touch hello.1); +!, '', +"cp hello.1 hello.tsk +cp: cannot stat 'hello.1': $ERR_no_such_file +#MAKE#: *** [#MAKEFILE#:4: hello.tsk] Error 1\n", 512); + +# sv 62706. +# Second expansion of intermediate prerequisites. +# The rule to build hello.x is implicit. +# Test that $$(deps) is secondary expanded. +run_make_test(q! +deps:=hello.h +.SECONDEXPANSION: +all: hello.tsk +%.tsk: %.x; $(info $@) +%.x: $$(deps); $(info $@) +hello.h:; $(info $@) +!, '', "hello.h\nhello.x\nhello.tsk\n#MAKE#: Nothing to be done for 'all'.\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 index 17f9c348..616a1a85 100644 --- a/tests/scripts/features/se_statpat +++ b/tests/scripts/features/se_statpat @@ -91,11 +91,9 @@ baz.a.2 # run_make_test(q! .SECONDEXPANSION: -foo$$bar: f%r: % $$*.1 - @echo '$*' +foo$$bar: f%r: % $$*.1 ; @echo '$*' -oo$$ba oo$$ba.1: - @echo '$@' +oo$$ba oo$$ba.1: ; @echo '$@' !, '', 'oo$ba oo$ba.1 @@ -110,5 +108,126 @@ all: bye.x bye.x: %.x: $$(firstword %.1; !, '', "#MAKEFILE#:4: *** unterminated call to function 'firstword': missing ')'. Stop.", 512); +#unlink('hello.tsk', 'bye.tsk', 'hello.o', 'hello.q', 'bye.o'); + +# sv 62706. +# Test that makes avoids second expanding prerequisites of the targets which +# are not built. +# Here, hello.tsk is built and its prerequisites are second expanded. +# bye.tsk is not built and its prerequisites are not second expanded. + +# Static pattern rules. +run_make_test(q! +.SECONDEXPANSION: +hello.tsk: %.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +bye.tsk: %.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +hello.o: $$(info second expansion of $$@ prereqs); $(info $@) +bye.o: $$(info second expansion of $$@ prereqs); $(info $@) +!, 'hello.tsk', +"second expansion of hello.tsk prereqs +second expansion of hello.o prereqs +hello.o +hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Order only prereqs. +run_make_test(q! +.SECONDEXPANSION: +hello.tsk: %.tsk:| %.o $$(info second expansion of $$@ prereqs); $(info $@ from $|) +bye.tsk: %.tsk:| %.o $$(info second expansion of $$@ prereqs); $(info $@ from $|) +hello.o:| $$(info second expansion of $$@ prereqs); $(info $@) +bye.o:| $$(info second expansion of $$@ prereqs); $(info $@) +!, 'hello.tsk', +"second expansion of hello.tsk prereqs +second expansion of hello.o prereqs +hello.o +hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Double colon. 1 rule per target. +run_make_test(q! +.SECONDEXPANSION: +hello.tsk:: %.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +bye.tsk:: %.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $<) +hello.o:: $$(info second expansion of $$@ prereqs); $(info $@) +bye.o:: $$(info second expansion of $$@ prereqs); $(info $@) +!, 'hello.tsk', +"second expansion of hello.tsk prereqs +second expansion of hello.o prereqs +hello.o +hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Double colon. 2 rules per target. +run_make_test(q! +.SECONDEXPANSION: +hello.tsk:: %.tsk: %.o $$(info 1 second expansion of $$@ prereqs); $(info 1 $@ from $<) +hello.tsk:: %.tsk: %.o $$(info 2 second expansion of $$@ prereqs); $(info 2 $@ from $<) +bye.tsk:: %.tsk: %.o $$(info 1 second expansion of $$@ prereqs); $(info 1 $@ from $<) +bye.tsk:: %.tsk: %.o $$(info 2 second expansion of $$@ prereqs); $(info 2 $@ from $<) +hello.o:: $$(info 1 second expansion of $$@ prereqs); $(info 1 $@) +hello.o:: $$(info 2 second expansion of $$@ prereqs); $(info 2 $@) +bye.o:: $$(info 1 second expansion of $$@ prereqs); $(info 1 $@) +bye.o:: $$(info 2 second expansion of $$@ prereqs); $(info 2 $@) +!, 'hello.tsk', +"1 second expansion of hello.tsk prereqs +1 second expansion of hello.o prereqs +1 hello.o +2 second expansion of hello.o prereqs +2 hello.o +1 hello.tsk from hello.o +2 second expansion of hello.tsk prereqs +2 hello.tsk from hello.o +#MAKE#: 'hello.tsk' is up to date.\n"); + +# sv 62706. +# Test that the prerequisites of 'hello.tsk' are second expanded once. +run_make_test(q! +.SECONDEXPANSION: +all: hello.tsk hello.q +hello.tsk: %.tsk: %.o $$(info second expansion of $$@ prereqs); $(info $@ from $^) +hello.o: $$(info second expansion of $$@ prereqs); $(info $@) +hello.q: %.q: %.tsk $$(info second expansion of $$@ prereqs); $(info $@ from $^) +!, '', +"second expansion of hello.tsk prereqs +second expansion of hello.o prereqs +hello.o +hello.tsk from hello.o +second expansion of hello.q prereqs +hello.q from hello.tsk +#MAKE#: Nothing to be done for 'all'.\n"); + +unlink('hello.1'); + +# sv 62706. +# No side effects from second expansion of unrelated rules. +run_make_test(q! +.SECONDEXPANSION: +all: hello.tsk +hello.tsk: %.tsk: %.o; cp hello.1 $@ +hello.o:; +bye.tsk: %.tsk: $$(shell touch hello.1); +!, '', +"cp hello.1 hello.tsk +cp: cannot stat 'hello.1': $ERR_no_such_file +#MAKE#: *** [#MAKEFILE#:4: hello.tsk] Error 1\n", 512); + +# sv 62706. +# Second expansion of intermediate prerequisites. +# The rule to build hello.x is static pattern. +# .SECONDARY marks hello.x as intermediate. +# Test that $$(deps) is secondary expanded. +run_make_test(q! +deps:=hello.h +.SECONDEXPANSION: +.SECONDARY: hello.x +all: hello.x +hello.x: %.x: $$(deps); $(info $@) +hello.h:; $(info $@) +!, '', "hello.h\nhello.x\n#MAKE#: Nothing to be done for 'all'.\n"); + # This tells the test driver that the perl test script executed properly. 1; |