(update_goal_chain): Do inner loop on double-colon entries.

(update_file): Use FILE->double_colon pointer to find all entries.
(f_mtime): Likewise.
(notice_finished_file): Propagate mtime change to all entries.
This commit is contained in:
Roland McGrath 1994-04-05 10:37:12 +00:00
parent 4e4b1ed670
commit 6dc8e442f2

View File

@ -1,5 +1,5 @@
/* Basic dependency engine for GNU Make. /* Basic dependency engine for GNU Make.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify GNU Make is free software; you can redistribute it and/or modify
@ -95,15 +95,22 @@ update_goal_chain (goals, makefiles)
lastgoal = 0; lastgoal = 0;
g = goals; g = goals;
while (g != 0) while (g != 0)
{
/* Iterate over all double-colon entries for this file. */
struct file *file = g->file;
int stop, any_not_updated = 0;
for (file = g->file->double_colon ? g->file->double_colon : g->file;
file != NULL;
file = file->prev)
{ {
unsigned int ocommands_started; unsigned int ocommands_started;
int x; int x;
time_t mtime = MTIME (g->file); time_t mtime = MTIME (file);
check_renamed (g->file); check_renamed (file);
if (makefiles) if (makefiles)
{ {
if (g->file->cmd_target) if (file->cmd_target)
{ {
touch_flag = t; touch_flag = t;
question_flag = q; question_flag = q;
@ -113,51 +120,61 @@ update_goal_chain (goals, makefiles)
touch_flag = question_flag = just_print_flag = 0; touch_flag = question_flag = just_print_flag = 0;
} }
/* Save the old value of `commands_started' so we can compare later. /* Save the old value of `commands_started' so we can compare
It will be incremented when any commands are actually run. */ later. It will be incremented when any commands are
actually run. */
ocommands_started = commands_started; ocommands_started = commands_started;
x = update_file (g->file, makefiles ? 1 : 0); x = update_file (file, makefiles ? 1 : 0);
check_renamed (g->file); check_renamed (file);
/* Set the goal's `changed' flag if any commands were started /* Set the goal's `changed' flag if any commands were started
by calling update_file above. We check this flag below to by calling update_file above. We check this flag below to
decide when to give an "up to date" diagnostic. */ decide when to give an "up to date" diagnostic. */
g->changed += commands_started - ocommands_started; g->changed += commands_started - ocommands_started;
if (x != 0 || g->file->updated) stop = 0;
if (x != 0 || file->updated)
{ {
int stop = 0;
/* If STATUS was not already 1, set it to 1 if /* If STATUS was not already 1, set it to 1 if
updating failed, or to 0 if updating succeeded. updating failed, or to 0 if updating succeeded.
Leave STATUS as it is if no updating was done. */ Leave STATUS as it is if no updating was done. */
if (status < 1) if (status < 1)
{ {
if (g->file->update_status != 0) if (file->update_status != 0)
{ {
/* Updating failed. */ /* Updating failed. */
status = 1; status = 1;
stop = !keep_going_flag && !makefiles; stop = !keep_going_flag && !makefiles;
} }
else if (MTIME (g->file) != mtime) else if (MTIME (file) != mtime)
{ {
/* Updating was done. /* Updating was done. If this is a makefile and
If this is a makefile and just_print_flag or just_print_flag or question_flag is set
question_flag is set (meaning -n or -q was given (meaning -n or -q was given and this file was
and this file was specified as a command-line target), specified as a command-line target), don't
don't change STATUS. If STATUS is changed, we will change STATUS. If STATUS is changed, we will
get re-exec'd, and fall into an infinite loop. */ get re-exec'd, and fall into an infinite loop. */
if (!makefiles || (!just_print_flag && !question_flag)) if (!makefiles
|| (!just_print_flag && !question_flag))
status = 0; status = 0;
if (makefiles && g->file->dontcare) if (makefiles && file->dontcare)
/* This is a default makefile. Stop remaking. */ /* This is a default makefile. Stop remaking. */
stop = 1; stop = 1;
} }
} }
}
if (stop || g->file->prev == 0) /* Keep track if any double-colon entry is not finished.
When they are all finished, the goal is finished. */
any_not_updated |= !file->updated;
if (stop)
break;
}
if (stop || !any_not_updated)
{ {
/* If we have found nothing whatever to do for the goal, /* If we have found nothing whatever to do for the goal,
print a message saying nothing needs doing. */ print a message saying nothing needs doing. */
@ -166,15 +183,15 @@ update_goal_chain (goals, makefiles)
/* If the update_status is zero, we updated successfully /* If the update_status is zero, we updated successfully
or not at all. G->changed will have been set above if or not at all. G->changed will have been set above if
any commands were actually started for this goal. */ any commands were actually started for this goal. */
&& g->file->update_status == 0 && !g->changed && file->update_status == 0 && !g->changed
/* Never give a message under -s or -q. */ /* Never give a message under -s or -q. */
&& !silent_flag && !question_flag) && !silent_flag && !question_flag)
{ {
if (g->file->phony || g->file->cmds == 0) if (file->phony || file->cmds == 0)
message ("Nothing to be done for `%s'.", message ("Nothing to be done for `%s'.",
g->file->name); file->name);
else else
message ("`%s' is up to date.", g->file->name); message ("`%s' is up to date.", file->name);
fflush (stdout); fflush (stdout);
} }
@ -188,16 +205,6 @@ update_goal_chain (goals, makefiles)
free ((char *) g); free ((char *) g);
g = lastgoal == 0 ? goals : lastgoal->next; g = lastgoal == 0 ? goals : lastgoal->next;
}
else if (g->file->updated)
/* This instance of the target is done being updated.
Go to the next instance (:: rule).
update_file cycles through all instances, but under -j,
update_file can return while the file is running,
then reap_children can change its command state and
updated flag, leaving G->file done, but some of its
other instances needing work. */
g->file = g->file->prev;
if (stop) if (stop)
break; break;
@ -241,7 +248,7 @@ update_file (file, depth)
register int status = 0; register int status = 0;
register struct file *f; register struct file *f;
for (f = file; f != 0; f = f->prev) for (f = file->double_colon ? file->double_colon : file; f != 0; f = f->prev)
{ {
status |= update_file_1 (f, depth); status |= update_file_1 (f, depth);
check_renamed (f); check_renamed (f);
@ -390,6 +397,8 @@ update_file_1 (file, depth)
{ {
register struct file *f = d->file; register struct file *f = d->file;
if (f->double_colon)
f = f->double_colon;
do do
{ {
running |= (f->command_state == cs_running running |= (f->command_state == cs_running
@ -425,6 +434,8 @@ update_file_1 (file, depth)
{ {
register struct file *f = d->file; register struct file *f = d->file;
if (f->double_colon)
f = f->double_colon;
do do
{ {
running |= (f->command_state == cs_running running |= (f->command_state == cs_running
@ -612,11 +623,18 @@ notice_finished_file (file)
if (!file->phony) if (!file->phony)
{ {
struct file *f;
if (just_print_flag || question_flag if (just_print_flag || question_flag
|| (file->is_target && file->cmds == 0)) || (file->is_target && file->cmds == 0))
file->last_mtime = NEW_MTIME; file->last_mtime = NEW_MTIME;
else else
file->last_mtime = 0; file->last_mtime = 0;
/* Propagate the change of modification time to all the double-colon
entries for this file. */
for (f = file->double_colon; f != 0; f = f->next)
f->last_mtime = file->last_mtime;
} }
if (file->update_status != -1) if (file->update_status != -1)
@ -925,6 +943,8 @@ f_mtime (file, search)
} }
/* Store the mtime into all the entries for this file. */ /* Store the mtime into all the entries for this file. */
if (file->double_colon)
file = file->double_colon;
do do
{ {
file->last_mtime = mtime; file->last_mtime = mtime;