mirror of
https://github.com/mirror/make.git
synced 2024-12-27 13:20:34 +08:00
* Removed a memory stomp (reading freed memory).
* Fixed some infinite recursion on rebuilt makefiles bugs.
This commit is contained in:
parent
10fee1c03c
commit
e49b2f15c9
21
ChangeLog
21
ChangeLog
@ -1,3 +1,24 @@
|
||||
1999-09-03 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* remake.c (notice_finished_file): Always set mtime_before_update
|
||||
if it's not been set, not just if we ran some rules. Otherwise we
|
||||
may have a situation where a target's prerequisite was rebuilt but
|
||||
not changed, so this target's rules weren't run, then
|
||||
update_goal_chain() sees mtime_before_update != last_mtime and
|
||||
thinks that the top-level target changed when it really didn't.
|
||||
This can cause an infinite loop when remaking makefiles.
|
||||
(update_goal_chain): If we get back to the top and we don't know
|
||||
what the goal's last_mtime was, find it now. We need to know so
|
||||
we can compare it to mtime_before_update later (this is only
|
||||
crucial when remaking makefiles--should we only do it then?)
|
||||
|
||||
1999-09-02 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* read.c (read_makefile): If "override" appears as the first
|
||||
prerequisite, look further to ensure this is really a
|
||||
target-specific variable definition, and not just some
|
||||
prerequisite named "override".
|
||||
|
||||
1999-09-01 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* function.c (IS_PATHSEP) [WINDOWS32]: Allow backslash separators
|
||||
|
5
main.c
5
main.c
@ -1331,7 +1331,8 @@ int main (int argc, char ** argv)
|
||||
(ignore the jobserver pipe for this make) but print a message. */
|
||||
|
||||
if (job_slots > 0)
|
||||
error (NILF, _("warning: -jN set for submakes: ignoring jobserver."));
|
||||
error (NILF,
|
||||
_("warning: -jN forced in submake: disabling jobserver mode."));
|
||||
|
||||
/* Create a duplicate pipe, that will be closed in the SIGCHLD
|
||||
handler. If this fails with EBADF, the parent has closed the pipe
|
||||
@ -1344,7 +1345,7 @@ int main (int argc, char ** argv)
|
||||
pfatal_with_name (_("dup jobserver"));
|
||||
|
||||
error (NILF,
|
||||
_("warning: jobserver unavailable (using -j1). Add `+' to parent make rule."));
|
||||
_("warning: jobserver unavailable: using -j1. Add `+' to parent make rule."));
|
||||
job_slots = 1;
|
||||
}
|
||||
|
||||
|
67
read.c
67
read.c
@ -177,10 +177,12 @@ read_all_makefiles (makefiles)
|
||||
|
||||
while ((name = find_next_token (&p, &length)) != 0)
|
||||
{
|
||||
name = xstrdup (name);
|
||||
if (*p != '\0')
|
||||
*p++ = '\0';
|
||||
(void) read_makefile (name,
|
||||
RM_NO_DEFAULT_GOAL | RM_INCLUDED | RM_DONTCARE);
|
||||
if (read_makefile (name,
|
||||
RM_NO_DEFAULT_GOAL|RM_INCLUDED|RM_DONTCARE) < 2)
|
||||
free (name);
|
||||
}
|
||||
|
||||
free (value);
|
||||
@ -269,7 +271,9 @@ read_all_makefiles (makefiles)
|
||||
|
||||
FILENAME is added to the `read_makefiles' chain.
|
||||
|
||||
Returns 1 if a file was found and read, 0 if not. */
|
||||
Returns 0 if a file was not found or not read.
|
||||
Returns 1 if FILENAME was found and read.
|
||||
Returns 2 if FILENAME was read, and we kept a reference (don't free it). */
|
||||
|
||||
static int
|
||||
read_makefile (filename, flags)
|
||||
@ -289,6 +293,7 @@ read_makefile (filename, flags)
|
||||
int len, reading_target;
|
||||
int ignoring = 0, in_ignored_define = 0;
|
||||
int no_targets = 0; /* Set when reading a rule without targets. */
|
||||
int using_filename = 0;
|
||||
struct floc fileinfo;
|
||||
char *passed_filename = filename;
|
||||
|
||||
@ -307,10 +312,12 @@ read_makefile (filename, flags)
|
||||
do \
|
||||
{ \
|
||||
if (filenames != 0) \
|
||||
record_files (filenames, pattern, pattern_percent, deps, \
|
||||
cmds_started, commands, commands_idx, \
|
||||
two_colon, &fileinfo, \
|
||||
!(flags & RM_NO_DEFAULT_GOAL)); \
|
||||
{ \
|
||||
record_files (filenames, pattern, pattern_percent, deps, \
|
||||
cmds_started, commands, commands_idx, two_colon, \
|
||||
&fileinfo, !(flags & RM_NO_DEFAULT_GOAL)); \
|
||||
using_filename |= commands_idx > 0; \
|
||||
} \
|
||||
filenames = 0; \
|
||||
commands_idx = 0; \
|
||||
if (pattern) { free(pattern); pattern = 0; } \
|
||||
@ -685,16 +692,18 @@ read_makefile (filename, flags)
|
||||
{
|
||||
struct nameseq *next = files->next;
|
||||
char *name = files->name;
|
||||
int r;
|
||||
|
||||
free ((char *)files);
|
||||
files = next;
|
||||
|
||||
if (! read_makefile (name, (RM_INCLUDED | RM_NO_TILDE
|
||||
| (noerror ? RM_DONTCARE : 0)))
|
||||
&& ! noerror)
|
||||
r = read_makefile (name, (RM_INCLUDED | RM_NO_TILDE
|
||||
| (noerror ? RM_DONTCARE : 0)));
|
||||
if (!r && !noerror)
|
||||
error (&fileinfo, "%s: %s", name, strerror (errno));
|
||||
|
||||
/* We can't free NAME here, in case some of the commands,
|
||||
etc. still contain references to the filename. */
|
||||
if (r < 2)
|
||||
free (name);
|
||||
}
|
||||
|
||||
/* Free any space allocated by conditional_line. */
|
||||
@ -880,7 +889,7 @@ read_makefile (filename, flags)
|
||||
continue;
|
||||
}
|
||||
/* This should never be possible; we handled it above. */
|
||||
assert(*p2 != '\0');
|
||||
assert (*p2 != '\0');
|
||||
++p2;
|
||||
|
||||
/* Is this a one-colon or two-colon entry? */
|
||||
@ -895,25 +904,31 @@ read_makefile (filename, flags)
|
||||
if (*lb_next != '\0')
|
||||
{
|
||||
unsigned int l = p2 - variable_buffer;
|
||||
plen = strlen(p2);
|
||||
(void)variable_buffer_output(p2+plen,
|
||||
lb_next, strlen(lb_next)+1);
|
||||
plen = strlen (p2);
|
||||
(void) variable_buffer_output (p2+plen,
|
||||
lb_next, strlen (lb_next)+1);
|
||||
p2 = variable_buffer + l;
|
||||
}
|
||||
wtype = get_next_mword(p2, NULL, &p, &len);
|
||||
|
||||
/* See if it's an "override" keyword; if so see if what comes after
|
||||
it looks like a variable definition. */
|
||||
|
||||
wtype = get_next_mword (p2, NULL, &p, &len);
|
||||
|
||||
v_origin = o_file;
|
||||
if (wtype == w_static && (len == (sizeof("override")-1)
|
||||
&& strneq(p, "override", len)))
|
||||
if (wtype == w_static && (len == (sizeof ("override")-1)
|
||||
&& strneq (p, "override", len)))
|
||||
{
|
||||
v_origin = o_override;
|
||||
(void)get_next_mword(p+len, NULL, &p, &len);
|
||||
wtype = get_next_mword (p+len, NULL, &p, &len);
|
||||
}
|
||||
else if (wtype != w_eol)
|
||||
wtype = get_next_mword(p+len, NULL, NULL, NULL);
|
||||
|
||||
if (wtype == w_varassign || v_origin == o_override)
|
||||
if (wtype != w_eol)
|
||||
wtype = get_next_mword (p+len, NULL, NULL, NULL);
|
||||
|
||||
if (wtype == w_varassign)
|
||||
{
|
||||
record_target_var(filenames, p, two_colon, v_origin, &fileinfo);
|
||||
record_target_var (filenames, p, two_colon, v_origin, &fileinfo);
|
||||
filenames = 0;
|
||||
continue;
|
||||
}
|
||||
@ -929,7 +944,7 @@ read_makefile (filename, flags)
|
||||
if (*lb_next != '\0')
|
||||
{
|
||||
unsigned int l = p2 - variable_buffer;
|
||||
(void)variable_expand_string(p2 + plen, lb_next, (long)-1);
|
||||
(void) variable_expand_string (p2 + plen, lb_next, (long)-1);
|
||||
p2 = variable_buffer + l;
|
||||
|
||||
/* Look for a semicolon in the expanded line. */
|
||||
@ -1046,7 +1061,7 @@ read_makefile (filename, flags)
|
||||
|
||||
reading_file = 0;
|
||||
|
||||
return 1;
|
||||
return 1+using_filename;
|
||||
}
|
||||
|
||||
/* Execute a `define' directive.
|
||||
|
18
remake.c
18
remake.c
@ -1,5 +1,5 @@
|
||||
/* Basic dependency engine for GNU Make.
|
||||
Copyright (C) 1988,89,90,91,92,93,94,95,96,97 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988,89,90,91,92,93,94,95,96,97,99 Free Software Foundation, Inc.
|
||||
This file is part of GNU Make.
|
||||
|
||||
GNU Make is free software; you can redistribute it and/or modify
|
||||
@ -154,6 +154,13 @@ update_goal_chain (goals, makefiles)
|
||||
x = update_file (file, makefiles ? 1 : 0);
|
||||
check_renamed (file);
|
||||
|
||||
/* If we don't know what the file's last mtime was, find it. */
|
||||
if (! file->last_mtime)
|
||||
{
|
||||
(void) f_mtime (file, 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. */
|
||||
@ -553,7 +560,8 @@ update_file_1 (file, depth)
|
||||
|
||||
if (depth == 0 && keep_going_flag
|
||||
&& !just_print_flag && !question_flag)
|
||||
error (NILF, _("Target `%s' not remade because of errors."), file->name);
|
||||
error (NILF,
|
||||
_("Target `%s' not remade because of errors."), file->name);
|
||||
|
||||
return dep_status;
|
||||
}
|
||||
@ -736,13 +744,13 @@ notice_finished_file (file)
|
||||
}
|
||||
}
|
||||
|
||||
if (file->mtime_before_update == 0)
|
||||
file->mtime_before_update = file->last_mtime;
|
||||
|
||||
if (ran && !file->phony)
|
||||
{
|
||||
struct file *f;
|
||||
|
||||
assert(file->mtime_before_update == 0);
|
||||
file->mtime_before_update = file->last_mtime;
|
||||
|
||||
if (just_print_flag || question_flag
|
||||
|| (file->is_target && file->cmds == 0))
|
||||
file->last_mtime = NEW_MTIME;
|
||||
|
Loading…
Reference in New Issue
Block a user