summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstrap.conf1
-rw-r--r--src/config.h-vms.template3
-rw-r--r--src/config.h.W32.template3
-rw-r--r--src/implicit.c106
-rw-r--r--src/job.c2
-rw-r--r--src/makeint.h5
-rw-r--r--src/misc.c8
-rw-r--r--src/remake.c10
-rw-r--r--src/rule.c65
-rw-r--r--src/rule.h2
10 files changed, 146 insertions, 59 deletions
diff --git a/bootstrap.conf b/bootstrap.conf
index 7c4c9ab7..bd37f1b9 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -49,5 +49,6 @@ fdl
findprog-in
getloadavg
host-cpu-c-abi
+mempcpy
strerror
make-glob"
diff --git a/src/config.h-vms.template b/src/config.h-vms.template
index 7cd393db..62daac2d 100644
--- a/src/config.h-vms.template
+++ b/src/config.h-vms.template
@@ -324,6 +324,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the <memory.h> header file. */
/* #undef HAVE_MEMORY_H */
+/* Define to 1 if you have the `mempcpy' function. */
+/* #undef HAVE_MEMPCPY */
+
/* Define to 1 if you have the <ndir.h> header file. */
/* #undef HAVE_NDIR_H */
diff --git a/src/config.h.W32.template b/src/config.h.W32.template
index f847be87..bd3b4763 100644
--- a/src/config.h.W32.template
+++ b/src/config.h.W32.template
@@ -177,6 +177,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
+/* Define to 1 if you have the `mempcpy' function. */
+/* #undef HAVE_MEMPCPY */
+
/* Define to 1 if you have the 'mkstemp' function. */
/* #undef HAVE_MKSTEMP */
diff --git a/src/implicit.c b/src/implicit.c
index 3c7fba76..7505ff69 100644
--- a/src/implicit.c
+++ b/src/implicit.c
@@ -54,6 +54,9 @@ try_implicit_rule (struct file *file, unsigned int depth)
_("Looking for archive-member implicit rule for '%s'.\n"));
if (pattern_search (file, 1, depth, 0))
return 1;
+ DBS (DB_IMPLICIT,
+ (_("No archive-member implicit rule found for '%s'.\n"),
+ file->name));
}
#endif
@@ -309,7 +312,9 @@ pattern_search (struct file *file, int archive,
don't use it here. */
if (rule->in_use)
{
- DBS (DB_IMPLICIT, (_("Avoiding implicit rule recursion.\n")));
+ DBS (DB_IMPLICIT,
+ (_("Avoiding implicit rule recursion for rule '%s'.\n"),
+ get_rule_defn (rule)));
continue;
}
@@ -432,6 +437,8 @@ pattern_search (struct file *file, int archive,
for (intermed_ok = 0; intermed_ok < 2; ++intermed_ok)
{
pat = deplist;
+ if (intermed_ok)
+ DBS (DB_IMPLICIT, (_("Trying harder.\n")));
/* Try each pattern rule till we find one that applies. If it does,
expand its dependencies (as substituted) and chain them in DEPS. */
@@ -480,6 +487,10 @@ pattern_search (struct file *file, int archive,
}
}
+ DBS (DB_IMPLICIT,
+ (_("Trying pattern rule '%s' with stem '%.*s'.\n"),
+ get_rule_defn (rule), (int) stemlen, stem));
+
if (stemlen + (check_lastslash ? pathlen : 0) > GET_PATH_MAX)
{
DBS (DB_IMPLICIT, (_("Stem too long: '%s%.*s'.\n"),
@@ -488,9 +499,6 @@ pattern_search (struct file *file, int archive,
continue;
}
- DBS (DB_IMPLICIT, (_("Trying pattern rule with stem '%.*s'.\n"),
- (int) stemlen, stem));
-
if (!check_lastslash)
{
memcpy (stem_str, stem, stemlen);
@@ -712,9 +720,10 @@ pattern_search (struct file *file, int archive,
/* Go through the nameseq and handle each as a prereq name. */
for (d = dl; d != 0; d = d->next)
{
- struct dep *expl_d;
- struct file *f;
+ struct file *df;
int is_rule = d->name == dep_name (dep);
+ int explicit;
+ int exists = -1;
if (file_impossible_p (d->name))
{
@@ -723,9 +732,11 @@ pattern_search (struct file *file, int archive,
second pass either since we know that will fail. */
DBS (DB_IMPLICIT,
(is_rule
- ? _("Rejecting impossible rule prerequisite '%s'.\n")
- : _("Rejecting impossible implicit prerequisite '%s'.\n"),
- d->name));
+ ? _("Rejecting rule '%s' due to impossible rule"
+ " prerequisite '%s'.\n")
+ : _("Rejecting rule '%s' due to impossible implicit"
+ " prerequisite '%s'.\n"),
+ get_rule_defn (rule), d->name));
tryrules[ri].rule = 0;
failed = 1;
@@ -742,38 +753,41 @@ pattern_search (struct file *file, int archive,
? _("Trying rule prerequisite '%s'.\n")
: _("Trying implicit prerequisite '%s'.\n"), d->name));
- /* If this prereq is also explicitly mentioned for FILE,
- skip all tests below since it must be built no matter
- which implicit rule we choose. */
-
- for (expl_d = file->deps; expl_d != 0; expl_d = expl_d->next)
- if (streq (dep_name (expl_d), d->name))
- break;
- if (expl_d != 0)
- {
- (pat++)->name = d->name;
- continue;
- }
+ df = lookup_file (d->name);
+
+ /* If we found a file for the dep, set its intermediate flag.
+ df->is_explicit is set when the dep file is mentioned
+ explicitly on some other rule. d->is_explicit is set when
+ the dep file is mentioned explicitly on this rule. E.g.:
+ %.x : %.y ; ...
+ then:
+ one.x:
+ one.y: # df->is_explicit
+ vs.
+ one.x: one.y # d->is_explicit
+ */
+ if (df && !df->is_explicit && !d->is_explicit)
+ df->intermediate = 1;
+
+ /* If the pattern prereq is also explicitly mentioned for
+ FILE, skip all tests below since it must be built no
+ matter which implicit rule we choose. */
+ explicit = df || (exists = file_exists_p (d->name)) != 0;
+ if (!explicit)
+ for (struct dep *dp = file->deps; dp != 0; dp = dp->next)
+ if (streq (d->name, dep_name (dp)))
+ {
+ explicit = 1;
+ break;
+ }
- /* f->is_explicit is set when this file is mentioned
- explicitly on some other rule. d->is_explicit is set when
- this file is mentioned explicitly on this rule. */
- f = lookup_file (d->name);
- if (f && !f->is_explicit && !d->is_explicit)
- f->intermediate = 1;
-
- /* The DEP->changed flag says that this dependency resides
- in a nonexistent directory. So we normally can skip
- looking for the file. However, if CHECK_LASTSLASH is
- set, then the dependency file we are actually looking for
- is in a different directory (the one gotten by prepending
- FILENAME's directory), so it might actually exist. */
-
- /* @@ dep->changed check is disabled. */
- if (f /* || ((!dep->changed || check_lastslash) */
- || file_exists_p (d->name))
+ if (explicit)
{
(pat++)->name = d->name;
+ if (exists > 0)
+ DBS (DB_IMPLICIT, (_("Found '%s'.\n"), d->name));
+ else
+ DBS (DB_IMPLICIT, (_("'%s' ought to exist.\n"), d->name));
continue;
}
@@ -785,7 +799,7 @@ pattern_search (struct file *file, int archive,
if (vname)
{
DBS (DB_IMPLICIT,
- (_("Found prerequisite '%s' as VPATH '%s'\n"),
+ (_("Found prerequisite '%s' as VPATH '%s'.\n"),
d->name, vname));
(pat++)->name = d->name;
continue;
@@ -833,6 +847,14 @@ pattern_search (struct file *file, int archive,
/* A dependency of this rule does not exist. Therefore, this
rule fails. */
+ if (intermed_ok)
+ DBS (DB_IMPLICIT,
+ (_("Rejecting rule '%s' "
+ "due to impossible prerequisite '%s'.\n"),
+ get_rule_defn (rule), d->name));
+ else
+ DBS (DB_IMPLICIT, (_("Not found '%s'.\n"), d->name));
+
failed = 1;
break;
}
@@ -1042,5 +1064,11 @@ pattern_search (struct file *file, int archive,
free (tryrules);
free (deplist);
+ if (rule)
+ DBS (DB_IMPLICIT, (_("Found implicit rule '%s' for '%s'.\n"),
+ get_rule_defn (rule), filename));
+ else
+ DBS (DB_IMPLICIT, (_("No implicit rule found for '%s'.\n"), filename));
+
return rule != 0;
}
diff --git a/src/job.c b/src/job.c
index ee59b95b..54fadf00 100644
--- a/src/job.c
+++ b/src/job.c
@@ -922,7 +922,7 @@ reap_children (int block, int err)
to fork/exec but I don't want to bother with that. Just do the
best we can. */
- EINTRLOOP(r, stat(c->cmd_name, &st));
+ EINTRLOOP(r, stat (c->cmd_name, &st));
if (r < 0)
e = strerror (errno);
else if (S_ISDIR(st.st_mode) || !(st.st_mode & S_IXUSR))
diff --git a/src/makeint.h b/src/makeint.h
index eb78b402..15dc07d5 100644
--- a/src/makeint.h
+++ b/src/makeint.h
@@ -671,6 +671,11 @@ int strncasecmp (const char *s1, const char *s2, int n);
# endif
#endif
+#if !HAVE_MEMPCPY
+/* Create our own, in misc.c */
+void *mempcpy (void *dest, const void *src, size_t n);
+#endif
+
#define OUTPUT_SYNC_NONE 0
#define OUTPUT_SYNC_LINE 1
#define OUTPUT_SYNC_TARGET 2
diff --git a/src/misc.c b/src/misc.c
index 3072952c..f400135b 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -846,3 +846,11 @@ get_path_max (void)
return value;
}
#endif
+
+#if !HAVE_MEMPCPY
+void *
+mempcpy (void *dest, const void *src, size_t n)
+{
+ return (char *) memcpy (dest, src, n) + n;
+}
+#endif
diff --git a/src/remake.c b/src/remake.c
index 9b71ce61..bd6d8e51 100644
--- a/src/remake.c
+++ b/src/remake.c
@@ -509,10 +509,7 @@ update_file_1 (struct file *file, unsigned int depth)
if (!file->phony && file->cmds == 0 && !file->tried_implicit)
{
- if (try_implicit_rule (file, depth))
- DBF (DB_IMPLICIT, _("Found an implicit rule for '%s'.\n"));
- else
- DBF (DB_IMPLICIT, _("No implicit rule found for '%s'.\n"));
+ try_implicit_rule (file, depth);
file->tried_implicit = 1;
}
if (file->cmds == 0 && !file->is_target
@@ -1045,10 +1042,7 @@ check_dep (struct file *file, unsigned int depth,
if (!file->phony && file->cmds == 0 && !file->tried_implicit)
{
- if (try_implicit_rule (file, depth))
- DBF (DB_IMPLICIT, _("Found an implicit rule for '%s'.\n"));
- else
- DBF (DB_IMPLICIT, _("No implicit rule found for '%s'.\n"));
+ try_implicit_rule (file, depth);
file->tried_implicit = 1;
}
if (file->cmds == 0 && !file->is_target
diff --git a/src/rule.c b/src/rule.c
index 7efca58b..16aec7fe 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -59,6 +59,55 @@ struct file *suffix_file;
/* Maximum length of a suffix. */
static size_t maxsuffix;
+
+/* Return the rule definition: space separated rule targets, followed by
+ either a colon or two colons in the case of a terminal rule, followed by
+ space separated rule prerequisites, followed by a pipe, followed by
+ order-only prerequisites, if present. */
+
+const char *get_rule_defn (struct rule *r)
+{
+ if (r->_defn == NULL)
+ {
+ unsigned int k;
+ ptrdiff_t len = 8; // Reserve for ":: ", " | " and the null terminator.
+ char *p;
+ const char *sep = "";
+ const struct dep *dep, *ood = 0;
+
+ for (k = 0; k < r->num; ++k)
+ len += r->lens[k] + 1; // Add one for a space.
+
+ for (dep = r->deps; dep; dep = dep->next)
+ len += strlen (dep_name (dep)) + 1; // Add one for a space.
+
+ p = r->_defn = xmalloc (len);
+ for (k = 0; k < r->num; ++k, sep = " ")
+ p = mempcpy (mempcpy (p, sep, strlen (sep)), r->targets[k], r->lens[k]);
+ *p++ = ':';
+ if (r->terminal)
+ *p++ = ':';
+
+ /* Copy all normal dependencies; note any order-only deps. */
+ for (dep = r->deps; dep; dep = dep->next)
+ if (dep->ignore_mtime == 0)
+ p = mempcpy (mempcpy (p, " ", 1), dep_name (dep),
+ strlen (dep_name (dep)));
+ else if (ood == 0)
+ ood = dep;
+
+ /* Copy order-only deps, if we have any. */
+ for (sep = " | "; ood; ood = ood->next, sep = " ")
+ if (ood->ignore_mtime)
+ p = mempcpy (mempcpy (p, sep, strlen (sep)), dep_name (ood),
+ strlen (dep_name (ood)));
+ *p = '\0';
+ assert (p - r->_defn < len);
+ }
+
+ return r->_defn;
+}
+
/* Compute the maximum dependency length and maximum number of dependencies of
all implicit rules. Also sets the subdir flag for a rule when appropriate,
@@ -398,6 +447,7 @@ install_pattern_rule (struct pspec *p, int terminal)
r->targets = xmalloc (sizeof (const char *));
r->suffixes = xmalloc (sizeof (const char *));
r->lens = xmalloc (sizeof (unsigned int));
+ r->_defn = NULL;
r->lens[0] = (unsigned int) strlen (p->target);
r->targets[0] = p->target;
@@ -439,6 +489,7 @@ freerule (struct rule *rule, struct rule *lastrule)
free ((void *)rule->targets);
free ((void *)rule->suffixes);
free (rule->lens);
+ free ((void *) rule->_defn);
/* We can't free the storage for the commands because there
are ways that they could be in more than one place:
@@ -488,6 +539,7 @@ create_pattern_rule (const char **targets, const char **target_percents,
r->targets = targets;
r->suffixes = target_percents;
r->lens = xmalloc (n * sizeof (unsigned int));
+ r->_defn = NULL;
for (i = 0; i < n; ++i)
{
@@ -505,17 +557,8 @@ create_pattern_rule (const char **targets, const char **target_percents,
static void /* Useful to call from gdb. */
print_rule (struct rule *r)
{
- unsigned int i;
-
- for (i = 0; i < r->num; ++i)
- {
- fputs (r->targets[i], stdout);
- putchar ((i + 1 == r->num) ? ':' : ' ');
- }
- if (r->terminal)
- putchar (':');
-
- print_prereqs (r->deps);
+ fputs (get_rule_defn (r), stdout);
+ putchar ('\n');
if (r->cmds != 0)
print_commands (r->cmds);
diff --git a/src/rule.h b/src/rule.h
index 120a6827..c18ae518 100644
--- a/src/rule.h
+++ b/src/rule.h
@@ -25,6 +25,7 @@ struct rule
const char **suffixes; /* Suffixes (after '%') of each target. */
struct dep *deps; /* Dependencies of the rule. */
struct commands *cmds; /* Commands to execute. */
+ char *_defn; /* Definition of the rule. */
unsigned short num; /* Number of targets. */
char terminal; /* If terminal (double-colon). */
char in_use; /* If in use by a parent pattern_search. */
@@ -54,4 +55,5 @@ void install_pattern_rule (struct pspec *p, int terminal);
void create_pattern_rule (const char **targets, const char **target_percents,
unsigned short num, int terminal, struct dep *deps,
struct commands *commands, int override);
+const char *get_rule_defn (struct rule *rule);
void print_rule_data_base (void);