mirror of
https://github.com/mirror/make.git
synced 2026-08-08 00:51:25 +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:
committed by
Paul Smith
parent
16e14b4114
commit
07eea3aa49
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".
|
mentioned in other targets as "ought to exist".
|
||||||
Implementation provided by Dmitry Goncharov <dgoncharov@users.sf.net>
|
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
|
* 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
|
immediately rather than after all makefiles have been read. Note that
|
||||||
although all options are parsed immediately, some special effects won't
|
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
|
@code{.SECONDEXPANSION} must be defined before the first prerequisite
|
||||||
list that makes use of this feature.
|
list that makes use of this feature.
|
||||||
|
|
||||||
If that special target is defined then in between the two phases
|
If @code{.SECONDEXPANSION} is defined then when GNU @code{make} needs to check
|
||||||
mentioned above, right at the end of the read-in phase, all the
|
the prerequisites of a target, the prerequisites are expanded a @emph{second
|
||||||
prerequisites of the targets defined after the special target are
|
time}. In most circumstances this secondary expansion will have no effect,
|
||||||
expanded a @emph{second time}. In most circumstances this secondary
|
since all variable and function references will have been expanded during the
|
||||||
expansion will have no effect, since all variable and function
|
initial parsing of the makefiles. In order to take advantage of the secondary
|
||||||
references will have been expanded during the initial parsing of the
|
expansion phase of the parser, then, it's necessary to @emph{escape} the
|
||||||
makefiles. In order to take advantage of the secondary expansion
|
variable or function reference in the makefile. In this case the first
|
||||||
phase of the parser, then, it's necessary to @emph{escape} the
|
expansion merely un-escapes the reference but doesn't expand it, and expansion
|
||||||
variable or function reference in the makefile. In this case the
|
is left to the secondary expansion phase. For example, consider this
|
||||||
first expansion merely un-escapes the reference but doesn't expand it,
|
makefile:
|
||||||
and expansion is left to the secondary expansion phase. For example,
|
|
||||||
consider this makefile:
|
|
||||||
|
|
||||||
@example
|
@example
|
||||||
.SECONDEXPANSION:
|
.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 (secondary);
|
||||||
MERGE (notintermediate);
|
MERGE (notintermediate);
|
||||||
MERGE (ignore_vpath);
|
MERGE (ignore_vpath);
|
||||||
|
MERGE (snapped);
|
||||||
#undef MERGE
|
#undef MERGE
|
||||||
|
|
||||||
to_file->builtin = 0;
|
to_file->builtin = 0;
|
||||||
@@ -565,8 +566,10 @@ enter_prereqs (struct dep *deps, const char *stem)
|
|||||||
return deps;
|
return deps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expand and parse each dependency line. */
|
/* Expand and parse each dependency line.
|
||||||
static void
|
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)
|
expand_deps (struct file *f)
|
||||||
{
|
{
|
||||||
struct dep *d;
|
struct dep *d;
|
||||||
@@ -574,7 +577,9 @@ expand_deps (struct file *f)
|
|||||||
const char *fstem;
|
const char *fstem;
|
||||||
int initialized = 0;
|
int initialized = 0;
|
||||||
|
|
||||||
f->updating = 0;
|
if (f->snapped)
|
||||||
|
return;
|
||||||
|
f->snapped = 1;
|
||||||
|
|
||||||
/* Walk through the dependencies. For any dependency that needs 2nd
|
/* Walk through the dependencies. For any dependency that needs 2nd
|
||||||
expansion, expand it then insert the result into the list. */
|
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);
|
set_file_variables (f, d->stem ? d->stem : f->stem);
|
||||||
|
|
||||||
|
/* Perform second expansion. */
|
||||||
p = variable_expand_for_file (d->name, f);
|
p = variable_expand_for_file (d->name, f);
|
||||||
|
|
||||||
/* Free the un-expanded name. */
|
/* 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
|
/* Mark the files depended on by .PRECIOUS, .PHONY, .SILENT,
|
||||||
at the appropriate 'struct file' (which may have to be created).
|
|
||||||
|
|
||||||
Also mark the files depended on by .PRECIOUS, .PHONY, .SILENT,
|
|
||||||
and various other special targets. */
|
and various other special targets. */
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -775,37 +778,6 @@ snap_deps (void)
|
|||||||
longer define new targets. */
|
longer define new targets. */
|
||||||
snapped_deps = 1;
|
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. */
|
/* Now manage all the special targets. */
|
||||||
|
|
||||||
for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
|
for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ struct file
|
|||||||
diagnostics has been issued (dontcare). */
|
diagnostics has been issued (dontcare). */
|
||||||
unsigned int was_shuffled:1; /* Did we already shuffle 'deps'? used when
|
unsigned int was_shuffled:1; /* Did we already shuffle 'deps'? used when
|
||||||
--shuffle passes through the graph. */
|
--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 file *enter_file (const char *name);
|
||||||
struct dep *split_prereqs (char *prereqstr);
|
struct dep *split_prereqs (char *prereqstr);
|
||||||
struct dep *enter_prereqs (struct dep *prereqs, const char *stem);
|
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);
|
struct dep *expand_extra_prereqs (const struct variable *extra);
|
||||||
void remove_intermediates (int sig);
|
void remove_intermediates (int sig);
|
||||||
void snap_deps (void);
|
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;
|
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 */
|
/* Find the deps we're scanning */
|
||||||
du = ad->file->deps;
|
du = ad->file->deps;
|
||||||
ad = ad->next;
|
ad = ad->next;
|
||||||
@@ -1089,6 +1095,12 @@ check_dep (struct file *file, unsigned int depth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ld = 0;
|
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;
|
d = file->deps;
|
||||||
while (d != 0)
|
while (d != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -299,4 +299,207 @@ all: bye.x
|
|||||||
bye.x: $$(firstword bye.1;
|
bye.x: $$(firstword bye.1;
|
||||||
!, '', "#MAKEFILE#:4: *** unterminated call to function 'firstword': missing ')'. Stop.", 512);
|
!, '', "#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;
|
1;
|
||||||
|
|||||||
@@ -292,8 +292,11 @@ all: hello.z
|
|||||||
!, '', "hello.z\n");
|
!, '', "hello.z\n");
|
||||||
|
|
||||||
# subtest 3.
|
# subtest 3.
|
||||||
# hello.x is explicitly mentioned on an unrelated rule and thus is not an
|
# make is building hello.z and does not second expand the prerequisites of rule
|
||||||
# intermediate file.
|
# '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!
|
run_make_test(q!
|
||||||
.SECONDEXPANSION:
|
.SECONDEXPANSION:
|
||||||
dep:=hello.x
|
dep:=hello.x
|
||||||
@@ -301,7 +304,19 @@ all: hello.z
|
|||||||
%.z: %.x; @echo $@
|
%.z: %.x; @echo $@
|
||||||
%.x: ;
|
%.x: ;
|
||||||
unrelated: $$(dep)
|
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');
|
unlink('hello.z');
|
||||||
|
|
||||||
@@ -442,5 +457,51 @@ all: bye.x
|
|||||||
%.x: $$(firstword %.1;
|
%.x: $$(firstword %.1;
|
||||||
!, '', "#MAKE#: *** unterminated call to function 'firstword': missing ')'. Stop.", 512);
|
!, '', "#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.
|
# This tells the test driver that the perl test script executed properly.
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -91,11 +91,9 @@ baz.a.2
|
|||||||
#
|
#
|
||||||
run_make_test(q!
|
run_make_test(q!
|
||||||
.SECONDEXPANSION:
|
.SECONDEXPANSION:
|
||||||
foo$$bar: f%r: % $$*.1
|
foo$$bar: f%r: % $$*.1 ; @echo '$*'
|
||||||
@echo '$*'
|
|
||||||
|
|
||||||
oo$$ba oo$$ba.1:
|
oo$$ba oo$$ba.1: ; @echo '$@'
|
||||||
@echo '$@'
|
|
||||||
!,
|
!,
|
||||||
'', 'oo$ba
|
'', 'oo$ba
|
||||||
oo$ba.1
|
oo$ba.1
|
||||||
@@ -110,5 +108,126 @@ all: bye.x
|
|||||||
bye.x: %.x: $$(firstword %.1;
|
bye.x: %.x: $$(firstword %.1;
|
||||||
!, '', "#MAKEFILE#:4: *** unterminated call to function 'firstword': missing ')'. Stop.", 512);
|
!, '', "#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.
|
# This tells the test driver that the perl test script executed properly.
|
||||||
1;
|
1;
|
||||||
|
|||||||
Reference in New Issue
Block a user