diff --git a/NEWS b/NEWS index 752de7d0..3a437a27 100644 --- a/NEWS +++ b/NEWS @@ -83,6 +83,11 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se mentioned in other targets as "ought to exist". Implementation provided by Dmitry Goncharov +* GNU make was performing secondary expansion of all targets, even targets + which didn't need to be considered during the build. In this release + only targets which are considered will be secondarily expanded. + Implementation provided by Dmitry Goncharov + * If the MAKEFLAGS variable is modified in a makefile, it will be re-parsed immediately rather than after all makefiles have been read. Note that although all options are parsed immediately, some special effects won't diff --git a/doc/make.texi b/doc/make.texi index 085e9c24..49cdb0b2 100644 --- a/doc/make.texi +++ b/doc/make.texi @@ -1703,18 +1703,16 @@ this second expansion to occur, the special target @code{.SECONDEXPANSION} must be defined before the first prerequisite list that makes use of this feature. -If that special target is defined then in between the two phases -mentioned above, right at the end of the read-in phase, all the -prerequisites of the targets defined after the special target are -expanded a @emph{second time}. In most circumstances this secondary -expansion will have no effect, since all variable and function -references will have been expanded during the initial parsing of the -makefiles. In order to take advantage of the secondary expansion -phase of the parser, then, it's necessary to @emph{escape} the -variable or function reference in the makefile. In this case the -first expansion merely un-escapes the reference but doesn't expand it, -and expansion is left to the secondary expansion phase. For example, -consider this makefile: +If @code{.SECONDEXPANSION} is defined then when GNU @code{make} needs to check +the prerequisites of a target, the prerequisites are expanded a @emph{second +time}. In most circumstances this secondary expansion will have no effect, +since all variable and function references will have been expanded during the +initial parsing of the makefiles. In order to take advantage of the secondary +expansion phase of the parser, then, it's necessary to @emph{escape} the +variable or function reference in the makefile. In this case the first +expansion merely un-escapes the reference but doesn't expand it, and expansion +is left to the secondary expansion phase. For example, consider this +makefile: @example .SECONDEXPANSION: diff --git a/src/file.c b/src/file.c index 3960cdab..7596ff10 100644 --- a/src/file.c +++ b/src/file.c @@ -342,6 +342,7 @@ rehash_file (struct file *from_file, const char *to_hname) MERGE (secondary); MERGE (notintermediate); MERGE (ignore_vpath); + MERGE (snapped); #undef MERGE to_file->builtin = 0; @@ -565,8 +566,10 @@ enter_prereqs (struct dep *deps, const char *stem) return deps; } -/* Expand and parse each dependency line. */ -static void +/* Expand and parse each dependency line. + For each dependency of the file, make the 'struct dep' point + at the appropriate 'struct file' (which may have to be created). */ +void expand_deps (struct file *f) { struct dep *d; @@ -574,7 +577,9 @@ expand_deps (struct file *f) const char *fstem; int initialized = 0; - f->updating = 0; + if (f->snapped) + return; + f->snapped = 1; /* Walk through the dependencies. For any dependency that needs 2nd expansion, expand it then insert the result into the list. */ @@ -646,6 +651,7 @@ expand_deps (struct file *f) set_file_variables (f, d->stem ? d->stem : f->stem); + /* Perform second expansion. */ p = variable_expand_for_file (d->name, f); /* Free the un-expanded name. */ @@ -758,10 +764,7 @@ snap_file (const void *item, void *arg) } } -/* For each dependency of each file, make the 'struct dep' point - at the appropriate 'struct file' (which may have to be created). - - Also mark the files depended on by .PRECIOUS, .PHONY, .SILENT, +/* Mark the files depended on by .PRECIOUS, .PHONY, .SILENT, and various other special targets. */ void @@ -775,37 +778,6 @@ snap_deps (void) longer define new targets. */ snapped_deps = 1; - /* Perform second expansion and enter each dependency name as a file. We - must use hash_dump() here because within these loops we likely add new - files to the table, possibly causing an in-situ table expansion. - - We only need to do this if second_expansion has been defined; if it - hasn't then all deps were expanded as the makefile was read in. If we - ever change make to be able to unset .SECONDARY_EXPANSION this will have - to change. */ - - if (second_expansion) - { - struct file **file_slot_0 = (struct file **) hash_dump (&files, 0, 0); - struct file **file_end = file_slot_0 + files.ht_fill; - struct file **file_slot; - const char *suffixes; - - /* Expand .SUFFIXES: its prerequisites are used for $$* calc. */ - f = lookup_file (".SUFFIXES"); - suffixes = f ? f->name : 0; - for (; f != 0; f = f->prev) - expand_deps (f); - - /* For every target that's not .SUFFIXES, expand its prerequisites. */ - - for (file_slot = file_slot_0; file_slot < file_end; file_slot++) - for (f = *file_slot; f != 0; f = f->prev) - if (f->name != suffixes) - expand_deps (f); - free (file_slot_0); - } - /* Now manage all the special targets. */ for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev) diff --git a/src/filedef.h b/src/filedef.h index 4330d787..1eb8f61c 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -110,6 +110,8 @@ struct file diagnostics has been issued (dontcare). */ unsigned int was_shuffled:1; /* Did we already shuffle 'deps'? used when --shuffle passes through the graph. */ + unsigned int snapped:1; /* True if the deps of this file have been + secondary expanded. */ }; @@ -120,6 +122,7 @@ struct file *lookup_file (const char *name); struct file *enter_file (const char *name); struct dep *split_prereqs (char *prereqstr); struct dep *enter_prereqs (struct dep *prereqs, const char *stem); +void expand_deps (struct file *f); struct dep *expand_extra_prereqs (const struct variable *extra); void remove_intermediates (int sig); void snap_deps (void); diff --git a/src/remake.c b/src/remake.c index 2930a5bb..228b8af6 100644 --- a/src/remake.c +++ b/src/remake.c @@ -532,6 +532,12 @@ update_file_1 (struct file *file, unsigned int depth) { struct dep *lastd = 0; + /* Perform second expansion and enter each dependency name as a file. + We only need to do this if second_expansion has been defined; if it + hasn't then all deps were expanded as the makefile was read in. */ + if (second_expansion) + expand_deps (ad->file); + /* Find the deps we're scanning */ du = ad->file->deps; ad = ad->next; @@ -1089,6 +1095,12 @@ check_dep (struct file *file, unsigned int depth, } ld = 0; + /* Perform second expansion and enter each dependency name as a file. + We only need to do this if second_expansion has been defined; if it + hasn't then all deps were expanded as the makefile was read in. */ + if (second_expansion) + expand_deps (file); + d = file->deps; while (d != 0) { 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;