mirror of
https://github.com/mirror/make.git
synced 2025-01-14 22:30:39 +08:00
Support the .EXTRA_PREREQS special variable
Initial implementation by Christof Warlich <cwarlich@gmx.de> * NEWS: Announce the new feature. * doc/make.texi (Other Special Variables): Document .EXTRA_PREREQS. * src/dep.h (struct dep): New flag to note extra prereq deps. * src/filedef.h (expand_extra_prereqs): Declare a function to expand the value of .EXTRA_PREREQS. * src/file.c (expand_extra_prereqs): Given a struct variable lookup of .EXTRA_PREREQS, convert it into a list of deps and for each one make sure it has a struct file and has the new flag set. (snap_file): A new function invoked by hash_map that will perform per-file operations: set up second expansion, intermediate, and also .EXTRA_PREREQS. Manage circular dependencies by ignoring them. (snap_deps): Defer per-file operations until the end. Look up the global .EXTRA_PREREQS and pass it along to snap_file for each file. * src/implicit.c (struct patdeps): Remember the extra prereqs flag. (pattern_search): Transfer extra prereqs flag settings into the matched pattern rule. * src/rule.h (snap_implicit_rules): Rename count_implicit_rules to snap_implicit_rules since we now do more than count. * src/rule.c (snap_implicit_rules): As we walk through all the pattern rules, add in any global .EXTRA_PREREQS to the dep list. Ensure we take them into account for the max number of prereqs and name length. * src/main.c (main): Add extra-prereqs to .FEATURES. Call the renamed snap_implicit_rules. * tests/scripts/variables/EXTRA_PREREQS: Add tests.
This commit is contained in:
parent
e56243fe57
commit
4e12a5fa45
1
AUTHORS
1
AUTHORS
@ -68,6 +68,7 @@ Other contributors:
|
||||
David Boyce <dsb@boyski.com>
|
||||
Frank Heckenbach <f.heckenbach@fh-soft.de>
|
||||
Kaz Kylheku <kaz@kylheku.com>
|
||||
Christof Warlich <cwarlich@gmx.de>
|
||||
|
||||
With suggestions/comments/bug reports from a cast of ... well ...
|
||||
hundreds, anyway :)
|
||||
|
7
NEWS
7
NEWS
@ -48,6 +48,13 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&set
|
||||
search for 'grouped-target' in the .FEATURES special variable.
|
||||
Implementation contributed by Kaz Kylheku <kaz@kylheku.com>
|
||||
|
||||
* New feature: .EXTRA_PREREQS variable
|
||||
Words in this variable are considered prerequisites of targets but they are
|
||||
not added to any of the automatic variable values when expanding the
|
||||
recipe. This variable can either be global (applies to all targets) or
|
||||
a target-specific variable. To detect this feature search for 'extra-prereqs'
|
||||
in the .FEATURES special variable.
|
||||
|
||||
* Makefiles can now specify the '-j' option in their MAKEFLAGS variable and
|
||||
this will cause make to enable that parallelism mode.
|
||||
|
||||
|
@ -6631,6 +6631,57 @@ Supports dynamically loadable objects for creating custom extensions.
|
||||
Expands to a list of directories that @code{make} searches for
|
||||
included makefiles (@pxref{Include, , Including Other Makefiles}).
|
||||
|
||||
@vindex .EXTRA_PREREQS @r{(prerequisites not added to automatic variables)}
|
||||
@item .EXTRA_PREREQS
|
||||
Each word in this variable is a new prerequisite which is added to
|
||||
targets for which it is set. These prerequisites differ from normal
|
||||
prerequisites in that they do not appear in any of the automatic
|
||||
variables (@pxref{Automatic Variables}). This allows prerequisites to
|
||||
be defined which do not impact the recipe.
|
||||
|
||||
Consider a rule to link a program:
|
||||
|
||||
@example
|
||||
myprog: myprog.o file1.o file2.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@@ $^ $(LDLIBS)
|
||||
@end example
|
||||
|
||||
Now suppose you want to enhance this makefile to ensure that updates
|
||||
to the compiler cause the program to be re-linked. You can add the
|
||||
compiler as a prerequisite, but you must ensure that it's not passed
|
||||
as an argument to link command. You'll need something like this:
|
||||
|
||||
@example
|
||||
myprog: myprog.o file1.o file2.o $(CC)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@@ $(filter-out $(CC),$^) $(LDLIBS)
|
||||
@end example
|
||||
|
||||
Then consider having multiple extra prerequisites: they would all have
|
||||
to be filtered out. Using @code{.EXTRA_PREREQS} and target-specific
|
||||
variables provides a simpler solution:
|
||||
|
||||
@example
|
||||
myprog: myprog.o file1.o file2.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@@ $^ $(LDLIBS)
|
||||
myprog: .EXTRA_PREREQS = $(CC)
|
||||
@end example
|
||||
|
||||
This feature can also be useful if you want to add prerequisites to a
|
||||
makefile you cannot easily modify: you can create a new file such as
|
||||
@file{extra.mk}:
|
||||
|
||||
@example
|
||||
myprog: .EXTRA_PREREQS = $(CC)
|
||||
@end example
|
||||
|
||||
then invoke @code{make -f extra.mk -f Makefile}.
|
||||
|
||||
Setting @code{.EXTRA_PREREQS} globally will cause those prerequisites
|
||||
to be added to all targets (which did not themselves override it with
|
||||
a target-specific value). Note @code{make} is smart enough not to add
|
||||
a prerequisite listed in @code{.EXTRA_PREREQS} as a prerequisite to
|
||||
itself.
|
||||
|
||||
@end table
|
||||
|
||||
@node Conditionals, Functions, Using Variables, Top
|
||||
|
@ -133,7 +133,7 @@ set_file_variables (struct file *file)
|
||||
/* $< is the first not order-only dependency. */
|
||||
less = "";
|
||||
for (d = file->deps; d != 0; d = d->next)
|
||||
if (!d->ignore_mtime)
|
||||
if (!d->ignore_mtime && !d->ignore_automatic_vars)
|
||||
{
|
||||
if (!d->need_2nd_expansion)
|
||||
less = dep_name (d);
|
||||
@ -178,7 +178,7 @@ set_file_variables (struct file *file)
|
||||
bar_len = 0;
|
||||
for (d = file->deps; d != 0; d = d->next)
|
||||
{
|
||||
if (!d->need_2nd_expansion)
|
||||
if (!d->need_2nd_expansion && !d->ignore_automatic_vars)
|
||||
{
|
||||
if (d->ignore_mtime)
|
||||
bar_len += strlen (dep_name (d)) + 1;
|
||||
@ -200,7 +200,7 @@ set_file_variables (struct file *file)
|
||||
|
||||
qmark_len = plus_len + 1; /* Will be this or less. */
|
||||
for (d = file->deps; d != 0; d = d->next)
|
||||
if (! d->ignore_mtime && ! d->need_2nd_expansion)
|
||||
if (! d->ignore_mtime && ! d->need_2nd_expansion && ! d->ignore_automatic_vars)
|
||||
{
|
||||
const char *c = dep_name (d);
|
||||
|
||||
@ -247,7 +247,7 @@ set_file_variables (struct file *file)
|
||||
|
||||
for (d = file->deps; d != 0; d = d->next)
|
||||
{
|
||||
if (d->need_2nd_expansion)
|
||||
if (d->need_2nd_expansion || d->ignore_automatic_vars)
|
||||
continue;
|
||||
|
||||
slot = hash_find_slot (&dep_hash, d);
|
||||
@ -269,7 +269,7 @@ set_file_variables (struct file *file)
|
||||
{
|
||||
const char *c;
|
||||
|
||||
if (d->need_2nd_expansion || hash_find_item (&dep_hash, d) != d)
|
||||
if (d->need_2nd_expansion || d->ignore_automatic_vars || hash_find_item (&dep_hash, d) != d)
|
||||
continue;
|
||||
|
||||
c = dep_name (d);
|
||||
|
@ -48,7 +48,8 @@ struct nameseq
|
||||
unsigned int changed : 1; \
|
||||
unsigned int ignore_mtime : 1; \
|
||||
unsigned int staticpattern : 1; \
|
||||
unsigned int need_2nd_expansion : 1
|
||||
unsigned int need_2nd_expansion : 1; \
|
||||
unsigned int ignore_automatic_vars : 1
|
||||
|
||||
struct dep
|
||||
{
|
||||
|
90
src/file.c
90
src/file.c
@ -550,15 +550,6 @@ enter_prereqs (struct dep *deps, const char *stem)
|
||||
return deps;
|
||||
}
|
||||
|
||||
/* Set the intermediate flag. */
|
||||
|
||||
static void
|
||||
set_intermediate (const void *item)
|
||||
{
|
||||
struct file *f = (struct file *) item;
|
||||
f->intermediate = 1;
|
||||
}
|
||||
|
||||
/* Expand and parse each dependency line. */
|
||||
static void
|
||||
expand_deps (struct file *f)
|
||||
@ -644,13 +635,69 @@ expand_deps (struct file *f)
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the updating flag. */
|
||||
/* Add extra prereqs to the file in question. */
|
||||
|
||||
struct dep *
|
||||
expand_extra_prereqs (const struct variable *extra)
|
||||
{
|
||||
struct dep *prereqs = extra ? split_prereqs (variable_expand (extra->value)) : NULL;
|
||||
|
||||
for (struct dep *d = prereqs; d; d = d->next)
|
||||
{
|
||||
d->file = lookup_file (d->name);
|
||||
if (!d->file)
|
||||
d->file = enter_file (d->name);
|
||||
d->name = NULL;
|
||||
d->ignore_automatic_vars = 1;
|
||||
}
|
||||
|
||||
return prereqs;
|
||||
}
|
||||
|
||||
/* Perform per-file snap operations. */
|
||||
|
||||
static void
|
||||
reset_updating (const void *item)
|
||||
snap_file (const void *item, void *arg)
|
||||
{
|
||||
struct file *f = (struct file *) item;
|
||||
f->updating = 0;
|
||||
struct file *f = (struct file*)item;
|
||||
struct dep *prereqs = NULL;
|
||||
|
||||
/* If we're not doing second expansion then reset updating. */
|
||||
if (!second_expansion)
|
||||
f->updating = 0;
|
||||
|
||||
/* If .SECONDARY is set with no deps, mark all targets as intermediate. */
|
||||
if (all_secondary)
|
||||
f->intermediate = 1;
|
||||
|
||||
/* If .EXTRA_PREREQS is set, add them as ignored by automatic variables. */
|
||||
if (f->variables)
|
||||
prereqs = expand_extra_prereqs (lookup_variable_in_set (STRING_SIZE_TUPLE(".EXTRA_PREREQS"), f->variables->set));
|
||||
|
||||
else if (f->is_target)
|
||||
prereqs = copy_dep_chain (arg);
|
||||
|
||||
if (prereqs)
|
||||
{
|
||||
struct dep *d;
|
||||
for (d = prereqs; d; d = d->next)
|
||||
if (streq (f->name, dep_name (d)))
|
||||
/* Skip circular dependencies. */
|
||||
break;
|
||||
|
||||
if (d)
|
||||
/* We broke early: must have found a circular dependency. */
|
||||
free_dep_chain (prereqs);
|
||||
else if (!f->deps)
|
||||
f->deps = prereqs;
|
||||
else
|
||||
{
|
||||
d = f->deps;
|
||||
while (d->next)
|
||||
d = d->next;
|
||||
d->next = prereqs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* For each dependency of each file, make the 'struct dep' point
|
||||
@ -700,9 +747,6 @@ snap_deps (void)
|
||||
expand_deps (f);
|
||||
free (file_slot_0);
|
||||
}
|
||||
else
|
||||
/* We're not doing second expansion, so reset updating. */
|
||||
hash_map (&files, reset_updating);
|
||||
|
||||
/* Now manage all the special targets. */
|
||||
|
||||
@ -744,10 +788,7 @@ snap_deps (void)
|
||||
f2->intermediate = f2->secondary = 1;
|
||||
/* .SECONDARY with no deps listed marks *all* files that way. */
|
||||
else
|
||||
{
|
||||
all_secondary = 1;
|
||||
hash_map (&files, set_intermediate);
|
||||
}
|
||||
all_secondary = 1;
|
||||
|
||||
f = lookup_file (".EXPORT_ALL_VARIABLES");
|
||||
if (f != 0 && f->is_target)
|
||||
@ -779,6 +820,15 @@ snap_deps (void)
|
||||
if (f != 0 && f->is_target)
|
||||
not_parallel = 1;
|
||||
|
||||
{
|
||||
struct dep *prereqs = expand_extra_prereqs (lookup_variable (STRING_SIZE_TUPLE(".EXTRA_PREREQS")));
|
||||
|
||||
/* Perform per-file snap operations. */
|
||||
hash_map_arg(&files, snap_file, prereqs);
|
||||
|
||||
free_dep_chain (prereqs);
|
||||
}
|
||||
|
||||
#ifndef NO_MINUS_C_MINUS_O
|
||||
/* If .POSIX was defined, remove OUTPUT_OPTION to comply. */
|
||||
/* This needs more work: what if the user sets this in the makefile?
|
||||
|
@ -21,6 +21,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "hash.h"
|
||||
|
||||
struct commands;
|
||||
struct dep;
|
||||
struct variable;
|
||||
struct variable_set_list;
|
||||
|
||||
struct file
|
||||
{
|
||||
const char *name;
|
||||
@ -110,6 +115,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);
|
||||
struct dep *expand_extra_prereqs (const struct variable *extra);
|
||||
void remove_intermediates (int sig);
|
||||
void snap_deps (void);
|
||||
void rename_file (struct file *file, const char *name);
|
||||
|
@ -152,6 +152,7 @@ struct patdeps
|
||||
const char *pattern;
|
||||
struct file *file;
|
||||
unsigned int ignore_mtime : 1;
|
||||
unsigned int ignore_automatic_vars : 1;
|
||||
};
|
||||
|
||||
/* This structure stores information about pattern rules that we need
|
||||
@ -564,6 +565,7 @@ pattern_search (struct file *file, int archive,
|
||||
{
|
||||
++deps_found;
|
||||
d->ignore_mtime = dep->ignore_mtime;
|
||||
d->ignore_automatic_vars = dep->ignore_automatic_vars;
|
||||
}
|
||||
|
||||
/* We've used up this dep, so next time get a new one. */
|
||||
@ -723,6 +725,7 @@ pattern_search (struct file *file, int archive,
|
||||
|
||||
memset (pat, '\0', sizeof (struct patdeps));
|
||||
pat->ignore_mtime = d->ignore_mtime;
|
||||
pat->ignore_automatic_vars = d->ignore_automatic_vars;
|
||||
|
||||
DBS (DB_IMPLICIT,
|
||||
(is_rule
|
||||
@ -913,6 +916,7 @@ pattern_search (struct file *file, int archive,
|
||||
|
||||
dep = alloc_dep ();
|
||||
dep->ignore_mtime = pat->ignore_mtime;
|
||||
dep->ignore_automatic_vars = pat->ignore_automatic_vars;
|
||||
s = strcache_add (pat->name);
|
||||
if (recursions)
|
||||
dep->name = s;
|
||||
|
@ -1313,7 +1313,7 @@ main (int argc, char **argv, char **envp)
|
||||
{
|
||||
const char *features = "target-specific order-only second-expansion"
|
||||
" else-if shortest-stem undefine oneshell nocomment"
|
||||
" grouped-target"
|
||||
" grouped-target extra-prereqs"
|
||||
#ifndef NO_ARCHIVES
|
||||
" archives"
|
||||
#endif
|
||||
@ -2134,9 +2134,9 @@ main (int argc, char **argv, char **envp)
|
||||
|
||||
install_default_implicit_rules ();
|
||||
|
||||
/* Compute implicit rule limits. */
|
||||
/* Compute implicit rule limits and do magic for pattern rules. */
|
||||
|
||||
count_implicit_rule_limits ();
|
||||
snap_implicit_rules ();
|
||||
|
||||
/* Construct the listings of directories in VPATH lists. */
|
||||
|
||||
|
61
src/rule.c
61
src/rule.c
@ -60,36 +60,43 @@ struct file *suffix_file;
|
||||
|
||||
static size_t maxsuffix;
|
||||
|
||||
/* Compute the maximum dependency length and maximum number of
|
||||
dependencies of all implicit rules. Also sets the subdir
|
||||
flag for a rule when appropriate, possibly removing the rule
|
||||
completely when appropriate. */
|
||||
/* Compute the maximum dependency length and maximum number of dependencies of
|
||||
all implicit rules. Also sets the subdir flag for a rule when appropriate,
|
||||
possibly removing the rule completely when appropriate.
|
||||
|
||||
Add any global EXTRA_PREREQS here as well. */
|
||||
|
||||
void
|
||||
count_implicit_rule_limits (void)
|
||||
snap_implicit_rules (void)
|
||||
{
|
||||
char *name;
|
||||
size_t namelen;
|
||||
struct rule *rule;
|
||||
char *name = NULL;
|
||||
size_t namelen = 0;
|
||||
struct dep *prereqs = expand_extra_prereqs (lookup_variable (STRING_SIZE_TUPLE(".EXTRA_PREREQS")));
|
||||
unsigned int pre_deps = 0;
|
||||
|
||||
num_pattern_rules = max_pattern_targets = max_pattern_deps = 0;
|
||||
max_pattern_dep_length = 0;
|
||||
|
||||
name = 0;
|
||||
namelen = 0;
|
||||
rule = pattern_rules;
|
||||
while (rule != 0)
|
||||
for (struct dep *d = prereqs; d; d = d->next)
|
||||
{
|
||||
unsigned int ndeps = 0;
|
||||
struct dep *dep;
|
||||
struct rule *next = rule->next;
|
||||
size_t l = strlen (dep_name (d));
|
||||
if (l > max_pattern_dep_length)
|
||||
max_pattern_dep_length = l;
|
||||
++pre_deps;
|
||||
}
|
||||
|
||||
num_pattern_rules = max_pattern_targets = max_pattern_deps = 0;
|
||||
|
||||
for (struct rule *rule = pattern_rules; rule; rule = rule->next)
|
||||
{
|
||||
unsigned int ndeps = pre_deps;
|
||||
struct dep *lastdep = NULL;
|
||||
|
||||
++num_pattern_rules;
|
||||
|
||||
if (rule->num > max_pattern_targets)
|
||||
max_pattern_targets = rule->num;
|
||||
|
||||
for (dep = rule->deps; dep != 0; dep = dep->next)
|
||||
for (struct dep *dep = rule->deps; dep != 0; dep = dep->next)
|
||||
{
|
||||
const char *dname = dep_name (dep);
|
||||
size_t len = strlen (dname);
|
||||
@ -99,17 +106,20 @@ count_implicit_rule_limits (void)
|
||||
const char *p2;
|
||||
if (p == 0)
|
||||
p = strrchr (dname, ':');
|
||||
p2 = p != 0 ? strchr (dname, '%') : 0;
|
||||
p2 = p ? strchr (p, '%') : 0;
|
||||
#else
|
||||
const char *p = strrchr (dname, '/');
|
||||
const char *p2 = p != 0 ? strchr (dname, '%') : 0;
|
||||
const char *p2 = p ? strchr (p, '%') : 0;
|
||||
#endif
|
||||
ndeps++;
|
||||
|
||||
if (len > max_pattern_dep_length)
|
||||
max_pattern_dep_length = len;
|
||||
|
||||
if (p != 0 && p2 > p)
|
||||
if (!dep->next)
|
||||
lastdep = dep;
|
||||
|
||||
if (p2)
|
||||
{
|
||||
/* There is a slash before the % in the dep name.
|
||||
Extract the directory name. */
|
||||
@ -134,13 +144,20 @@ count_implicit_rule_limits (void)
|
||||
dep->changed = 0;
|
||||
}
|
||||
|
||||
if (prereqs)
|
||||
{
|
||||
if (lastdep)
|
||||
lastdep->next = copy_dep_chain (prereqs);
|
||||
else
|
||||
rule->deps = copy_dep_chain (prereqs);
|
||||
}
|
||||
|
||||
if (ndeps > max_pattern_deps)
|
||||
max_pattern_deps = ndeps;
|
||||
|
||||
rule = next;
|
||||
}
|
||||
|
||||
free (name);
|
||||
free_dep_chain (prereqs);
|
||||
}
|
||||
|
||||
/* Create a pattern rule from a suffix rule.
|
||||
|
@ -48,7 +48,7 @@ extern size_t max_pattern_dep_length;
|
||||
extern struct file *suffix_file;
|
||||
|
||||
|
||||
void count_implicit_rule_limits (void);
|
||||
void snap_implicit_rules (void);
|
||||
void convert_to_pattern (void);
|
||||
void install_pattern_rule (struct pspec *p, int terminal);
|
||||
void create_pattern_rule (const char **targets, const char **target_percents,
|
||||
|
151
tests/scripts/variables/EXTRA_PREREQS
Normal file
151
tests/scripts/variables/EXTRA_PREREQS
Normal file
@ -0,0 +1,151 @@
|
||||
# -*-perl-*-
|
||||
|
||||
$description = "Test the .EXTRA_PREREQS special variable.";
|
||||
$details = "";
|
||||
|
||||
# Simple global .EXTRA_PREREQS and automatic variable settings
|
||||
run_make_test('
|
||||
.EXTRA_PREREQS = tick tack
|
||||
.PHONY: all
|
||||
all: ; @echo ${.EXTRA_PREREQS}/$@/$</$^/$?/$+/$|/$*/
|
||||
tick tack: ; @echo $@
|
||||
',
|
||||
'', "tick\ntack\ntick tack/all///////\n");
|
||||
|
||||
# Global .EXTRA_PREREQS and pattern rules
|
||||
run_make_test('
|
||||
.EXTRA_PREREQS = tick tack
|
||||
a%: ; @echo ${.EXTRA_PREREQS}/$@/$</$^/$?/$+/$|/$*/
|
||||
tick tack: ; @echo $@
|
||||
',
|
||||
'all', "tick\ntack\ntick tack/all//////ll/\n");
|
||||
|
||||
# Simple target-specific .EXTRA_PREREQS and automatic variable settings
|
||||
run_make_test('
|
||||
.PHONY: all
|
||||
all: ; @echo ${.EXTRA_PREREQS}/$@/$</$^/$?/$+/$|/$*/
|
||||
all: .EXTRA_PREREQS = tick tack
|
||||
tick tack: ; @echo $@
|
||||
',
|
||||
'', "tick\ntack\ntick tack/all///////\n");
|
||||
|
||||
# Simple pattern-specific .EXTRA_PREREQS and automatic variable settings
|
||||
# This is not currently supported :-/
|
||||
if (0) {
|
||||
run_make_test('
|
||||
.PHONY: all
|
||||
all: ; @echo ${.EXTRA_PREREQS}/$@/$</$^/$?/$+/$|/$*/
|
||||
a%: .EXTRA_PREREQS = tick tack
|
||||
tick tack: ; @echo $@
|
||||
',
|
||||
'', "tick\ntack\ntick tack/all///////\n");
|
||||
}
|
||||
|
||||
touch('hi');
|
||||
|
||||
# Basic test target specific .EXTRA_PREREQS:
|
||||
run_make_test('
|
||||
DEPENDENCY_ONLY_PREREQUISITES = ho hey
|
||||
OTHER_PREREQUISITES := foo bar baz
|
||||
target: .EXTRA_PREREQS := hi ${DEPENDENCY_ONLY_PREREQUISITES}
|
||||
target: ${OTHER_PREREQUISITES} ; @echo ${.EXTRA_PREREQS} $^
|
||||
.PHONY: target ${DEPENDENCY_ONLY_PREREQUISITES} ${OTHER_PREREQUISITES}
|
||||
${DEPENDENCY_ONLY_PREREQUISITES} ${OTHER_PREREQUISITES}: ; @echo $@
|
||||
',
|
||||
'', "foo\nbar\nbaz\nho\nhey\nhi ho hey foo bar baz\n");
|
||||
|
||||
# Test target specific .EXTRA_PREREQS and pattern rules:
|
||||
run_make_test('
|
||||
all: target.dst
|
||||
DEPENDENCY_ONLY_PREREQUISITES = ho hey
|
||||
target.dst: .EXTRA_PREREQS := hi ${DEPENDENCY_ONLY_PREREQUISITES}
|
||||
%.dst: %.src ; @echo ${.EXTRA_PREREQS} $^
|
||||
.PHONY: ${DEPENDENCY_ONLY_PREREQUISITES} target.src
|
||||
${DEPENDENCY_ONLY_PREREQUISITES} target.src: ; @echo $@
|
||||
',
|
||||
'', "target.src\nho\nhey\nhi ho hey target.src\n");
|
||||
|
||||
# Test that global .EXTRA_PREREQS are built first:
|
||||
run_make_test('
|
||||
.EXTRA_PREREQS = hi ho hey
|
||||
OTHER_PREREQUISITES := foo bar baz
|
||||
target: ${OTHER_PREREQUISITES} ; @echo ${.EXTRA_PREREQS} $^
|
||||
.PHONY: target ${.EXTRA_PREREQS} ${OTHER_PREREQUISITES}
|
||||
${.EXTRA_PREREQS} ${OTHER_PREREQUISITES}: ; @echo $@
|
||||
',
|
||||
'', "hi\nho\nhey\nfoo\nbar\nbaz\nhi ho hey foo bar baz\n");
|
||||
|
||||
# Test that target specific .EXTRA_PREREQS override global .EXTRA_PREREQS:
|
||||
run_make_test('
|
||||
.EXTRA_PREREQS = tick tack
|
||||
DEPENDENCY_ONLY_PREREQUISITES = ho hey
|
||||
OTHER_PREREQUISITES := foo bar baz
|
||||
target: .EXTRA_PREREQS := hi ${DEPENDENCY_ONLY_PREREQUISITES}
|
||||
target: ${OTHER_PREREQUISITES} ; @echo ${.EXTRA_PREREQS} $^
|
||||
.PHONY: target ${DEPENDENCY_ONLY_PREREQUISITES} ${OTHER_PREREQUISITES} ${.EXTRA_PREREQS}
|
||||
${DEPENDENCY_ONLY_PREREQUISITES} ${OTHER_PREREQUISITES} ${.EXTRA_PREREQS}: ; @echo $@
|
||||
',
|
||||
'', "tick\ntack\nfoo\nbar\nbaz\nho\nhey\nhi ho hey foo bar baz\n");
|
||||
|
||||
# Cleanup:
|
||||
unlink('hi');
|
||||
|
||||
# Test error reporting of global .EXTRA_PREREQS:
|
||||
run_make_test('
|
||||
.EXTRA_PREREQS = tick tack
|
||||
.PHONY: all
|
||||
all: ; @echo ${.EXTRA_PREREQS} $^
|
||||
',
|
||||
'', "#MAKE#: *** No rule to make target 'tick', needed by 'all'. Stop.", 512);
|
||||
|
||||
# Test error reporting of global .EXTRA_PREREQS and keep-going:
|
||||
run_make_test('
|
||||
.EXTRA_PREREQS = tick tack
|
||||
.PHONY: all
|
||||
all: ; @echo ${.EXTRA_PREREQS} $^
|
||||
',
|
||||
'-k', "#MAKE#: *** No rule to make target 'tick', needed by 'all'.\n#MAKE#: *** No rule to make target 'tack', needed by 'all'.\n#MAKE#: Target 'all' not remade because of errors.", 512);
|
||||
|
||||
# Test error reporting of target specific .EXTRA_PREREQS and keep-going:
|
||||
run_make_test('
|
||||
all: .EXTRA_PREREQS = tick tack
|
||||
.PHONY: all
|
||||
all: ; @echo ${.EXTRA_PREREQS} $^
|
||||
',
|
||||
'-k',
|
||||
"#MAKE#: *** No rule to make target 'tick', needed by 'all'.
|
||||
#MAKE#: *** No rule to make target 'tack', needed by 'all'.
|
||||
#MAKE#: Target 'all' not remade because of errors.\n", 512);
|
||||
|
||||
# Test wildcard
|
||||
|
||||
touch('tick', 'tack');
|
||||
|
||||
run_make_test('
|
||||
.EXTRA_PREREQS = *ck
|
||||
.PHONY: all tick tack
|
||||
all: ; @echo ${.EXTRA_PREREQS} $^
|
||||
tick tack: ; @echo $@
|
||||
',
|
||||
'', "tack\ntick\ntack tick\n");
|
||||
|
||||
run_make_test('
|
||||
.PHONY: all tick tack
|
||||
all: ; @echo ${.EXTRA_PREREQS} $^
|
||||
all: .EXTRA_PREREQS = *ck
|
||||
tick tack: ; @echo $@
|
||||
',
|
||||
'', "tack\ntick\ntack tick\n");
|
||||
|
||||
run_make_test('
|
||||
.PHONY: tick tack
|
||||
a%: ; @echo ${.EXTRA_PREREQS} $^
|
||||
.EXTRA_PREREQS = *ck
|
||||
tick tack: ; @echo $@
|
||||
',
|
||||
'all', "tack\ntick\ntack tick\n");
|
||||
|
||||
unlink('tick', 'tack');
|
||||
|
||||
# This tells the test driver that the perl test script executed properly.
|
||||
1;
|
Loading…
Reference in New Issue
Block a user