mirror of
https://github.com/mirror/make.git
synced 2026-08-23 18:33:28 +08:00
Compare commits
10 Commits
3.79
...
filedef-cl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
646aeb50a1 | ||
|
|
fed90f1fa8 | ||
|
|
6a1a4343f3 | ||
|
|
e27c3fc91b | ||
|
|
9f3539c4ae | ||
|
|
1b40ffb900 | ||
|
|
0d621b0627 | ||
|
|
5ed230d3f8 | ||
|
|
b0e3148933 | ||
|
|
3b4369f170 |
116
ChangeLog
116
ChangeLog
@@ -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>
|
2000-02-07 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
For += target-specific variables we need to remember which
|
For += target-specific variables we need to remember which
|
||||||
|
|||||||
27
file.c
27
file.c
@@ -166,7 +166,7 @@ enter_file (name)
|
|||||||
new = (struct file *) xmalloc (sizeof (struct file));
|
new = (struct file *) xmalloc (sizeof (struct file));
|
||||||
bzero ((char *) new, sizeof (struct file));
|
bzero ((char *) new, sizeof (struct file));
|
||||||
new->name = new->hname = name;
|
new->name = new->hname = name;
|
||||||
new->update_status = -1;
|
new->update_status = 0; /* assume the file won */
|
||||||
|
|
||||||
if (f == 0)
|
if (f == 0)
|
||||||
{
|
{
|
||||||
@@ -199,8 +199,7 @@ rehash_file (file, name)
|
|||||||
register unsigned int oldhash;
|
register unsigned int oldhash;
|
||||||
register char *n;
|
register char *n;
|
||||||
|
|
||||||
while (file->renamed != 0)
|
check_renamed(file);
|
||||||
file = file->renamed;
|
|
||||||
|
|
||||||
/* Find the hash values of the old and new names. */
|
/* Find the hash values of the old and new names. */
|
||||||
|
|
||||||
@@ -361,7 +360,6 @@ in favor of those for `%s'."),
|
|||||||
MERGE (precious);
|
MERGE (precious);
|
||||||
MERGE (tried_implicit);
|
MERGE (tried_implicit);
|
||||||
MERGE (updating);
|
MERGE (updating);
|
||||||
MERGE (updated);
|
|
||||||
MERGE (is_target);
|
MERGE (is_target);
|
||||||
MERGE (cmd_target);
|
MERGE (cmd_target);
|
||||||
MERGE (phony);
|
MERGE (phony);
|
||||||
@@ -397,7 +395,7 @@ remove_intermediates (sig)
|
|||||||
&& !f->secondary)
|
&& !f->secondary)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
if (f->update_status == -1)
|
if (f->command_state == cs_not_started)
|
||||||
/* If nothing would have created this file yet,
|
/* If nothing would have created this file yet,
|
||||||
don't print an "rm" command for it. */
|
don't print an "rm" command for it. */
|
||||||
continue;
|
continue;
|
||||||
@@ -659,7 +657,7 @@ print_file (f)
|
|||||||
file_timestamp_sprintf (buf, f->last_mtime);
|
file_timestamp_sprintf (buf, f->last_mtime);
|
||||||
printf (_("# Last modified %s\n"), buf);
|
printf (_("# Last modified %s\n"), buf);
|
||||||
}
|
}
|
||||||
puts (f->updated
|
puts ((f->command_state == cs_finished)
|
||||||
? _("# File has been updated.") : _("# File has not been updated."));
|
? _("# File has been updated.") : _("# File has not been updated."));
|
||||||
switch (f->command_state)
|
switch (f->command_state)
|
||||||
{
|
{
|
||||||
@@ -670,26 +668,19 @@ print_file (f)
|
|||||||
puts (_("# Dependencies commands running (THIS IS A BUG)."));
|
puts (_("# Dependencies commands running (THIS IS A BUG)."));
|
||||||
break;
|
break;
|
||||||
case cs_not_started:
|
case cs_not_started:
|
||||||
|
break;
|
||||||
case cs_finished:
|
case cs_finished:
|
||||||
switch (f->update_status)
|
switch (f->update_status)
|
||||||
{
|
{
|
||||||
case -1:
|
|
||||||
break;
|
|
||||||
case 0:
|
case 0:
|
||||||
|
/* file won */
|
||||||
puts (_("# Successfully updated."));
|
puts (_("# Successfully updated."));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
assert (question_flag);
|
/* file lost */
|
||||||
puts (_("# Needs to be updated (-q is set)."));
|
puts (question_flag ? _("# Needs to be updated (-q is set).")
|
||||||
|
:_("# Failed to be updated."));
|
||||||
break;
|
break;
|
||||||
case 2:
|
|
||||||
puts (_("# Failed to be updated."));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
puts (_("# Invalid value in `update_status' member!"));
|
|
||||||
fflush (stdout);
|
|
||||||
fflush (stderr);
|
|
||||||
abort ();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -60,9 +60,6 @@ struct file
|
|||||||
the same file. Otherwise this is null. */
|
the same file. Otherwise this is null. */
|
||||||
struct file *double_colon;
|
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. */
|
enum /* State of the commands. */
|
||||||
{ /* Note: It is important that cs_not_started be zero. */
|
{ /* Note: It is important that cs_not_started be zero. */
|
||||||
cs_not_started, /* Not yet started. */
|
cs_not_started, /* Not yet started. */
|
||||||
@@ -71,12 +68,15 @@ struct file
|
|||||||
cs_finished /* Commands finished. */
|
cs_finished /* Commands finished. */
|
||||||
} command_state ENUM_BITFIELD (2);
|
} 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 precious:1; /* Non-0 means don't delete file on quit */
|
||||||
unsigned int tried_implicit:1; /* Nonzero if have searched
|
unsigned int tried_implicit:1; /* Nonzero if have searched
|
||||||
for implicit rule for making
|
for implicit rule for making
|
||||||
this file; don't search again. */
|
this file; don't search again. */
|
||||||
unsigned int updating:1; /* Nonzero while updating deps of this file */
|
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 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 cmd_target:1; /* Nonzero if file was given on cmd line. */
|
||||||
unsigned int phony:1; /* Nonzero if this is a phony file
|
unsigned int phony:1; /* Nonzero if this is a phony file
|
||||||
|
|||||||
12
implicit.c
12
implicit.c
@@ -37,6 +37,7 @@ try_implicit_rule (file, depth)
|
|||||||
struct file *file;
|
struct file *file;
|
||||||
unsigned int depth;
|
unsigned int depth;
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
DBF (DB_IMPLICIT, _("Looking for an implicit rule for `%s'.\n"));
|
DBF (DB_IMPLICIT, _("Looking for an implicit rule for `%s'.\n"));
|
||||||
|
|
||||||
/* The order of these searches was previously reversed. My logic now is
|
/* The order of these searches was previously reversed. My logic now is
|
||||||
@@ -45,21 +46,24 @@ try_implicit_rule (file, depth)
|
|||||||
should come first. */
|
should come first. */
|
||||||
|
|
||||||
if (pattern_search (file, 0, depth, 0))
|
if (pattern_search (file, 0, depth, 0))
|
||||||
return 1;
|
ret = 1;
|
||||||
|
|
||||||
#ifndef NO_ARCHIVES
|
#ifndef NO_ARCHIVES
|
||||||
/* If this is an archive member reference, use just the
|
/* If this is an archive member reference, use just the
|
||||||
archive member name to search for implicit rules. */
|
archive member name to search for implicit rules. */
|
||||||
if (ar_name (file->name))
|
else if (ar_name (file->name))
|
||||||
{
|
{
|
||||||
DBF (DB_IMPLICIT,
|
DBF (DB_IMPLICIT,
|
||||||
_("Looking for archive-member implicit rule for `%s'.\n"));
|
_("Looking for archive-member implicit rule for `%s'.\n"));
|
||||||
if (pattern_search (file, 1, depth, 0))
|
if (pattern_search (file, 1, depth, 0))
|
||||||
return 1;
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
file->tried_implicit = 1;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
6
job.c
6
job.c
@@ -665,7 +665,7 @@ reap_children (block, err)
|
|||||||
delete non-precious targets, and abort. */
|
delete non-precious targets, and abort. */
|
||||||
static int delete_on_error = -1;
|
static int delete_on_error = -1;
|
||||||
child_error (c->file->name, exit_code, exit_sig, coredump, 0);
|
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)
|
if (delete_on_error == -1)
|
||||||
{
|
{
|
||||||
struct file *f = lookup_file (".DELETE_ON_ERROR");
|
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,
|
Since there are more commands that wanted to be run,
|
||||||
the target was not completely remade. So we treat
|
the target was not completely remade. So we treat
|
||||||
this as if a command had failed. */
|
this as if a command had failed. */
|
||||||
c->file->update_status = 2;
|
c->file->update_status = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1250,7 +1250,7 @@ start_job_command (child)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
child->file->update_status = 2;
|
child->file->update_status = 1;
|
||||||
notice_finished_file (child->file);
|
notice_finished_file (child->file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
25
main.c
25
main.c
@@ -1254,7 +1254,6 @@ int main (int argc, char ** argv)
|
|||||||
/* Make sure the temporary file will not be remade. */
|
/* Make sure the temporary file will not be remade. */
|
||||||
stdin_nm = savestring (name, sizeof (name) -1);
|
stdin_nm = savestring (name, sizeof (name) -1);
|
||||||
f = enter_file (stdin_nm);
|
f = enter_file (stdin_nm);
|
||||||
f->updated = 1;
|
|
||||||
f->update_status = 0;
|
f->update_status = 0;
|
||||||
f->command_state = cs_finished;
|
f->command_state = cs_finished;
|
||||||
/* Can't be intermediate, or it'll be removed too early for
|
/* 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 = enter_command_line_file (*p);
|
||||||
f->last_mtime = f->mtime_before_update = (FILE_TIMESTAMP) 1;
|
f->last_mtime = f->mtime_before_update = (FILE_TIMESTAMP) 1;
|
||||||
f->updated = 1;
|
|
||||||
f->update_status = 0;
|
f->update_status = 0;
|
||||||
f->command_state = cs_finished;
|
f->command_state = cs_finished;
|
||||||
}
|
}
|
||||||
@@ -1606,17 +1604,11 @@ int main (int argc, char ** argv)
|
|||||||
|
|
||||||
switch (update_goal_chain (read_makefiles, 1))
|
switch (update_goal_chain (read_makefiles, 1))
|
||||||
{
|
{
|
||||||
case 1:
|
|
||||||
default:
|
|
||||||
#define BOGUS_UPDATE_STATUS 0
|
|
||||||
assert (BOGUS_UPDATE_STATUS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
/* Did nothing. */
|
/* Did nothing. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 1:
|
||||||
/* Failed to update. Figure out if we care. */
|
/* Failed to update. Figure out if we care. */
|
||||||
{
|
{
|
||||||
/* Nonzero if any makefile was successfully remade. */
|
/* Nonzero if any makefile was successfully remade. */
|
||||||
@@ -1633,7 +1625,7 @@ int main (int argc, char ** argv)
|
|||||||
again to print an error. */
|
again to print an error. */
|
||||||
d->file->considered = 0;
|
d->file->considered = 0;
|
||||||
|
|
||||||
if (d->file->updated)
|
if (d->file->command_state == cs_finished)
|
||||||
{
|
{
|
||||||
/* This makefile was updated. */
|
/* This makefile was updated. */
|
||||||
if (d->file->update_status == 0)
|
if (d->file->update_status == 0)
|
||||||
@@ -1836,18 +1828,19 @@ int main (int argc, char ** argv)
|
|||||||
{
|
{
|
||||||
case -1:
|
case -1:
|
||||||
/* Nothing happened. */
|
/* Nothing happened. */
|
||||||
|
/* FALL THRU */
|
||||||
case 0:
|
case 0:
|
||||||
/* Updated successfully. */
|
/* Updated successfully. */
|
||||||
status = EXIT_SUCCESS;
|
status = EXIT_SUCCESS;
|
||||||
break;
|
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:
|
case 1:
|
||||||
|
if (question_flag)
|
||||||
/* We are under -q and would run some commands. */
|
/* 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;
|
break;
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
|
|||||||
415
remake.c
415
remake.c
@@ -43,12 +43,39 @@ Boston, MA 02111-1307, USA. */
|
|||||||
extern int try_implicit_rule PARAMS ((struct file *file, unsigned int depth));
|
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). */
|
/* Incremented when a command is started (under -n, when one would be). */
|
||||||
unsigned int commands_started = 0;
|
unsigned int commands_started = 0;
|
||||||
|
|
||||||
static int update_file PARAMS ((struct file *file, unsigned int depth));
|
static target_state_t update_file PARAMS ((struct file *file, unsigned int depth));
|
||||||
static int update_file_1 PARAMS ((struct file *file, unsigned int depth));
|
static target_state_t 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 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 int touch_file PARAMS ((struct file *file));
|
||||||
static void remake_file PARAMS ((struct file *file));
|
static void remake_file PARAMS ((struct file *file));
|
||||||
static FILE_TIMESTAMP name_mtime PARAMS ((char *name));
|
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
|
should only make one goal at a time and return as soon as one goal whose
|
||||||
`changed' member is nonzero is successfully made. */
|
`changed' member is nonzero is successfully made. */
|
||||||
|
|
||||||
/* We need to know this "lower down" for correct error handling. */
|
|
||||||
static int updating_makefiles = 0;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
update_goal_chain (goals, makefiles)
|
update_goal_chain (goals, makefiles)
|
||||||
@@ -74,10 +99,6 @@ update_goal_chain (goals, makefiles)
|
|||||||
unsigned int j = job_slots;
|
unsigned int j = job_slots;
|
||||||
int status = -1;
|
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. */
|
/* 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. */
|
/* Iterate over all double-colon entries for this file. */
|
||||||
struct file *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;
|
target_state = ts_done;
|
||||||
file != NULL;
|
|
||||||
file = file->prev)
|
file = g->file;
|
||||||
|
check_renamed (file);
|
||||||
|
if (makefiles)
|
||||||
{
|
{
|
||||||
unsigned int ocommands_started;
|
if (file->cmd_target)
|
||||||
int x;
|
|
||||||
check_renamed (file);
|
|
||||||
if (makefiles)
|
|
||||||
{
|
{
|
||||||
if (file->cmd_target)
|
touch_flag = t;
|
||||||
{
|
question_flag = q;
|
||||||
touch_flag = t;
|
just_print_flag = n;
|
||||||
question_flag = q;
|
|
||||||
just_print_flag = n;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
touch_flag = question_flag = just_print_flag = 0;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Save the old value of `commands_started' so we can compare
|
touch_flag = question_flag = just_print_flag = 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset FILE since it is null at the end of the loop. */
|
commands_started = 0;
|
||||||
file = g->file;
|
|
||||||
|
|
||||||
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,
|
case ts_failed:
|
||||||
print a message saying nothing needs doing. */
|
/* 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 (!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. */
|
||||||
&& file->update_status == 0 && !g->changed
|
&& !file->update_status && !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)
|
||||||
message (1, ((file->phony || file->cmds == 0)
|
message (1, ((file->phony || file->cmds == 0)
|
||||||
@@ -221,24 +212,27 @@ update_goal_chain (goals, makefiles)
|
|||||||
: _("`%s' is up to date.")),
|
: _("`%s' is up to date.")),
|
||||||
file->name);
|
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)
|
if (lastgoal == 0)
|
||||||
goals = g->next;
|
goals = g->next;
|
||||||
else
|
else
|
||||||
lastgoal->next = g->next;
|
lastgoal->next = g->next;
|
||||||
|
|
||||||
/* Free the storage. */
|
free (g);
|
||||||
free ((char *) g);
|
|
||||||
|
|
||||||
g = lastgoal == 0 ? goals : lastgoal->next;
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If FILE is not up to date, execute the commands for it.
|
/* If FILE is not up to date, execute the commands for it. Return
|
||||||
Return 0 if successful, 1 if unsuccessful;
|
ts_done if FILE has completed successfully, ts_incomplete if FILE
|
||||||
but with some flag settings, just call `exit' if unsuccessful.
|
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.
|
DEPTH is the depth in recursions of this function.
|
||||||
We increment it during the consideration of our dependencies,
|
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,
|
If there are multiple double-colon entries for FILE,
|
||||||
each is considered in turn. */
|
each is considered in turn. */
|
||||||
|
|
||||||
static int
|
static target_state_t
|
||||||
update_file (file, depth)
|
update_file (file, depth)
|
||||||
struct file *file;
|
struct file *file;
|
||||||
unsigned int depth;
|
unsigned int depth;
|
||||||
{
|
{
|
||||||
register int status = 0;
|
register target_state_t status = ts_done;
|
||||||
register struct file *f;
|
register struct file *f;
|
||||||
|
|
||||||
f = file->double_colon ? file->double_colon : file;
|
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
|
/* This loop runs until we start commands for a double colon rule, or until
|
||||||
the chain is exhausted. */
|
the chain is exhausted. */
|
||||||
for (; f != 0; f = f->prev)
|
for (; f != 0; f = f->prev)
|
||||||
{
|
{
|
||||||
f->considered = considered;
|
|
||||||
|
|
||||||
status |= update_file_1 (f, depth);
|
status |= update_file_1 (f, depth);
|
||||||
check_renamed (f);
|
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;
|
break;
|
||||||
|
|
||||||
if (f->command_state == cs_running
|
if (f->command_state == cs_running
|
||||||
@@ -307,65 +298,88 @@ update_file (file, depth)
|
|||||||
{
|
{
|
||||||
/* Don't run the other :: rules for this
|
/* Don't run the other :: rules for this
|
||||||
file until this rule is finished. */
|
file until this rule is finished. */
|
||||||
status = 0;
|
status = ts_incomplete;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process the remaining rules in the double colon chain so they're marked
|
/* Process the remaining rules in the double colon chain so they're marked
|
||||||
considered. Start their prerequisites, too. */
|
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;
|
struct dep *d;
|
||||||
|
|
||||||
f->considered = considered;
|
f->considered = considered;
|
||||||
|
|
||||||
for (d = f->deps; d != 0; d = d->next)
|
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;
|
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)
|
update_file_1 (file, depth)
|
||||||
struct file *file;
|
struct file *file;
|
||||||
unsigned int depth;
|
unsigned int depth;
|
||||||
{
|
{
|
||||||
register FILE_TIMESTAMP this_mtime;
|
register FILE_TIMESTAMP this_mtime;
|
||||||
int noexist, must_make, deps_changed;
|
int noexist, must_make, deps_changed;
|
||||||
int dep_status = 0;
|
target_state_t dep_status = ts_done;
|
||||||
register struct dep *d, *lastd;
|
register struct dep *d, *lastd;
|
||||||
int running = 0;
|
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"));
|
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)
|
switch (file->command_state)
|
||||||
{
|
{
|
||||||
case cs_not_started:
|
case cs_not_started:
|
||||||
case cs_deps_running:
|
case cs_deps_running:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cs_running:
|
case cs_running:
|
||||||
DBF (DB_VERBOSE, _("Still updating file `%s'.\n"));
|
DBF (DB_VERBOSE, _("Still updating file `%s'.\n"));
|
||||||
return 0;
|
return ts_incomplete;
|
||||||
|
|
||||||
case cs_finished:
|
case cs_finished:
|
||||||
DBF (DB_VERBOSE, _("Finished updating file `%s'.\n"));
|
if (file->update_status != 0)
|
||||||
return file->update_status;
|
{
|
||||||
|
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:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
@@ -373,7 +387,7 @@ update_file_1 (file, depth)
|
|||||||
++depth;
|
++depth;
|
||||||
|
|
||||||
/* Notice recursive update of the same file. */
|
/* Notice recursive update of the same file. */
|
||||||
file->updating = 1;
|
set_updating(file);
|
||||||
|
|
||||||
/* Looking at the file's modtime beforehand allows the possibility
|
/* Looking at the file's modtime beforehand allows the possibility
|
||||||
that its name may be changed by a VPATH search, and thus it may
|
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);
|
this_mtime = file_mtime (file);
|
||||||
check_renamed (file);
|
check_renamed (file);
|
||||||
noexist = this_mtime == (FILE_TIMESTAMP) -1;
|
must_make = noexist = this_mtime == (FILE_TIMESTAMP) -1;
|
||||||
if (noexist)
|
if (noexist)
|
||||||
DBF (DB_BASIC, _("File `%s' does not exist.\n"));
|
DBF (DB_BASIC, _("File `%s' does not exist.\n"));
|
||||||
|
|
||||||
must_make = noexist;
|
|
||||||
|
|
||||||
/* If file was specified as a target with no commands,
|
/* If file was specified as a target with no commands,
|
||||||
come up with some default 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))
|
if (!file->phony && !file->tried_implicit)
|
||||||
DBF (DB_IMPLICIT, _("Found an implicit rule for `%s'.\n"));
|
{
|
||||||
else
|
if (try_implicit_rule (file, depth))
|
||||||
DBF (DB_IMPLICIT, _("No implicit rule found for `%s'.\n"));
|
DBF (DB_IMPLICIT, _("Found an implicit rule for `%s'.\n"));
|
||||||
file->tried_implicit = 1;
|
else
|
||||||
}
|
DBF (DB_IMPLICIT, _("No implicit rule found for `%s'.\n"));
|
||||||
if (file->cmds == 0 && !file->is_target
|
}
|
||||||
&& default_file != 0 && default_file->cmds != 0)
|
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;
|
DBF (DB_IMPLICIT, _("Using default commands for `%s'.\n"));
|
||||||
|
file->cmds = default_file->cmds;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update all non-intermediate files we depend on, if necessary,
|
/* Update all non-intermediate files we depend on, if necessary,
|
||||||
@@ -421,7 +437,7 @@ update_file_1 (file, depth)
|
|||||||
mtime = file_mtime (d->file);
|
mtime = file_mtime (d->file);
|
||||||
check_renamed (d->file);
|
check_renamed (d->file);
|
||||||
|
|
||||||
if (d->file->updating)
|
if (tst_updating(d->file))
|
||||||
{
|
{
|
||||||
error (NILF, _("Circular %s <- %s dependency dropped."),
|
error (NILF, _("Circular %s <- %s dependency dropped."),
|
||||||
file->name, d->file->name);
|
file->name, d->file->name);
|
||||||
@@ -453,7 +469,7 @@ update_file_1 (file, depth)
|
|||||||
while (f != 0);
|
while (f != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dep_status != 0 && !keep_going_flag)
|
if (dep_status == ts_failed && !keep_going_flag)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!running)
|
if (!running)
|
||||||
@@ -490,7 +506,7 @@ update_file_1 (file, depth)
|
|||||||
while (f != 0);
|
while (f != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dep_status != 0 && !keep_going_flag)
|
if (dep_status == ts_failed && !keep_going_flag)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!running)
|
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"));
|
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);
|
set_command_state (file, cs_deps_running);
|
||||||
--depth;
|
--depth;
|
||||||
DBF (DB_VERBOSE, _("The prerequisites of `%s' are being made.\n"));
|
DBF (DB_VERBOSE, _("The prerequisites of `%s' are being made.\n"));
|
||||||
return 0;
|
return ts_incomplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If any dependency failed, give up now. */
|
/* 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);
|
notice_finished_file (file);
|
||||||
|
|
||||||
depth--;
|
depth--;
|
||||||
@@ -527,7 +543,7 @@ update_file_1 (file, depth)
|
|||||||
error (NILF,
|
error (NILF,
|
||||||
_("Target `%s' not remade because of errors."), file->name);
|
_("Target `%s' not remade because of errors."), file->name);
|
||||||
|
|
||||||
return dep_status;
|
return ts_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file->command_state == cs_deps_running)
|
if (file->command_state == cs_deps_running)
|
||||||
@@ -632,7 +648,7 @@ update_file_1 (file, depth)
|
|||||||
file = file->prev;
|
file = file->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ts_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBF (DB_BASIC, _("Must remake target `%s'.\n"));
|
DBF (DB_BASIC, _("Must remake target `%s'.\n"));
|
||||||
@@ -651,32 +667,24 @@ update_file_1 (file, depth)
|
|||||||
if (file->command_state != cs_finished)
|
if (file->command_state != cs_finished)
|
||||||
{
|
{
|
||||||
DBF (DB_VERBOSE, _("Commands of `%s' are being run.\n"));
|
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, (question_flag ? _("Target file `%s' needs remade under -q.\n")
|
||||||
DBF (DB_BASIC, _("Failed to remake target file `%s'.\n"));
|
: _("Failed to remake target file `%s'.\n")));
|
||||||
break;
|
return ts_failed;
|
||||||
case 0:
|
}
|
||||||
DBF (DB_BASIC, _("Successfully remade target file `%s'.\n"));
|
else
|
||||||
break;
|
{
|
||||||
case 1:
|
DBF (DB_BASIC, _("Successfully remade target file `%s'.\n"));
|
||||||
DBF (DB_BASIC, _("Target file `%s' needs remade under -q.\n"));
|
return ts_done;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert (file->update_status >= 0 && file->update_status <= 2);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file->updated = 1;
|
|
||||||
return file->update_status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set FILE's `updated' flag and re-check its mtime and the mtime's of all
|
/* re-check FILE's mtime and the mtime's of all files listed in its
|
||||||
files listed in its `also_make' member. Under -t, this function also
|
`also_make' member. Under -t, this function also touches FILE.
|
||||||
touches FILE.
|
|
||||||
|
|
||||||
On return, FILE->update_status will no longer be -1 if it was. */
|
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;
|
int ran = file->command_state == cs_running;
|
||||||
|
|
||||||
file->command_state = cs_finished;
|
file->command_state = cs_finished;
|
||||||
file->updated = 1;
|
|
||||||
|
|
||||||
if (touch_flag
|
if (touch_flag
|
||||||
/* The update status will be:
|
/* The update status will be:
|
||||||
@@ -715,7 +722,7 @@ notice_finished_file (file)
|
|||||||
file->update_status = 0;
|
file->update_status = 0;
|
||||||
else
|
else
|
||||||
/* Should set file's modification date and do nothing 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;
|
f->last_mtime = file->last_mtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ran && file->update_status != -1)
|
if (ran)
|
||||||
/* We actually tried to update FILE, which has
|
/* We actually tried to update FILE, which has
|
||||||
updated its also_make's as well (if it worked).
|
updated its also_make's as well (if it worked).
|
||||||
If it didn't work, it wouldn't work again for them.
|
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)
|
for (d = file->also_make; d != 0; d = d->next)
|
||||||
{
|
{
|
||||||
d->file->command_state = cs_finished;
|
d->file->command_state = cs_finished;
|
||||||
d->file->updated = 1;
|
|
||||||
d->file->update_status = file->update_status;
|
d->file->update_status = file->update_status;
|
||||||
|
|
||||||
if (ran && !d->file->phony)
|
if (ran && !d->file->phony)
|
||||||
@@ -769,10 +775,6 @@ notice_finished_file (file)
|
|||||||
never be done because the target is already updated. */
|
never be done because the target is already updated. */
|
||||||
(void) f_mtime (d->file, 0);
|
(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)
|
/* 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.
|
If it does, store 1 in *MUST_MAKE_PTR.
|
||||||
In the process, update any non-intermediate files
|
In the process, update any non-intermediate files
|
||||||
that FILE depends on (including FILE itself).
|
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)
|
check_dep (file, depth, this_mtime, must_make_ptr)
|
||||||
struct file *file;
|
struct file *file;
|
||||||
unsigned int depth;
|
unsigned int depth;
|
||||||
@@ -790,10 +796,10 @@ check_dep (file, depth, this_mtime, must_make_ptr)
|
|||||||
int *must_make_ptr;
|
int *must_make_ptr;
|
||||||
{
|
{
|
||||||
register struct dep *d;
|
register struct dep *d;
|
||||||
int dep_status = 0;
|
target_state_t dep_status = ts_done;
|
||||||
|
|
||||||
++depth;
|
++depth;
|
||||||
file->updating = 1;
|
set_updating(file);
|
||||||
|
|
||||||
if (!file->intermediate)
|
if (!file->intermediate)
|
||||||
/* If this is a non-intermediate file, update it and record
|
/* 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"));
|
DBF (DB_IMPLICIT, _("Found an implicit rule for `%s'.\n"));
|
||||||
else
|
else
|
||||||
DBF (DB_IMPLICIT, _("No implicit rule found for `%s'.\n"));
|
DBF (DB_IMPLICIT, _("No implicit rule found for `%s'.\n"));
|
||||||
file->tried_implicit = 1;
|
|
||||||
}
|
}
|
||||||
if (file->cmds == 0 && !file->is_target
|
if (file->cmds == 0 && !file->is_target
|
||||||
&& default_file != 0 && default_file->cmds != 0)
|
&& default_file != 0 && default_file->cmds != 0)
|
||||||
@@ -845,7 +850,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
|
|||||||
d = file->deps;
|
d = file->deps;
|
||||||
while (d != 0)
|
while (d != 0)
|
||||||
{
|
{
|
||||||
if (d->file->updating)
|
if (tst_updating(d->file))
|
||||||
{
|
{
|
||||||
error (NILF, _("Circular %s <- %s dependency dropped."),
|
error (NILF, _("Circular %s <- %s dependency dropped."),
|
||||||
file->name, d->file->name);
|
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,
|
dep_status |= check_dep (d->file, depth, this_mtime,
|
||||||
must_make_ptr);
|
must_make_ptr);
|
||||||
check_renamed (d->file);
|
check_renamed (d->file);
|
||||||
if (dep_status != 0 && !keep_going_flag)
|
if (dep_status == ts_failed && !keep_going_flag)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (d->file->command_state == cs_running
|
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;
|
return dep_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -985,7 +990,7 @@ remake_file (file)
|
|||||||
error (NILF, msg_parent, "*** ",
|
error (NILF, msg_parent, "*** ",
|
||||||
file->name, file->parent->name, ".");
|
file->name, file->parent->name, ".");
|
||||||
}
|
}
|
||||||
file->update_status = 2;
|
file->update_status = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1138,7 +1143,7 @@ f_mtime (file, search)
|
|||||||
static FILE_TIMESTAMP now = 0;
|
static FILE_TIMESTAMP now = 0;
|
||||||
if (!clock_skew_detected
|
if (!clock_skew_detected
|
||||||
&& mtime != (FILE_TIMESTAMP)-1 && mtime > now
|
&& mtime != (FILE_TIMESTAMP)-1 && mtime > now
|
||||||
&& !file->updated)
|
&& !(file->command_state == cs_finished))
|
||||||
{
|
{
|
||||||
/* This file's time appears to be in the future.
|
/* This file's time appears to be in the future.
|
||||||
Update our concept of the present, and compare again. */
|
Update our concept of the present, and compare again. */
|
||||||
|
|||||||
Reference in New Issue
Block a user