Avoid infinite loops when remaking makefiles not only

for Makefile targets but also for targets they depend on.
This commit is contained in:
Max Khon 2009-04-07 19:49:38 +00:00
parent 82b70c3e01
commit c2502d78e1
4 changed files with 26 additions and 41 deletions

View File

@ -81,6 +81,7 @@ extern Boolean noExecute; /* True if should execute nothing */
extern Boolean allPrecious; /* True if every target is precious */
extern Boolean is_posix; /* .POSIX target seen */
extern Boolean mfAutoDeps; /* .MAKEFILEDEPS target seen */
extern Boolean remakingMakefiles; /* True if remaking makefiles is in progress */
/* True if should continue on unaffected portions of the graph
* when have an error in one portion */

View File

@ -124,6 +124,7 @@ Lst create = Lst_Initializer(create);
Boolean allPrecious; /* .PRECIOUS given on line by itself */
Boolean is_posix; /* .POSIX target seen */
Boolean mfAutoDeps; /* .MAKEFILEDEPS target seen */
Boolean remakingMakefiles; /* True if remaking makefiles is in progress */
Boolean beSilent; /* -s flag */
Boolean beVerbose; /* -v flag */
Boolean beQuiet; /* -Q flag */
@ -731,41 +732,6 @@ Remake_Makefiles(void)
DEBUGF(MAKE, ("Checking %s...", gn->name));
Suff_FindDeps(gn);
/*
* ! dependencies as well as
* dependencies with .FORCE, .EXEC and .PHONY attributes
* are skipped to prevent infinite loops
*/
if (gn->type & (OP_FORCE | OP_EXEC | OP_PHONY)) {
DEBUGF(MAKE, ("skipping (force, exec or phony).\n",
gn->name));
continue;
}
/*
* Skip :: targets that have commands and no children
* because such targets are always out-of-date
*/
if ((gn->type & OP_DOUBLEDEP) &&
!Lst_IsEmpty(&gn->commands) &&
Lst_IsEmpty(&gn->children)) {
DEBUGF(MAKE, ("skipping (doubledep, no sources "
"and has commands).\n"));
continue;
}
/*
* Skip targets without sources and without commands
*/
if (Lst_IsEmpty(&gn->commands) &&
Lst_IsEmpty(&gn->children)) {
DEBUGF(MAKE,
("skipping (no sources and no commands).\n"));
continue;
}
DEBUGF(MAKE, ("\n"));
/*
* -t, -q and -n has no effect unless the makefile is
* specified as one of the targets explicitly in the
@ -787,7 +753,9 @@ Remake_Makefiles(void)
* Check and remake the makefile
*/
mtime = Dir_MTime(gn);
remakingMakefiles = TRUE;
Compat_Make(gn, gn);
remakingMakefiles = FALSE;
/*
* Restore -t, -q and -n behaviour

View File

@ -1629,7 +1629,7 @@ To prevent infinite loops the following source Makefile targets are ignored:
.Bl -bullet
.It
.Ic ::
targets that have no prerequisites but have commands
targets that have no prerequisites
.It
.Ic !
targets

View File

@ -211,11 +211,15 @@ Make_OODate(GNode *gn)
} else {
DEBUGF(MAKE, (".EXEC node..."));
}
oodate = TRUE;
} else if ((gn->mtime < gn->cmtime) ||
((gn->cmtime == 0) &&
((gn->mtime==0) || (gn->type & OP_DOUBLEDEP)))) {
if (remakingMakefiles) {
DEBUGF(MAKE, ("skipping (remaking makefiles)..."));
oodate = FALSE;
} else {
oodate = TRUE;
}
} else if (gn->mtime < gn->cmtime ||
(gn->cmtime == 0 && (gn->mtime == 0 || (gn->type & OP_DOUBLEDEP)))) {
/*
* A node whose modification time is less than that of its
* youngest child or that has no children (cmtime == 0) and
@ -226,12 +230,24 @@ Make_OODate(GNode *gn)
if (gn->mtime < gn->cmtime) {
DEBUGF(MAKE, ("modified before source (%s)...",
gn->cmtime_gn ? gn->cmtime_gn->path : "???"));
oodate = TRUE;
} else if (gn->mtime == 0) {
DEBUGF(MAKE, ("non-existent and no sources..."));
if (remakingMakefiles && Lst_IsEmpty(&gn->commands)) {
DEBUGF(MAKE, ("skipping (no commands and remaking makefiles)..."));
oodate = FALSE;
} else {
oodate = TRUE;
}
} else {
DEBUGF(MAKE, (":: operator and no sources..."));
if (remakingMakefiles) {
DEBUGF(MAKE, ("skipping (remaking makefiles)..."));
oodate = FALSE;
} else {
oodate = TRUE;
}
}
oodate = TRUE;
} else
oodate = FALSE;