mirror of
https://git.savannah.gnu.org/git/make.git
synced 2024-12-24 12:58:39 +00:00
[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.
This commit is contained in:
parent
16e14b4114
commit
07eea3aa49
8 changed files with 430 additions and 57 deletions
5
NEWS
5
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 <dgoncharov@users.sf.net>
|
||||
|
||||
* 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 <dgoncharov@users.sf.net>
|
||||
|
||||
* 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
|
||||
|
|
|
@ -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:
|
||||
|
|
48
src/file.c
48
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)
|
||||
|
|
|
@ -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);
|
||||
|
|
12
src/remake.c
12
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue