mirror of
https://github.com/mirror/make.git
synced 2026-08-21 01:13:27 +08:00
Compare commits
2 Commits
filedef-cl
...
3.78.91
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75f879f37f | ||
|
|
e68a27ec7b |
147
ChangeLog
147
ChangeLog
@@ -1,128 +1,22 @@
|
||||
2000-03-13 Tim Magill <magill@gate.net>
|
||||
2000-02-09 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* remake.c:
|
||||
(update_file_1):
|
||||
(check_dep): fixed problem with double colon rules and circular
|
||||
precursor detection.
|
||||
* Version 3.78.91 released.
|
||||
|
||||
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>
|
||||
|
||||
* read.c (read_makefile): Reset *p2 to ':', not *colonp. If any
|
||||
filenames contained backslashes the resulting output (without
|
||||
backslashes) will be shorter, so setting *colonp doesn't change
|
||||
the right character. Fix for PR/1586.
|
||||
|
||||
For += target-specific variables we need to remember which
|
||||
variable set we found the variable in, so we can start looking
|
||||
there in the next iteration (otherwise we'll see it again in
|
||||
recursively_expand and fail!). This is getting to be a hack; if
|
||||
it gets any worse we'll have to rethink this entire algorithm;
|
||||
probably implementing expansion of these separately from the
|
||||
"normal" expansion, instead of alongside.
|
||||
from there in the next iteration (otherwise we might see it again
|
||||
in recursively_expand and fail!). This is turning into a hack; if
|
||||
it gets any worse we'll have to rethink this entire algorithm...
|
||||
implementing expansion of these references separately from the
|
||||
"normal" expansion, say, instead of using the same codepath.
|
||||
Actually, it's already "worse enough" :-/.
|
||||
|
||||
* variable.h (recursively_expand_setlist): Rename
|
||||
recursively_expand to add a struct variable_set_list argument, and
|
||||
@@ -131,8 +25,7 @@
|
||||
variable_set_list argument, and make a macro for lookup_variable.
|
||||
|
||||
* expand.c (recursively_expand_setlist): Take an extra struct
|
||||
variable_set_list argument and pass it to
|
||||
allocated_variable_append().
|
||||
variable_set_list argument and pass it to allocated_variable_append().
|
||||
(reference_variable): Use lookup_variable_setlist() and pass the
|
||||
returned variable_set_list to recursively_expand_setlist.
|
||||
(allocated_variable_append): Take an extra setlist argument and
|
||||
@@ -140,7 +33,7 @@
|
||||
expansion. If it's null, use current_variable_set_list as before.
|
||||
|
||||
* variable.c (lookup_variable_setlist): If the LISTP argument is
|
||||
not nil, return the list where we found the variable in it.
|
||||
not nil, set it to the list containing the variable we found.
|
||||
|
||||
2000-02-04 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
@@ -203,6 +96,16 @@
|
||||
|
||||
* default.c (default_variables) [__MSDOS__]: Define CXX to gpp.
|
||||
|
||||
2000-01-27 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* gettext.c: Some warning cleanups, and a fix for systems which
|
||||
don't define HAVE_ALLOCA (the workaround code was included
|
||||
twice).
|
||||
|
||||
2000-01-26 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* Version 3.78.90 released.
|
||||
|
||||
2000-01-25 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
Change gettext support to use the simplified version in libit 0.7.
|
||||
|
||||
@@ -30,10 +30,18 @@ site. There is information there about ordering hardcopy documentation.
|
||||
|
||||
You can also find the latest versions of GNU Make from there.
|
||||
|
||||
You can send GNU make bug reports to bug-make@gnu.org. Please see the
|
||||
You can send GNU make bug reports to <bug-make@gnu.org>. Please see the
|
||||
section of the GNU make manual entitled `Problems and Bugs' for
|
||||
information on submitting useful and complete bug reports.
|
||||
|
||||
You can also use the FSF's online bug tracking system to submit new
|
||||
problem reports or search for existing ones. A web interface is
|
||||
available here:
|
||||
|
||||
http://www-gnats.gnu.org:8080/cgi-bin/wwwgnats.pl
|
||||
|
||||
Use the Category "make".
|
||||
|
||||
If you need help using GNU make, try these forums:
|
||||
|
||||
help-make@gnu.org
|
||||
@@ -46,6 +54,8 @@ Also:
|
||||
- See README.customs for details on integrating GNU make with the
|
||||
Customs distributed build environment from the Pmake distribution.
|
||||
|
||||
- See readme.vms for details about GNU Make on OpenVMS.
|
||||
|
||||
- See README.W32 for details about GNU Make on Windows NT, 95, or 98.
|
||||
|
||||
- See README.Amiga for details about GNU Make on AmigaDOS.
|
||||
|
||||
27
file.c
27
file.c
@@ -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 = 0; /* assume the file won */
|
||||
new->update_status = -1;
|
||||
|
||||
if (f == 0)
|
||||
{
|
||||
@@ -199,7 +199,8 @@ rehash_file (file, name)
|
||||
register unsigned int oldhash;
|
||||
register char *n;
|
||||
|
||||
check_renamed(file);
|
||||
while (file->renamed != 0)
|
||||
file = file->renamed;
|
||||
|
||||
/* Find the hash values of the old and new names. */
|
||||
|
||||
@@ -360,6 +361,7 @@ in favor of those for `%s'."),
|
||||
MERGE (precious);
|
||||
MERGE (tried_implicit);
|
||||
MERGE (updating);
|
||||
MERGE (updated);
|
||||
MERGE (is_target);
|
||||
MERGE (cmd_target);
|
||||
MERGE (phony);
|
||||
@@ -395,7 +397,7 @@ remove_intermediates (sig)
|
||||
&& !f->secondary)
|
||||
{
|
||||
int status;
|
||||
if (f->command_state == cs_not_started)
|
||||
if (f->update_status == -1)
|
||||
/* If nothing would have created this file yet,
|
||||
don't print an "rm" command for it. */
|
||||
continue;
|
||||
@@ -657,7 +659,7 @@ print_file (f)
|
||||
file_timestamp_sprintf (buf, f->last_mtime);
|
||||
printf (_("# Last modified %s\n"), buf);
|
||||
}
|
||||
puts ((f->command_state == cs_finished)
|
||||
puts (f->updated
|
||||
? _("# File has been updated.") : _("# File has not been updated."));
|
||||
switch (f->command_state)
|
||||
{
|
||||
@@ -668,19 +670,26 @@ 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:
|
||||
/* file lost */
|
||||
puts (question_flag ? _("# Needs to be updated (-q is set).")
|
||||
:_("# Failed to be updated."));
|
||||
assert (question_flag);
|
||||
puts (_("# Needs to be updated (-q is set)."));
|
||||
break;
|
||||
case 2:
|
||||
puts (_("# Failed to be updated."));
|
||||
break;
|
||||
default:
|
||||
puts (_("# Invalid value in `update_status' member!"));
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
abort ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -60,6 +60,9 @@ 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. */
|
||||
@@ -68,15 +71,12 @@ 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
|
||||
|
||||
@@ -492,9 +492,9 @@ func_notdir_suffix(o, argv, funcname)
|
||||
char *list_iterator = argv[0];
|
||||
char *p2 =0;
|
||||
int doneany =0;
|
||||
int len=0;
|
||||
unsigned int len=0;
|
||||
|
||||
int is_suffix = streq(funcname, "suffix");
|
||||
int is_suffix = streq (funcname, "suffix");
|
||||
int is_notdir = !is_suffix;
|
||||
while ((p2 = find_next_token (&list_iterator, &len)) != 0)
|
||||
{
|
||||
@@ -555,7 +555,7 @@ func_basename_dir(o, argv, funcname)
|
||||
int doneany=0;
|
||||
unsigned int len=0;
|
||||
char *p=0;
|
||||
int is_basename= streq(funcname, "basename");
|
||||
int is_basename= streq (funcname, "basename");
|
||||
int is_dir= !is_basename;
|
||||
|
||||
while ((p2 = find_next_token (&p3, &len)) != 0)
|
||||
@@ -563,7 +563,7 @@ func_basename_dir(o, argv, funcname)
|
||||
p = p2 + len;
|
||||
while (p >= p2 && (!is_basename || *p != '.'))
|
||||
{
|
||||
if (IS_PATHSEP(*p))
|
||||
if (IS_PATHSEP (*p))
|
||||
break;
|
||||
--p;
|
||||
}
|
||||
|
||||
46
gettext.c
46
gettext.c
@@ -563,7 +563,8 @@ _nl_explode_name (name, language, modifier, territory, codeset,
|
||||
|
||||
if (*codeset != cp && (*codeset)[0] != '\0')
|
||||
{
|
||||
*normalized_codeset = _nl_normalize_codeset (*codeset,
|
||||
*normalized_codeset = _nl_normalize_codeset ((const unsigned
|
||||
char *)*codeset,
|
||||
cp - *codeset);
|
||||
if (strcmp (*codeset, *normalized_codeset) == 0)
|
||||
free ((char *) *normalized_codeset);
|
||||
@@ -1220,13 +1221,13 @@ read_alias_file (fname, fname_len)
|
||||
unsigned char *value;
|
||||
unsigned char *cp;
|
||||
|
||||
if (fgets (buf, sizeof buf, fp) == NULL)
|
||||
if (fgets ((char *)buf, sizeof buf, fp) == NULL)
|
||||
/* EOF reached. */
|
||||
break;
|
||||
|
||||
/* Possibly not the whole line fits into the buffer. Ignore
|
||||
the rest of the line. */
|
||||
if (strchr (buf, '\n') == NULL)
|
||||
if (strchr ((char *)buf, '\n') == NULL)
|
||||
{
|
||||
char altbuf[BUFSIZ];
|
||||
do
|
||||
@@ -1279,8 +1280,8 @@ read_alias_file (fname, fname_len)
|
||||
if (nmap >= maxmap)
|
||||
extend_alias_table ();
|
||||
|
||||
alias_len = strlen (alias) + 1;
|
||||
value_len = strlen (value) + 1;
|
||||
alias_len = strlen ((char *)alias) + 1;
|
||||
value_len = strlen ((char *)value) + 1;
|
||||
|
||||
if (string_space_act + alias_len + value_len > string_space_max)
|
||||
{
|
||||
@@ -1750,41 +1751,6 @@ static const char *guess_category_value PARAMS ((int category,
|
||||
const char *categoryname))
|
||||
internal_function;
|
||||
|
||||
/* For those loosing systems which don't have `alloca' we have to add
|
||||
some additional code emulating it. */
|
||||
#ifdef HAVE_ALLOCA
|
||||
/* Nothing has to be done. */
|
||||
# define ADD_BLOCK(list, address) /* nothing */
|
||||
# define FREE_BLOCKS(list) /* nothing */
|
||||
#else
|
||||
struct block_list
|
||||
{
|
||||
void *address;
|
||||
struct block_list *next;
|
||||
};
|
||||
# define ADD_BLOCK(list, addr) \
|
||||
do { \
|
||||
struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \
|
||||
/* If we cannot get a free block we cannot add the new element to \
|
||||
the list. */ \
|
||||
if (newp != NULL) { \
|
||||
newp->address = (addr); \
|
||||
newp->next = (list); \
|
||||
(list) = newp; \
|
||||
} \
|
||||
} while (0)
|
||||
# define FREE_BLOCKS(list) \
|
||||
do { \
|
||||
while (list != NULL) { \
|
||||
struct block_list *old = list; \
|
||||
list = list->next; \
|
||||
free (old); \
|
||||
} \
|
||||
} while (0)
|
||||
# undef alloca
|
||||
# define alloca(size) (malloc (size))
|
||||
#endif /* have alloca */
|
||||
|
||||
/* Names for the libintl functions are a problem. They must not clash
|
||||
with existing names and they should follow ANSI C. But this source
|
||||
code is also used in GNU C Library where the names have a __
|
||||
|
||||
12
implicit.c
12
implicit.c
@@ -37,7 +37,6 @@ 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
|
||||
@@ -46,24 +45,21 @@ try_implicit_rule (file, depth)
|
||||
should come first. */
|
||||
|
||||
if (pattern_search (file, 0, depth, 0))
|
||||
ret = 1;
|
||||
return 1;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
/* If this is an archive member reference, use just the
|
||||
archive member name to search for implicit rules. */
|
||||
else if (ar_name (file->name))
|
||||
if (ar_name (file->name))
|
||||
{
|
||||
DBF (DB_IMPLICIT,
|
||||
_("Looking for archive-member implicit rule for `%s'.\n"));
|
||||
if (pattern_search (file, 1, depth, 0))
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
file->tried_implicit = 1;
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
6
job.c
6
job.c
@@ -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 = 1;
|
||||
c->file->update_status = 2;
|
||||
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 = 1;
|
||||
c->file->update_status = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1250,7 +1250,7 @@ start_job_command (child)
|
||||
return;
|
||||
|
||||
error:
|
||||
child->file->update_status = 1;
|
||||
child->file->update_status = 2;
|
||||
notice_finished_file (child->file);
|
||||
return;
|
||||
}
|
||||
|
||||
25
main.c
25
main.c
@@ -1254,6 +1254,7 @@ 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
|
||||
@@ -1517,6 +1518,7 @@ 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;
|
||||
}
|
||||
@@ -1604,11 +1606,17 @@ 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 1:
|
||||
case 2:
|
||||
/* Failed to update. Figure out if we care. */
|
||||
{
|
||||
/* Nonzero if any makefile was successfully remade. */
|
||||
@@ -1625,7 +1633,7 @@ int main (int argc, char ** argv)
|
||||
again to print an error. */
|
||||
d->file->considered = 0;
|
||||
|
||||
if (d->file->command_state == cs_finished)
|
||||
if (d->file->updated)
|
||||
{
|
||||
/* This makefile was updated. */
|
||||
if (d->file->update_status == 0)
|
||||
@@ -1828,19 +1836,18 @@ 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;
|
||||
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;
|
||||
status = EXIT_FAILURE;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
|
||||
2
read.c
2
read.c
@@ -879,7 +879,7 @@ read_makefile (filename, flags)
|
||||
sizeof (struct nameseq),
|
||||
1),
|
||||
sizeof (struct nameseq));
|
||||
*colonp = ':';
|
||||
*p2 = ':';
|
||||
|
||||
if (!filenames)
|
||||
{
|
||||
|
||||
410
remake.c
410
remake.c
@@ -43,39 +43,12 @@ 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 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 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 int touch_file PARAMS ((struct file *file));
|
||||
static void remake_file PARAMS ((struct file *file));
|
||||
static FILE_TIMESTAMP name_mtime PARAMS ((char *name));
|
||||
@@ -89,7 +62,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. */
|
||||
|
||||
|
||||
int
|
||||
update_goal_chain (goals, makefiles)
|
||||
register struct dep *goals;
|
||||
@@ -99,6 +71,8 @@ update_goal_chain (goals, makefiles)
|
||||
unsigned int j = job_slots;
|
||||
int status = -1;
|
||||
|
||||
#define MTIME(file) (makefiles ? file_mtime_no_search (file) \
|
||||
: file_mtime (file))
|
||||
|
||||
/* Duplicate the chain so we can remove things from it. */
|
||||
|
||||
@@ -138,73 +112,103 @@ update_goal_chain (goals, makefiles)
|
||||
{
|
||||
/* Iterate over all double-colon entries for this file. */
|
||||
struct file *file;
|
||||
target_state_t target_state;
|
||||
int stop = 0, any_not_updated = 0;
|
||||
|
||||
target_state = ts_done;
|
||||
|
||||
file = g->file;
|
||||
check_renamed (file);
|
||||
if (makefiles)
|
||||
for (file = g->file->double_colon ? g->file->double_colon : g->file;
|
||||
file != NULL;
|
||||
file = file->prev)
|
||||
{
|
||||
if (file->cmd_target)
|
||||
unsigned int ocommands_started;
|
||||
int x;
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
commands_started = 0;
|
||||
/* Reset FILE since it is null at the end of the loop. */
|
||||
file = g->file;
|
||||
|
||||
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 (stop || !any_not_updated)
|
||||
{
|
||||
case ts_failed:
|
||||
/* Bail early? */
|
||||
if (!keep_going_flag && !question_flag && !makefiles)
|
||||
return 1;
|
||||
/* If we have found nothing whatever to do for the goal,
|
||||
print a message saying nothing needs doing. */
|
||||
|
||||
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 && !g->changed
|
||||
&& file->update_status == 0 && !g->changed
|
||||
/* Never give a message under -s or -q. */
|
||||
&& !silent_flag && !question_flag)
|
||||
message (1, ((file->phony || file->cmds == 0)
|
||||
@@ -212,27 +216,24 @@ update_goal_chain (goals, makefiles)
|
||||
: _("`%s' is up to date.")),
|
||||
file->name);
|
||||
|
||||
case ts_incomplete:
|
||||
break; /* do nothing */
|
||||
}
|
||||
|
||||
|
||||
/* advance to next target in goal chain */
|
||||
if (target_state == ts_incomplete)
|
||||
{
|
||||
lastgoal = g;
|
||||
g = g->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This goal is finished. Remove it from the chain. */
|
||||
if (lastgoal == 0)
|
||||
goals = g->next;
|
||||
else
|
||||
lastgoal->next = g->next;
|
||||
|
||||
free (g);
|
||||
/* Free the storage. */
|
||||
free ((char *) g);
|
||||
|
||||
g = lastgoal == 0 ? goals : lastgoal->next;
|
||||
|
||||
if (stop)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastgoal = g;
|
||||
g = g->next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,10 +253,9 @@ update_goal_chain (goals, makefiles)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
/* 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.
|
||||
|
||||
DEPTH is the depth in recursions of this function.
|
||||
We increment it during the consideration of our dependencies,
|
||||
@@ -265,32 +265,36 @@ update_goal_chain (goals, makefiles)
|
||||
If there are multiple double-colon entries for FILE,
|
||||
each is considered in turn. */
|
||||
|
||||
static target_state_t
|
||||
static int
|
||||
update_file (file, depth)
|
||||
struct file *file;
|
||||
unsigned int depth;
|
||||
{
|
||||
register target_state_t status = ts_done;
|
||||
register int status = 0;
|
||||
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 == ts_failed)
|
||||
{
|
||||
if (!keep_going_flag || question_flag)
|
||||
return ts_failed;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == ts_incomplete)
|
||||
if (status != 0 && !keep_going_flag)
|
||||
break;
|
||||
|
||||
if (f->command_state == cs_running
|
||||
@@ -298,88 +302,65 @@ update_file (file, depth)
|
||||
{
|
||||
/* Don't run the other :: rules for this
|
||||
file until this rule is finished. */
|
||||
status = ts_incomplete;
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process the remaining rules in the double colon chain so they're marked
|
||||
considered. Start their prerequisites, too. */
|
||||
for (f = (f ? f->prev : 0); f != 0 ; f = f->prev)
|
||||
for (; f != 0 ; f = f->prev)
|
||||
{
|
||||
struct dep *d;
|
||||
|
||||
f->considered = considered;
|
||||
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
if ((status |= update_file (d->file, depth + 1)) == ts_failed)
|
||||
{
|
||||
if (!keep_going_flag || question_flag)
|
||||
return ts_failed;
|
||||
}
|
||||
status |= update_file (d->file, depth + 1);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Consider a single `struct file' and update it as appropriate.
|
||||
/* Consider a single `struct file' and update it as appropriate. */
|
||||
|
||||
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
|
||||
static int
|
||||
update_file_1 (file, depth)
|
||||
struct file *file;
|
||||
unsigned int depth;
|
||||
{
|
||||
register FILE_TIMESTAMP this_mtime;
|
||||
int noexist, must_make, deps_changed;
|
||||
target_state_t dep_status = ts_done;
|
||||
int dep_status = 0;
|
||||
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 ts_incomplete;
|
||||
|
||||
return 0;
|
||||
case cs_finished:
|
||||
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;
|
||||
|
||||
DBF (DB_VERBOSE, _("Finished updating file `%s'.\n"));
|
||||
return file->update_status;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
@@ -387,7 +368,7 @@ update_file_1 (file, depth)
|
||||
++depth;
|
||||
|
||||
/* Notice recursive update of the same file. */
|
||||
set_updating(file);
|
||||
file->updating = 1;
|
||||
|
||||
/* Looking at the file's modtime beforehand allows the possibility
|
||||
that its name may be changed by a VPATH search, and thus it may
|
||||
@@ -397,30 +378,28 @@ update_file_1 (file, depth)
|
||||
|
||||
this_mtime = file_mtime (file);
|
||||
check_renamed (file);
|
||||
must_make = noexist = this_mtime == (FILE_TIMESTAMP) -1;
|
||||
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->cmds == 0)
|
||||
if (!file->phony && file->cmds == 0 && !file->tried_implicit)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/* Update all non-intermediate files we depend on, if necessary,
|
||||
@@ -437,7 +416,7 @@ update_file_1 (file, depth)
|
||||
mtime = file_mtime (d->file);
|
||||
check_renamed (d->file);
|
||||
|
||||
if (tst_updating(d->file))
|
||||
if (d->file->updating)
|
||||
{
|
||||
error (NILF, _("Circular %s <- %s dependency dropped."),
|
||||
file->name, d->file->name);
|
||||
@@ -469,7 +448,7 @@ update_file_1 (file, depth)
|
||||
while (f != 0);
|
||||
}
|
||||
|
||||
if (dep_status == ts_failed && !keep_going_flag)
|
||||
if (dep_status != 0 && !keep_going_flag)
|
||||
break;
|
||||
|
||||
if (!running)
|
||||
@@ -506,7 +485,7 @@ update_file_1 (file, depth)
|
||||
while (f != 0);
|
||||
}
|
||||
|
||||
if (dep_status == ts_failed && !keep_going_flag)
|
||||
if (dep_status != 0 && !keep_going_flag)
|
||||
break;
|
||||
|
||||
if (!running)
|
||||
@@ -515,7 +494,7 @@ update_file_1 (file, depth)
|
||||
}
|
||||
}
|
||||
|
||||
clr_updating(file);
|
||||
file->updating = 0;
|
||||
|
||||
DBF (DB_VERBOSE, _("Finished prerequisites of target file `%s'.\n"));
|
||||
|
||||
@@ -524,14 +503,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 ts_incomplete;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If any dependency failed, give up now. */
|
||||
|
||||
if (dep_status == ts_failed)
|
||||
if (dep_status != 0)
|
||||
{
|
||||
file->update_status = 1; /* if any precursors failed, so did we */
|
||||
file->update_status = dep_status;
|
||||
notice_finished_file (file);
|
||||
|
||||
depth--;
|
||||
@@ -543,7 +522,7 @@ update_file_1 (file, depth)
|
||||
error (NILF,
|
||||
_("Target `%s' not remade because of errors."), file->name);
|
||||
|
||||
return ts_failed;
|
||||
return dep_status;
|
||||
}
|
||||
|
||||
if (file->command_state == cs_deps_running)
|
||||
@@ -648,7 +627,7 @@ update_file_1 (file, depth)
|
||||
file = file->prev;
|
||||
}
|
||||
|
||||
return ts_done;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DBF (DB_BASIC, _("Must remake target `%s'.\n"));
|
||||
@@ -667,24 +646,32 @@ update_file_1 (file, depth)
|
||||
if (file->command_state != cs_finished)
|
||||
{
|
||||
DBF (DB_VERBOSE, _("Commands of `%s' are being run.\n"));
|
||||
return ts_incomplete;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (file->update_status)
|
||||
{
|
||||
DBF (DB_BASIC, (question_flag ? _("Target file `%s' needs remade under -q.\n")
|
||||
: _("Failed to remake target file `%s'.\n")));
|
||||
return ts_failed;
|
||||
}
|
||||
else
|
||||
switch (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"));
|
||||
return ts_done;
|
||||
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;
|
||||
}
|
||||
|
||||
file->updated = 1;
|
||||
return file->update_status;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
/* 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.
|
||||
|
||||
On return, FILE->update_status will no longer be -1 if it was. */
|
||||
|
||||
@@ -696,6 +683,7 @@ 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:
|
||||
@@ -722,7 +710,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) ? 1 : 0;
|
||||
file->update_status = touch_file (file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,7 +746,7 @@ notice_finished_file (file)
|
||||
f->last_mtime = file->last_mtime;
|
||||
}
|
||||
|
||||
if (ran)
|
||||
if (ran && file->update_status != -1)
|
||||
/* 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.
|
||||
@@ -766,6 +754,7 @@ 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)
|
||||
@@ -775,6 +764,10 @@ 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)
|
||||
@@ -782,13 +775,9 @@ 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. */
|
||||
|
||||
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
|
||||
static int
|
||||
check_dep (file, depth, this_mtime, must_make_ptr)
|
||||
struct file *file;
|
||||
unsigned int depth;
|
||||
@@ -796,10 +785,10 @@ check_dep (file, depth, this_mtime, must_make_ptr)
|
||||
int *must_make_ptr;
|
||||
{
|
||||
register struct dep *d;
|
||||
target_state_t dep_status = ts_done;
|
||||
int dep_status = 0;
|
||||
|
||||
++depth;
|
||||
set_updating(file);
|
||||
file->updating = 1;
|
||||
|
||||
if (!file->intermediate)
|
||||
/* If this is a non-intermediate file, update it and record
|
||||
@@ -824,6 +813,7 @@ 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)
|
||||
@@ -850,7 +840,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
|
||||
d = file->deps;
|
||||
while (d != 0)
|
||||
{
|
||||
if (tst_updating(d->file))
|
||||
if (d->file->updating)
|
||||
{
|
||||
error (NILF, _("Circular %s <- %s dependency dropped."),
|
||||
file->name, d->file->name);
|
||||
@@ -873,7 +863,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 == ts_failed && !keep_going_flag)
|
||||
if (dep_status != 0 && !keep_going_flag)
|
||||
break;
|
||||
|
||||
if (d->file->command_state == cs_running
|
||||
@@ -889,7 +879,7 @@ check_dep (file, depth, this_mtime, must_make_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
clr_updating(file);
|
||||
file->updating = 0;
|
||||
return dep_status;
|
||||
}
|
||||
|
||||
@@ -990,7 +980,7 @@ remake_file (file)
|
||||
error (NILF, msg_parent, "*** ",
|
||||
file->name, file->parent->name, ".");
|
||||
}
|
||||
file->update_status = 1;
|
||||
file->update_status = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1143,7 +1133,7 @@ f_mtime (file, search)
|
||||
static FILE_TIMESTAMP now = 0;
|
||||
if (!clock_skew_detected
|
||||
&& mtime != (FILE_TIMESTAMP)-1 && mtime > now
|
||||
&& !(file->command_state == cs_finished))
|
||||
&& !file->updated)
|
||||
{
|
||||
/* This file's time appears to be in the future.
|
||||
Update our concept of the present, and compare again. */
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
2000-02-07 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/escape: Add a test for backslash-escaped spaces
|
||||
in a target name (PR/1586).
|
||||
|
||||
2000-02-04 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/patspecific_vars: Add a test for PR/1407.
|
||||
* scripts/features/patspecific_vars: Add a test for pattern-specific
|
||||
target variables inherited from the parent target (PR/1407).
|
||||
|
||||
2000-02-02 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* run_make_tests.pl (set_more_defaults): Hard-code the LANG to C
|
||||
to make sure porting order, etc. is predictable.
|
||||
to make sure sorting order, etc. is predictable.
|
||||
Reported by Andreas Jaeger <aj@suse.de>.
|
||||
|
||||
* run_make_tests.pl (set_more_defaults): Set the $wtime variable
|
||||
@@ -17,6 +23,11 @@
|
||||
* scripts/targets/SECONDARY: Ditto.
|
||||
* scripts/targets/INTERMEDIATE: Ditto.
|
||||
|
||||
2000-01-27 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* test_driver.pl (toplevel): Don't try to run test scripts which
|
||||
are really directories.
|
||||
|
||||
2000-01-23 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* scripts/features/include: Remove a check; the fix caused more
|
||||
@@ -27,7 +38,7 @@
|
||||
|
||||
* scripts/functions/call: Add a test for PR/1517 and PR/1527: make
|
||||
sure $(call ...) doesn't eval its arguments and that you can
|
||||
invoke foreach from it without infinitely looping.
|
||||
invoke foreach from it without looping forever.
|
||||
|
||||
1999-12-15 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
# -*-perl-*-
|
||||
$description = "Test various types of escaping in makefiles.";
|
||||
|
||||
$details = "Make sure that escaping of `:' works in target names.";
|
||||
$details = "\
|
||||
Make sure that escaping of `:' works in target names.
|
||||
Also make sure escaping of whitespace works in target names";
|
||||
|
||||
open(MAKEFILE,"> $makefile");
|
||||
|
||||
print MAKEFILE '$(path)foo : ; @echo cp $^ $@
|
||||
';
|
||||
print MAKEFILE <<'EOF';
|
||||
$(path)foo : ; @echo cp $^ $@
|
||||
|
||||
foo\ bar: ; @echo 'touch "$@"'
|
||||
EOF
|
||||
|
||||
close(MAKEFILE);
|
||||
|
||||
@@ -34,5 +40,11 @@ $answer = "cp p:foo\n";
|
||||
$answer = "$makefile:1: *** target pattern contains no `%'. Stop.\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
# TEST 5: This one should work
|
||||
|
||||
&run_make_with_options($makefile, "'foo bar'", &get_logfile, 0);
|
||||
$answer = "touch \"foo bar\"\n";
|
||||
&compare_output($answer,&get_logfile(1));
|
||||
|
||||
# This tells the test driver that the perl test script executed properly.
|
||||
1;
|
||||
|
||||
@@ -117,7 +117,8 @@ sub toplevel
|
||||
closedir (SCRIPTDIR);
|
||||
foreach $dir (@dirs)
|
||||
{
|
||||
next if ! -d "$scriptpath/$dir" || $dir =~ /^\.\.?$/ || $dir eq 'CVS';
|
||||
next if ($dir =~ /^\.\.?$/ || $dir eq 'CVS' || $dir eq 'RCS'
|
||||
|| ! -d "$scriptpath/$dir");
|
||||
push (@rmdirs, $dir);
|
||||
mkdir ("$workpath/$dir", 0777)
|
||||
|| &error ("Couldn't mkdir $workpath/$dir: $!\n");
|
||||
@@ -127,7 +128,7 @@ sub toplevel
|
||||
closedir (SCRIPTDIR);
|
||||
foreach $test (@files)
|
||||
{
|
||||
next if $test =~ /^\.\.?$/ || $test =~ /~$/ || $test eq 'CVS';
|
||||
next if $test =~ /~$/ || -d $test;
|
||||
push (@TESTS, "$dir/$test");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user