diff --git a/src/implicit.c b/src/implicit.c
index 7505ff6..fa18f66 100644
--- a/src/implicit.c
+++ b/src/implicit.c
@@ -22,9 +22,11 @@ this program. If not, see . */
#include "variable.h"
#include "job.h" /* struct child, used inside commands.h */
#include "commands.h" /* set_file_variables */
+#include
static int pattern_search (struct file *file, int archive,
- unsigned int depth, unsigned int recursions);
+ unsigned int depth, unsigned int recursions,
+ int allow_compat_rules);
/* For a FILE which has no commands specified, try to figure out some
from the implicit pattern rules.
@@ -42,7 +44,7 @@ try_implicit_rule (struct file *file, unsigned int depth)
(the archive search omits the archive name), it is more specific and
should come first. */
- if (pattern_search (file, 0, depth, 0))
+ if (pattern_search (file, 0, depth, 0, 0))
return 1;
#ifndef NO_ARCHIVES
@@ -52,7 +54,7 @@ try_implicit_rule (struct file *file, unsigned int depth)
{
DBF (DB_IMPLICIT,
_("Looking for archive-member implicit rule for '%s'.\n"));
- if (pattern_search (file, 1, depth, 0))
+ if (pattern_search (file, 1, depth, 0, 0))
return 1;
DBS (DB_IMPLICIT,
(_("No archive-member implicit rule found for '%s'.\n"),
@@ -204,7 +206,8 @@ stemlen_compare (const void *v1, const void *v2)
static int
pattern_search (struct file *file, int archive,
- unsigned int depth, unsigned int recursions)
+ unsigned int depth, unsigned int recursions,
+ int allow_compat_rules)
{
/* Filename we are searching for a rule for. */
const char *filename = archive ? strchr (file->name, '(') : file->name;
@@ -255,6 +258,7 @@ pattern_search (struct file *file, int archive,
int specific_rule_matched = 0;
unsigned int ri; /* uninit checks OK */
+ int found_compat_rule = 0;
struct rule *rule;
char *pathdir = NULL;
@@ -722,10 +726,12 @@ pattern_search (struct file *file, int archive,
{
struct file *df;
int is_rule = d->name == dep_name (dep);
- int explicit;
- int exists = -1;
+ int explicit = 0;
+ struct dep *dp = 0;
- if (file_impossible_p (d->name))
+ /* When searching for compat rules, try files marked
+ * "impossible" on the prior, no compat rules run. */
+ if (allow_compat_rules == 0 && file_impossible_p (d->name))
{
/* If this prereq has already been ruled "impossible",
then the rule fails. Don't bother trying it on the
@@ -772,25 +778,56 @@ pattern_search (struct file *file, int archive,
/* 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 (df && df->is_target)
+ /* This prerequisite is mentioned explicitly as a target of
+ * some rule. */
+ explicit = 1;
+ else
+ for (dp = file->deps; dp != 0; dp = dp->next)
if (streq (d->name, dep_name (dp)))
- {
- explicit = 1;
- break;
- }
+ break;
+
+ /* If dp is set, this prerequisite is mentioned explicitly as
+ * a prerequisite of the current target. */
- if (explicit)
+ if (explicit || dp)
{
(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));
+ DBS (DB_IMPLICIT, (_("'%s' ought to exist.\n"), d->name));
+ continue;
+ }
+
+ if (file_exists_p (d->name))
+ {
+ (pat++)->name = d->name;
+ DBS (DB_IMPLICIT, (_("Found '%s'.\n"), d->name));
+ continue;
+ }
+
+ if (df && allow_compat_rules)
+ {
+ (pat++)->name = d->name;
+ DBS (DB_IMPLICIT,
+ (_("Using compatibility rule '%s' due to '%s'.\n"),
+ get_rule_defn (rule), d->name));
continue;
}
+ if (df)
+ {
+ /* This prerequisite is mentioned explicitly as a
+ * prerequisite on some rule, but it is not a
+ * prerequisite of the current target. Therefore, this
+ * prerequisite does not qualify as ought-to-exist. Keep
+ * note of this rule and continue the search. If a better
+ * suitable rule is not found, then use this rule. */
+ DBS (DB_IMPLICIT,
+ (_("Prerequisite '%s' of rule '%s' does not qualify"
+ " as ought to exist.\n"),
+ d->name, get_rule_defn (rule)));
+ found_compat_rule = 1;
+ }
+
/* This code, given FILENAME = "lib/foo.o", dependency name
"lib/foo.c", and VPATH=src, searches for
"src/lib/foo.c". */
@@ -825,7 +862,8 @@ pattern_search (struct file *file, int archive,
if (pattern_search (int_file,
0,
depth + 1,
- recursions + 1))
+ recursions + 1,
+ allow_compat_rules))
{
pat->pattern = int_file->name;
int_file->name = d->name;
@@ -886,6 +924,12 @@ pattern_search (struct file *file, int archive,
break;
rule = 0;
+
+ /* If compatibility rules are allowed, do not try intermediates.
+ * Intermediates were already tried on the prior, no compat rules run.
+ * */
+ if (allow_compat_rules)
+ break;
}
/* RULE is nil if the loop went through the list but everything failed. */
@@ -938,8 +982,8 @@ pattern_search (struct file *file, int archive,
f->pat_searched = imf->pat_searched;
f->also_make = imf->also_make;
f->is_target = 1;
- f->notintermediate = imf->notintermediate;
- f->intermediate = !(pat->is_explicit || f->notintermediate);
+ f->notintermediate |= imf->notintermediate;
+ f->intermediate |= !(pat->is_explicit || f->notintermediate);
f->tried_implicit = 1;
imf = lookup_file (pat->pattern);
@@ -1065,10 +1109,20 @@ pattern_search (struct file *file, int archive,
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));
+ {
+ DBS (DB_IMPLICIT, (_("Found implicit rule '%s' for '%s'.\n"),
+ get_rule_defn (rule), filename));
+ return 1;
+ }
- return rule != 0;
+ if (found_compat_rule)
+ {
+ DBS (DB_IMPLICIT, (_("Searching for a compatibility rule for '%s'.\n"),
+ filename));
+ assert (allow_compat_rules == 0);
+ return pattern_search (file, archive, depth, recursions, 1);
+ }
+
+ DBS (DB_IMPLICIT, (_("No implicit rule found for '%s'.\n"), filename));
+ return 0;
}