Compare commits

...

10 Commits

Author SHA1 Message Date
Tim Magill
646aeb50a1 * remake.c:
(update_file_1):
	(check_dep): fixed problem with double colon rules and circular
	precursor detection.

	* remake.c (update_file_1): simplified handling of files with no
	command into a single block.

	* remake.c (notice_finished_file): fixed obsolete comment.
2000-03-14 04:30:07 +00:00
Tim Magill
fed90f1fa8 * remake.c (update_goal_chain): re-arranged logic so that it makes
more sense.  After update_file(), the target status is used to
	handle the goal and possibly remove it from the goal chain.

	* remake.c (update_file): If -q we can bail as soon as we detect
	that something needs to be remade.
2000-03-12 19:50:20 +00:00
Tim Magill
6a1a4343f3 more cleanup 2000-03-11 23:27:28 +00:00
Tim Magill
e27c3fc91b more cleanup 2000-03-11 23:19:51 +00:00
Tim Magill
9f3539c4ae removed excess loop in update_goal_chain() 2000-03-01 04:46:33 +00:00
Tim Magill
1b40ffb900 changed return type of recursive update functions 2000-02-21 04:17:36 +00:00
Tim Magill
0d621b0627 removed essentially unused variable from update_goal_chain 2000-02-21 02:02:58 +00:00
Tim Magill
5ed230d3f8 cleaned up usage of filedef->update_status 2000-02-13 04:24:24 +00:00
Tim Magill
b0e3148933 minor cleanup 2000-02-12 22:32:30 +00:00
Tim Magill
3b4369f170 removed updated member from struct filedef 2000-02-09 05:49:41 +00:00
7 changed files with 359 additions and 250 deletions

116
ChangeLog
View File

@@ -1,3 +1,119 @@
2000-03-13 Tim Magill <magill@gate.net>
* remake.c:
(update_file_1):
(check_dep): fixed problem with double colon rules and circular
precursor detection.
2000-03-12 Tim Magill <magill@gate.net>
* remake.c (update_goal_chain): re-arranged logic so that it makes
more sense. After update_file(), the target status is used to
handle the goal and possibly remove it from the goal chain.
* remake.c (update_file_1): simplified handling of files with no
command into a single block.
* remake.c (notice_finished_file): fixed obsolete comment.
* remake.c (update_file): If -q we can bail as soon as we detect
that something needs to be remade.
2000-03-11 Tim Magill <magill@gate.net>
* remake.c
(update_file): If not -k, we can bail when a failure is detected.
If we don't, its possible that dependecies of double_colon rules
will get built after a failure has been detected.
(update_goal_chain): removed unused updating_makefiles
(update_file_1): cleaned up post remake_file() handling
2000-02-29 Tim Magill <magill@gate.net>
* remake.c (update_goal_chain): eliminated double colon loop.
update_file() handles the double colon logic, so
update_goal_chain() doesn't have to.
* remake.c (update_file):
(update_file_1): Moved consedered test to update_file_1() so
update_file() can more easily return a target_state_t which
represents the state of the entire double colon rule.
2000-02-20 Tim Magill <magill@gate.net>
* remake.c (check_dep):
(update_file_1):
(update_goal_chain):
(check_dep): Changed return value of target updating functions to
be enum target_state_t. This allows each caller to know the state
of the target being processed after each call. Thus,
update_goal_chain() can know from the return value of
update_file() whether or not a target has completed and can be
removed from the goal chain.
* remake.c (update_goal_chain): removed variable
ocommands_started, it was essentially unused.
2000-02-12 Tim Magill <magill@gate.net>
* remake.c (update_file_1):
(notice_finished_file):
(remake_file):
* main.c (main):
* job.c (reap_children):
(start_job_command):
* file.c (enter_file)
(remove_intermediates):
(print_file):
* filedef.h: converted update_status field from a short int, to an
unsigned int :1. previously, update status indicated whether the
file had actually executed any commands, won, lost, or lost under
-q conditions. command_state indicates more clearly whether or
not any commands have been executed for this file. lost or lost
under -q conditions can be determined by a combination of
question_flag and lost. Thus, update_status needs only indicate
won or lost.
* implicit.c (try_implicit_rule):
* remake.c (check_dep):
* remake.c (update_file_1):
move setting of tried_implicit into try_implicit_rule(). It is
only called in two places and the flag is set immediately after.
* remake.c (update_file_1): collapsed if statement based on
file->command_state into switch statment which immediately
follows. Removed code that could not be reached.
* remake.c (update_file): advance f pointer so as not to consider
same file twice after breaking loop.
* file.c (rehash_file): replaced hard coded check_renamed loop
with standard macro. seemed like the right thing to do.
2000-02-09 Tim Magill <magill@gate.net>
Started branch for cleaning up internal make structure regarding
recursion paths. Branch name is filedef-cleanup and was started
from a point on the mainline at filedef-cleanup-base. either tags
are suitable for cvs commands.
* file.c, filedef.h, main.c, remake.c (updated): Removed updated
member from 'struct filedef'. filedef->command_state fully
contains the same information and more.
2000-02-07 Paul D. Smith <psmith@gnu.org>
For += target-specific variables we need to remember which

