summaryrefslogtreecommitdiff
path: root/src/rule.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2020-01-02 05:08:06 -0500
committerPaul Smith <psmith@gnu.org>2020-01-03 02:08:59 -0500
commit4e12a5fa458e8e6a28d6728d5d14a9dbc25f6bef (patch)
tree4c5301da843bcec66104e548ee72d43b017335b5 /src/rule.c
parente56243fe57710124d4e5eb6c05179065f49d1333 (diff)
downloadmake-git-4e12a5fa458e8e6a28d6728d5d14a9dbc25f6bef.tar.gz
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.
Diffstat (limited to 'src/rule.c')
-rw-r--r--src/rule.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/src/rule.c b/src/rule.c
index 6b01aa33..6645a2f7 100644
--- a/src/rule.c
+++ b/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)
+ {
+ 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 = 0;
- struct dep *dep;
- struct rule *next = 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.