(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

208
remake.c
View File

@ -1,5 +1,5 @@
/* 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.
GNU Make is free software; you can redistribute it and/or modify
@ -96,108 +96,115 @@ update_goal_chain (goals, makefiles)
g = goals;
while (g != 0)
{
unsigned int ocommands_started;
int x;
time_t mtime = MTIME (g->file);
check_renamed (g->file);
if (makefiles)
/* 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)
{
if (g->file->cmd_target)
unsigned int ocommands_started;
int x;
time_t mtime = MTIME (file);
check_renamed (file);
if (makefiles)
{
touch_flag = t;
question_flag = q;
just_print_flag = n;
if (file->cmd_target)
{
touch_flag = t;
question_flag = q;
just_print_flag = n;
}
else
touch_flag = question_flag = just_print_flag = 0;
}
else
touch_flag = question_flag = just_print_flag = 0;
/* Save the old value of `commands_started' so we can compare
later. It will be incremented when any commands are
actually run. */
ocommands_started = commands_started;
x = update_file (file, makefiles ? 1 : 0);
check_renamed (file);
/* Set the goal's `changed' flag if any commands were started
by calling update_file above. We check this flag below to
decide when to give an "up to date" diagnostic. */
g->changed += commands_started - ocommands_started;
stop = 0;
if (x != 0 || file->updated)
{
/* If STATUS was not already 1, set it to 1 if
updating failed, or to 0 if updating succeeded.
Leave STATUS as it is if no updating was done. */
if (status < 1)
{
if (file->update_status != 0)
{
/* Updating failed. */
status = 1;
stop = !keep_going_flag && !makefiles;
}
else if (MTIME (file) != mtime)
{
/* Updating was done. If this is a makefile and
just_print_flag or question_flag is set
(meaning -n or -q was given and this file was
specified as a command-line target), don't
change STATUS. If STATUS is changed, we will
get re-exec'd, and fall into an infinite loop. */
if (!makefiles
|| (!just_print_flag && !question_flag))
status = 0;
if (makefiles && file->dontcare)
/* This is a default makefile. Stop remaking. */
stop = 1;
}
}
}
/* 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;
}
/* Save the old value of `commands_started' so we can compare later.
It will be incremented when any commands are actually run. */
ocommands_started = commands_started;
x = update_file (g->file, makefiles ? 1 : 0);
check_renamed (g->file);
/* Set the goal's `changed' flag if any commands were started
by calling update_file above. We check this flag below to
decide when to give an "up to date" diagnostic. */
g->changed += commands_started - ocommands_started;
if (x != 0 || g->file->updated)
if (stop || !any_not_updated)
{
int stop = 0;
/* If we have found nothing whatever to do for the goal,
print a message saying nothing needs doing. */
/* If STATUS was not already 1, set it to 1 if
updating failed, or to 0 if updating succeeded.
Leave STATUS as it is if no updating was done. */
if (status < 1)
if (!makefiles
/* If the update_status is zero, we updated successfully
or not at all. G->changed will have been set above if
any commands were actually started for this goal. */
&& file->update_status == 0 && !g->changed
/* Never give a message under -s or -q. */
&& !silent_flag && !question_flag)
{
if (g->file->update_status != 0)
{
/* Updating failed. */
status = 1;
stop = !keep_going_flag && !makefiles;
}
else if (MTIME (g->file) != mtime)
{
/* Updating was done.
If this is a makefile and just_print_flag or
question_flag is set (meaning -n or -q was given
and this file was specified as a command-line target),
don't change STATUS. If STATUS is changed, we will
get re-exec'd, and fall into an infinite loop. */
if (!makefiles || (!just_print_flag && !question_flag))
status = 0;
if (makefiles && g->file->dontcare)
/* This is a default makefile. Stop remaking. */
stop = 1;
}
}
if (stop || g->file->prev == 0)
{
/* If we have found nothing whatever to do for the goal,
print a message saying nothing needs doing. */
if (!makefiles
/* If the update_status is zero, we updated successfully
or not at all. G->changed will have been set above if
any commands were actually started for this goal. */
&& g->file->update_status == 0 && !g->changed
/* Never give a message under -s or -q. */
&& !silent_flag && !question_flag)
{
if (g->file->phony || g->file->cmds == 0)
message ("Nothing to be done for `%s'.",
g->file->name);
else
message ("`%s' is up to date.", g->file->name);
fflush (stdout);
}
/* This goal is finished. Remove it from the chain. */
if (lastgoal == 0)
goals = g->next;
if (file->phony || file->cmds == 0)
message ("Nothing to be done for `%s'.",
file->name);
else
lastgoal->next = g->next;
/* Free the storage. */
free ((char *) g);
g = lastgoal == 0 ? goals : lastgoal->next;
message ("`%s' is up to date.", file->name);
fflush (stdout);
}
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;
/* This goal is finished. Remove it from the chain. */
if (lastgoal == 0)
goals = g->next;
else
lastgoal->next = g->next;
/* Free the storage. */
free ((char *) g);
g = lastgoal == 0 ? goals : lastgoal->next;
if (stop)
break;
@ -241,7 +248,7 @@ update_file (file, depth)
register int status = 0;
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);
check_renamed (f);
@ -390,6 +397,8 @@ update_file_1 (file, depth)
{
register struct file *f = d->file;
if (f->double_colon)
f = f->double_colon;
do
{
running |= (f->command_state == cs_running
@ -425,6 +434,8 @@ update_file_1 (file, depth)
{
register struct file *f = d->file;
if (f->double_colon)
f = f->double_colon;
do
{
running |= (f->command_state == cs_running
@ -612,11 +623,18 @@ notice_finished_file (file)
if (!file->phony)
{
struct file *f;
if (just_print_flag || question_flag
|| (file->is_target && file->cmds == 0))
file->last_mtime = NEW_MTIME;
else
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)
@ -925,6 +943,8 @@ f_mtime (file, search)
}
/* Store the mtime into all the entries for this file. */
if (file->double_colon)
file = file->double_colon;
do
{
file->last_mtime = mtime;