27
file.c
View File

@@ -166,7 +166,7 @@ enter_file (name)
new = (struct file *) xmalloc (sizeof (struct file));
bzero ((char *) new, sizeof (struct file));
new->name = new->hname = name;
new->update_status = -1;
new->update_status = 0; /* assume the file won */
if (f == 0)
{
@@ -199,8 +199,7 @@ rehash_file (file, name)
register unsigned int oldhash;
register char *n;
while (file->renamed != 0)
file = file->renamed;
check_renamed(file);
/* Find the hash values of the old and new names. */
@@ -361,7 +360,6 @@ in favor of those for `%s'."),
MERGE (precious);
MERGE (tried_implicit);
MERGE (updating);
MERGE (updated);
MERGE (is_target);
MERGE (cmd_target);
MERGE (phony);
@@ -397,7 +395,7 @@ remove_intermediates (sig)
&& !f->secondary)
{
int status;
if (f->update_status == -1)
if (f->command_state == cs_not_started)
/* If nothing would have created this file yet,
don't print an "rm" command for it. */
continue;
@@ -659,7 +657,7 @@ print_file (f)
file_timestamp_sprintf (buf, f->last_mtime);
printf (_("# Last modified %s\n"), buf);
}
puts (f->updated
puts ((f->command_state == cs_finished)
? _("# File has been updated.") : _("# File has not been updated."));
switch (f->command_state)
{
@@ -670,26 +668,19 @@ print_file (f)
puts (_("# Dependencies commands running (THIS IS A BUG)."));
break;
case cs_not_started:
break;
case cs_finished:
switch (f->update_status)
{
case -1:
break;
case 0:
/* file won */
puts (_("# Successfully updated."));
break;
case 1:
assert (question_flag);
puts (_("# Needs to be updated (-q is set)."));
/* file lost */
puts (question_flag ? _("# Needs to be updated (-q is set).")
:_("# Failed to be updated."));
break;
case 2:
puts (_("# Failed to be updated."));
break;
default:
puts (_("# Invalid value in `update_status' member!"));
fflush (stdout);
fflush (stderr);
abort ();
}
break;
default:

View File

@@ -60,9 +60,6 @@ struct file
the same file. Otherwise this is null. */
struct file *double_colon;
short int update_status; /* Status of the last attempt to update,
or -1 if none has been made. */
enum /* State of the commands. */
{ /* Note: It is important that cs_not_started be zero. */
cs_not_started, /* Not yet started. */
@@ -71,12 +68,15 @@ struct file
cs_finished /* Commands finished. */
} command_state ENUM_BITFIELD (2);
unsigned int update_status:1; /* update status signifies only
whether the file won or lost */
unsigned int precious:1; /* Non-0 means don't delete file on quit */
unsigned int tried_implicit:1; /* Nonzero if have searched
for implicit rule for making
this file; don't search again. */
unsigned int updating:1; /* Nonzero while updating deps of this file */
unsigned int updated:1; /* Nonzero if this file has been remade. */
unsigned int is_target:1; /* Nonzero if file is described as target. */
unsigned int cmd_target:1; /* Nonzero if file was given on cmd line. */
unsigned int phony:1; /* Nonzero if this is a phony file

View File

@@ -37,6 +37,7 @@ try_implicit_rule (file, depth)
struct file *file;
unsigned int depth;
{
int ret = 0;
DBF (DB_IMPLICIT, _("Looking for an implicit rule for `%s'.\n"));
/* The order of these searches was previously reversed. My logic now is
@@ -45,21 +46,24 @@ try_implicit_rule (file, depth)
should come first. */
if (pattern_search (file, 0, depth, 0))
return 1;
ret = 1;
#ifndef NO_ARCHIVES
/* If this is an archive member reference, use just the
archive member name to search for implicit rules. */
if (ar_name (file->name))
else if (ar_name (file->name))
{
DBF (DB_IMPLICIT,
_("Looking for archive-member implicit rule for `%s'.\n"));
if (pattern_search (file, 1, depth, 0))
return 1;
{
ret = 1;
}
}
#endif
return 0;
file->tried_implicit = 1;
return ret;
}

6
job.c
View File

@@ -665,7 +665,7 @@ reap_children (block, err)
delete non-precious targets, and abort. */
static int delete_on_error = -1;
child_error (c->file->name, exit_code, exit_sig, coredump, 0);
c->file->update_status = 2;
c->file->update_status = 1;
if (delete_on_error == -1)
{
struct file *f = lookup_file (".DELETE_ON_ERROR");
@@ -693,7 +693,7 @@ reap_children (block, err)
Since there are more commands that wanted to be run,
the target was not completely remade. So we treat
this as if a command had failed. */
c->file->update_status = 2;
c->file->update_status = 1;
}
else
{
@@ -1250,7 +1250,7 @@ start_job_command (child)
return;
error:
child->file->update_status = 2;
child->file->update_status = 1;
notice_finished_file (child->file);
return;
}

25
main.c
View File

@@ -1254,7 +1254,6 @@ int main (int argc, char ** argv)
/* Make sure the temporary file will not be remade. */
stdin_nm = savestring (name, sizeof (name) -1);
f = enter_file (stdin_nm);
f->updated = 1;
f->update_status = 0;
f->command_state = cs_finished;
/* Can't be intermediate, or it'll be removed too early for
@@ -1518,7 +1517,6 @@ int main (int argc, char ** argv)
{
f = enter_command_line_file (*p);
f->last_mtime = f->mtime_before_update = (FILE_TIMESTAMP) 1;
f->updated = 1;
f->update_status = 0;
f->command_state = cs_finished;
}
@@ -1606,17 +1604,11 @@ int main (int argc, char ** argv)
switch (update_goal_chain (read_makefiles, 1))
{
case 1:
default:
#define BOGUS_UPDATE_STATUS 0
assert (BOGUS_UPDATE_STATUS);
break;
case -1:
/* Did nothing. */
break;
case 2:
case 1:
/* Failed to update. Figure out if we care. */
{
/* Nonzero if any makefile was successfully remade. */
@@ -1633,7 +1625,7 @@ int main (int argc, char ** argv)
again to print an error. */
d->file->considered = 0;
if (d->file->updated)
if (d->file->command_state == cs_finished)
{
/* This makefile was updated. */
if (d->file->update_status == 0)
@@ -1836,18 +1828,19 @@ int main (int argc, char ** argv)
{
case -1:
/* Nothing happened. */
/* FALL THRU */
case 0:
/* Updated successfully. */
status = EXIT_SUCCESS;
break;
case 2:
/* Updating failed. POSIX.2 specifies exit status >1 for this;
but in VMS, there is only success and failure. */
status = EXIT_FAILURE ? 2 : EXIT_FAILURE;
break;
case 1:
if (question_flag)
/* We are under -q and would run some commands. */
status = EXIT_FAILURE;
status = EXIT_FAILURE;
else
/* Updating failed. POSIX.2 specifies exit status >1 for this;
but in VMS, there is only success and failure. */
status = EXIT_FAILURE ? 2 : EXIT_FAILURE;
break;
default:
abort ();

415
remake.c
View File

@@ -43,12 +43,39 @@ Boston, MA 02111-1307, USA. */
extern int try_implicit_rule PARAMS ((struct file *file, unsigned int depth));
/* this enum encapsulates the return status of the recursive update
functions. Note: these values are important so that the state of
precursors can be or'ed together */
typedef enum {
ts_done = 0, /* all precursors and target are complete */
ts_incomplete = 1, /* some precursor or target is still running */
ts_failed = 3, /* some precursor or target failed */
ts_sentinal /* make ANSI happy with non trailing , */
} target_state_t;
/* the test for circular dependencies is based just on the 'updating'
bit in 'struct file'. However double colon targets have seperate
'struct file's. Therefore, we will lose if we don't notice that a
double colon targets are really the same file. Use the 'struct
file' at the base of the double colon chain. */
#define set_updating(file) (((file)->double_colon ? \
(file)->double_colon : (file))->updating = 1)
#define clr_updating(file) (((file)->double_colon ? \
(file)->double_colon : (file))->updating = 0)
#define tst_updating(file) (((file)->double_colon ? \
(file)->double_colon : (file))->updating)
/* Incremented when a command is started (under -n, when one would be). */
unsigned int commands_started = 0;
static int update_file PARAMS ((struct file *file, unsigned int depth));
static int update_file_1 PARAMS ((struct file *file, unsigned int depth));
static int check_dep PARAMS ((struct file *file, unsigned int depth, FILE_TIMESTAMP this_mtime, int *must_make_ptr));
static target_state_t update_file PARAMS ((struct file *file, unsigned int depth));
static target_state_t update_file_1 PARAMS ((struct file *file, unsigned int depth));
static target_state_t check_dep PARAMS ((struct file *file, unsigned int depth, FILE_TIMESTAMP this_mtime, int *must_make_ptr));
static int touch_file PARAMS ((struct file *file));
static void remake_file PARAMS ((struct file *file));
static FILE_TIMESTAMP name_mtime PARAMS ((char *name));
@@ -62,8 +89,6 @@ static int library_search PARAMS ((char **lib, FILE_TIMESTAMP *mtime_ptr));
should only make one goal at a time and return as soon as one goal whose
`changed' member is nonzero is successfully made. */
/* We need to know this "lower down" for correct error handling. */
static int updating_makefiles = 0;
int
update_goal_chain (goals, makefiles)
@@ -74,10 +99,6 @@ update_goal_chain (goals, makefiles)
unsigned int j = job_slots;
int status = -1;
updating_makefiles = makefiles;
#define MTIME(file) (makefiles ? file_mtime_no_search (file) \
: file_mtime (file))
/* Duplicate the chain so we can remove things from it. */
@@ -117,103 +138,73 @@ update_goal_chain (goals, makefiles)
{
/* Iterate over all double-colon entries for this file. */
struct file *file;
int stop = 0, any_not_updated = 0;
target_state_t target_state;
for (file = g->file->double_colon ? g->file->double_colon : g->file;
file != NULL;
file = file->prev)
target_state = ts_done;
file = g->file;
check_renamed (file);
if (makefiles)
{
unsigned int ocommands_started;
int x;
check_renamed (file);
if (makefiles)
if (file->cmd_target)
{
if (file->cmd_target)
{
touch_flag = t;
question_flag = q;
just_print_flag = n;
}
else
touch_flag = question_flag = just_print_flag = 0;
touch_flag = t;
question_flag = q;
just_print_flag = n;
}
/* 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;
/* If we updated a file and 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. */
stop = 0;
if ((x != 0 || file->updated) && status < 1)
{
if (file->update_status != 0)
{
/* Updating failed, or -q triggered. The STATUS value
tells our caller which. */
status = file->update_status;
/* If -q just triggered, stop immediately. It doesn't
matter how much more we run, since we already know
the answer to return. */
stop = (!keep_going_flag && !question_flag
&& !makefiles);
}
else
{
FILE_TIMESTAMP mtime = MTIME (file);
check_renamed (file);
if (file->updated && g->changed &&
mtime != file->mtime_before_update)
{
/* 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
enter 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;
else
touch_flag = question_flag = just_print_flag = 0;
}
/* Reset FILE since it is null at the end of the loop. */
file = g->file;
commands_started = 0;
if (stop || !any_not_updated)
target_state = 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 ? 1 : 0;
/* process the file according to its return */
switch (target_state)
{
/* If we have found nothing whatever to do for the goal,
print a message saying nothing needs doing. */
case ts_failed:
/* Bail early? */
if (!keep_going_flag && !question_flag && !makefiles)
return 1;
status = 1; /* mark status failed, keep going */
/* -k, Fall Though !!! */
case ts_done:
{
FILE_TIMESTAMP mtime =
(makefiles ? file_mtime_no_search (file) : file_mtime (file));
check_renamed (file);
if (g->changed && mtime != file->mtime_before_update)
{
/* 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
enter an infinite loop. */
if (status < 0)
{
if (!makefiles || (!just_print_flag && !question_flag))
status = 0;
}
}
}
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
&& !file->update_status && !g->changed
/* Never give a message under -s or -q. */
&& !silent_flag && !question_flag)
message (1, ((file->phony || file->cmds == 0)
@@ -221,24 +212,27 @@ update_goal_chain (goals, makefiles)
: _("`%s' is up to date.")),
file->name);
/* This goal is finished. Remove it from the chain. */
case ts_incomplete:
break; /* do nothing */
}
/* advance to next target in goal chain */
if (target_state == ts_incomplete)
{
lastgoal = g;
g = g->next;
}
else
{
if (lastgoal == 0)
goals = g->next;
else
lastgoal->next = g->next;
/* Free the storage. */
free ((char *) g);
free (g);
g = lastgoal == 0 ? goals : lastgoal->next;
if (stop)
break;
}
else
{
lastgoal = g;
g = g->next;
}
}
@@ -258,9 +252,10 @@ update_goal_chain (goals, makefiles)
return status;
}
/* If FILE is not up to date, execute the commands for it.
Return 0 if successful, 1 if unsuccessful;
but with some flag settings, just call `exit' if unsuccessful.
/* If FILE is not up to date, execute the commands for it. Return
ts_done if FILE has completed successfully, ts_incomplete if FILE
or any of its precursors are incomplete, or ts_failed if FILE or
any of its precursors failed.
DEPTH is the depth in recursions of this function.
We increment it during the consideration of our dependencies,
@@ -270,36 +265,32 @@ update_goal_chain (goals, makefiles)
If there are multiple double-colon entries for FILE,
each is considered in turn. */
static int
static target_state_t
update_file (file, depth)
struct file *file;
unsigned int depth;
{
register int status = 0;
register target_state_t status = ts_done;
register struct file *f;
f = file->double_colon ? file->double_colon : file;
/* Prune the dependency graph: if we've already been here on _this_
pass through the dependency graph, we don't have to go any further.
We won't reap_children until we start the next pass, so no state
change is possible below here until then. */
if (f->considered == considered)
{
DBF (DB_VERBOSE, _("Pruning file `%s'.\n"));
return 0;
}
/* This loop runs until we start commands for a double colon rule, or until
the chain is exhausted. */
for (; f != 0; f = f->prev)
{
f->considered = considered;
status |= update_file_1 (f, depth);
check_renamed (f);
if (status != 0 && !keep_going_flag)
if (status == ts_failed)
{
if (!keep_going_flag || question_flag)
return ts_failed;
else
break;
}
if (status == ts_incomplete)
break;
if (f->command_state == cs_running
@@ -307,65 +298,88 @@ update_file (file, depth)
{
/* Don't run the other :: rules for this
file until this rule is finished. */
status = 0;
status = ts_incomplete;
break;
}
}
/* Process the remaining rules in the double colon chain so they're marked
considered. Start their prerequisites, too. */
for (; f != 0 ; f = f->prev)
for (f = (f ? f->prev : 0); f != 0 ; f = f->prev)
{
struct dep *d;
f->considered = considered;
for (d = f->deps; d != 0; d = d->next)
status |= update_file (d->file, depth + 1);
if ((status |= update_file (d->file, depth + 1)) == ts_failed)
{
if (!keep_going_flag || question_flag)
return ts_failed;
}
}
return status;
}
/* Consider a single `struct file' and update it as appropriate. */
/* Consider a single `struct file' and update it as appropriate.
static int
Return ts_done if FILE has completed successfully, ts_incomplete if
FILE or any of its precursors are incomplete, or ts_failed if FILE
or any of its precursors failed.
*/
static target_state_t
update_file_1 (file, depth)
struct file *file;
unsigned int depth;
{
register FILE_TIMESTAMP this_mtime;
int noexist, must_make, deps_changed;
int dep_status = 0;
target_state_t dep_status = ts_done;
register struct dep *d, *lastd;
int running = 0;
/* Prune the dependency graph: if we've already been here on _this_
pass through the dependency graph, we don't have to go any further.
We won't reap_children until we start the next pass, so no state
change is possible below here until then. */
if (file->considered == considered)
{
DBF (DB_VERBOSE, _("Pruning file `%s'.\n"));
if (file->command_state == cs_finished)
{
return file->update_status ? ts_failed : ts_done;
}
return ts_incomplete;
}
file->considered = considered;
DBF (DB_VERBOSE, _("Considering target file `%s'.\n"));
if (file->updated)
{
if (file->update_status > 0)
{
DBF (DB_VERBOSE,
_("Recently tried and failed to update file `%s'.\n"));
return file->update_status;
}
DBF (DB_VERBOSE, _("File `%s' was considered already.\n"));
return 0;
}
switch (file->command_state)
{
case cs_not_started:
case cs_deps_running:
break;
case cs_running:
DBF (DB_VERBOSE, _("Still updating file `%s'.\n"));
return 0;
return ts_incomplete;
case cs_finished:
DBF (DB_VERBOSE, _("Finished updating file `%s'.\n"));
return file->update_status;
if (file->update_status != 0)
{
DBF (DB_VERBOSE,
_("Recently tried and failed to update file `%s'.\n"));
return ts_failed;
}
DBF (DB_VERBOSE, _("File `%s' was considered already.\n"));
return ts_done;
default:
abort ();
}
@@ -373,7 +387,7 @@ update_file_1 (file, depth)
++depth;
/* Notice recursive update of the same file. */
file->updating = 1;
set_updating(file);
/* Looking at the file's modtime beforehand allows the possibility
that its name may be changed by a VPATH search, and thus it may
@@ -383,28 +397,30 @@ update_file_1 (file, depth)
this_mtime = file_mtime (file);
check_renamed (file);
noexist = this_mtime == (FILE_TIMESTAMP) -1;
must_make = noexist = this_mtime == (FILE_TIMESTAMP) -1;
if (noexist)
DBF (DB_BASIC, _("File `%s' does not exist.\n"));
must_make = noexist;
/* If file was specified as a target with no commands,
come up with some default commands. */
if (!file->phony && file->cmds == 0 && !file->tried_implicit)
if (file->cmds == 0)
{
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"));
file->tried_implicit = 1;
}
if (file->cmds == 0 && !file->is_target
&& default_file != 0 && default_file->cmds != 0)
{
DBF (DB_IMPLICIT, _("Using default commands for `%s'.\n"));
file->cmds = default_file->cmds;
if (!file->phony && !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"));
}
if (!file->is_target
&& default_file != 0 && default_file->cmds != 0)
{
DBF (DB_IMPLICIT, _("Using default commands for `%s'.\n"));
file->cmds = default_file->cmds;
}
}
/* Update all non-intermediate files we depend on, if necessary,
@@ -421,7 +437,7 @@ update_file_1 (file, depth)
mtime = file_mtime (d->file);
check_renamed (d->file);
if (d->file->updating)
if (tst_updating(d->file))
{
error (NILF, _("Circular %s <- %s dependency dropped."),
file->name, d->file->name);
@@ -453,7 +469,7 @@ update_file_1 (file, depth)
while (f != 0);
}
if (dep_status != 0 && !keep_going_flag)
if (dep_status == ts_failed && !keep_going_flag)
break;
if (!running)
@@ -490,7 +506,7 @@ update_file_1 (file, depth)
while (f != 0);
}
if (dep_status != 0 && !keep_going_flag)
if (dep_status == ts_failed && !keep_going_flag)
break;
if (!running)
@@ -499,7 +515,7 @@ update_file_1 (file, depth)
}
}
file->updating = 0;
clr_updating(file);
DBF (DB_VERBOSE, _("Finished prerequisites of target file `%s'.\n"));
@@ -508,14 +524,14 @@ update_file_1 (file, depth)
set_command_state (file, cs_deps_running);
--depth;
DBF (DB_VERBOSE, _("The prerequisites of `%s' are being made.\n"));
return 0;
return ts_incomplete;
}
/* If any dependency failed, give up now. */
if (dep_status != 0)
if (dep_status == ts_failed)
{
file->update_status = dep_status;
file->update_status = 1; /* if any precursors failed, so did we */
notice_finished_file (file);
depth--;
@@ -527,7 +543,7 @@ update_file_1 (file, depth)
error (NILF,
_("Target `%s' not remade because of errors."), file->name);
return dep_status;
return ts_failed;
}
if (file->command_state == cs_deps_running)
@@ -632,7 +648,7 @@ update_file_1 (file, depth)
file = file->prev;
}
return 0;
return ts_done;
}
DBF (DB_BASIC, _("Must remake target `%s'.\n"));
@@ -651,32 +667,24 @@ update_file_1 (file, depth)
if (file->command_state != cs_finished)
{
DBF (DB_VERBOSE, _("Commands of `%s' are being run.\n"));
return 0;
return ts_incomplete;
}
switch (file->update_status)
if (file->update_status)
{
case 2:
DBF (DB_BASIC, _("Failed to remake target file `%s'.\n"));
break;
case 0:
DBF (DB_BASIC, _("Successfully remade target file `%s'.\n"));
break;
case 1:
DBF (DB_BASIC, _("Target file `%s' needs remade under -q.\n"));
break;
default:
assert (file->update_status >= 0 && file->update_status <= 2);
break;
DBF (DB_BASIC, (question_flag ? _("Target file `%s' needs remade under -q.\n")
: _("Failed to remake target file `%s'.\n")));
return ts_failed;
}
else
{
DBF (DB_BASIC, _("Successfully remade target file `%s'.\n"));
return ts_done;
}
file->updated = 1;
return file->update_status;
}
/* Set FILE's `updated' flag and re-check its mtime and the mtime's of all
files listed in its `also_make' member. Under -t, this function also
touches FILE.
/* re-check FILE's mtime and the mtime's of all files listed in its
`also_make' member. Under -t, this function also touches FILE.
On return, FILE->update_status will no longer be -1 if it was. */
@@ -688,7 +696,6 @@ notice_finished_file (file)
int ran = file->command_state == cs_running;
file->command_state = cs_finished;
file->updated = 1;
if (touch_flag
/* The update status will be:
@@ -715,7 +722,7 @@ notice_finished_file (file)
file->update_status = 0;
else
/* Should set file's modification date and do nothing else. */
file->update_status = touch_file (file);
file->update_status = touch_file (file) ? 1 : 0;
}
}
@@ -751,7 +758,7 @@ notice_finished_file (file)
f->last_mtime = file->last_mtime;
}
if (ran && file->update_status != -1)
if (ran)
/* We actually tried to update FILE, which has
updated its also_make's as well (if it worked).
If it didn't work, it wouldn't work again for them.
@@ -759,7 +766,6 @@ notice_finished_file (file)
for (d = file->also_make; d != 0; d = d->next)
{
d->file->command_state = cs_finished;
d->file->updated = 1;
d->file->update_status = file->update_status;
if (ran && !d->file->phony)
@@ -769,10 +775,6 @@ notice_finished_file (file)
never be done because the target is already updated. */
(void) f_mtime (d->file, 0);
}
else if (file->update_status == -1)
/* Nothing was done for FILE, but it needed nothing done.
So mark it now as "succeeded". */
file->update_status = 0;
}
/* Check whether another file (whose mtime is THIS_MTIME)
@@ -780,9 +782,13 @@ notice_finished_file (file)
If it does, store 1 in *MUST_MAKE_PTR.
In the process, update any non-intermediate files
that FILE depends on (including FILE itself).
Return nonzero if any updating failed. */
static int
Return ts_done if FILE has completed successfully, ts_incomplete if
FILE or any of its precursors are incomplete, or ts_failed if FILE
or any of its precursors failed.
*/
static target_state_t
check_dep (file, depth, this_mtime, must_make_ptr)
struct file *file;
unsigned int depth;
@@ -790,10 +796,10 @@ check_dep (file, depth, this_mtime, must_make_ptr)
int *must_make_ptr;
{
register struct dep *d;
int dep_status = 0;
target_state_t dep_status = ts_done;
++depth;
file->updating = 1;
set_updating(file);
if (!file->intermediate)
/* If this is a non-intermediate file, update it and record
@@ -818,7 +824,6 @@ check_dep (file, depth, this_mtime, must_make_ptr)
DBF (DB_IMPLICIT, _("Found an implicit rule for `%s'.\n"));
else
DBF (DB_IMPLICIT, _("No implicit rule found for `%s'.\n"));
file->tried_implicit = 1;
}
if (file->cmds == 0 && !file->is_target
&& default_file != 0 && default_file->cmds != 0)
@@ -845,7 +850,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
d = file->deps;
while (d != 0)
{
if (d->file->updating)
if (tst_updating(d->file))
{
error (NILF, _("Circular %s <- %s dependency dropped."),
file->name, d->file->name);
@@ -868,7 +873,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
dep_status |= check_dep (d->file, depth, this_mtime,
must_make_ptr);
check_renamed (d->file);
if (dep_status != 0 && !keep_going_flag)
if (dep_status == ts_failed && !keep_going_flag)
break;
if (d->file->command_state == cs_running
@@ -884,7 +889,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
}
}
file->updating = 0;
clr_updating(file);
return dep_status;
}
@@ -985,7 +990,7 @@ remake_file (file)
error (NILF, msg_parent, "*** ",
file->name, file->parent->name, ".");
}
file->update_status = 2;
file->update_status = 1;
}
}
else
@@ -1138,7 +1143,7 @@ f_mtime (file, search)
static FILE_TIMESTAMP now = 0;
if (!clock_skew_detected
&& mtime != (FILE_TIMESTAMP)-1 && mtime > now
&& !file->updated)
&& !(file->command_state == cs_finished))
{
/* This file's time appears to be in the future.
Update our concept of the present, and compare again. */