[SV 58735] Define the order that makefiles are rebuilt.

Ensure that makefiles are rebuilt in the order in which make first
considered them, and document this behavior in the manual.

* NEWS: Add a note about the new behavior
* doc/make.text (How make Processes a Makefile): Document it.
* main.c (main): Inverse the list of makefile goals.
* read.c (read_all_makefiles): Add default makefiles to the list at
the front in reverse order, the same way other makefiles are added.
* tests/scripts/features/include: Add tests to verify rebuild order.
This commit is contained in:
Paul Smith 2020-07-19 13:56:23 -04:00
parent db7658e042
commit 62e8f029e9
5 changed files with 65 additions and 33 deletions

9
NEWS
View File

@ -17,10 +17,17 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
* WARNING: Backward-incompatibility!
Previously if --no-print-directory was seen anywhere in the environment or
command line it would take precedence over --print-directory. Now, the
command line it would take precedence over any --print-directory. Now, the
last setting of directory printing options seen will be used, so a command
line such as "--no-print-directory -w" _will_ show directory entry/exits.
* WARNING: Backward-incompatibility!
Previously the order in which makefiles were remade was not explicitly
stated, but it was (roughly) the inverse of the order in which they were
processed by make. In this release, the order in which makefiles are
rebuilt is the same order in which make processed them, and this is defined
to be true in the GNU make manual.
* GNU Make can now be built for MS-Windows using the Tiny C tcc compiler.

View File

@ -1346,16 +1346,21 @@ files. If a makefile can be remade from other files, you probably want
@code{make} to get an up-to-date version of the makefile to read in.
To this end, after reading in all makefiles @code{make} will consider
each as a goal target and attempt to update it. If a makefile has a
rule which says how to update it (found either in that very makefile or
in another one) or if an implicit rule applies to it (@pxref{Implicit
Rules, ,Using Implicit Rules}), it will be updated if necessary. After
all makefiles have been checked, if any have actually been changed,
@code{make} starts with a clean slate and reads all the makefiles over
again. (It will also attempt to update each of them over again, but
normally this will not change them again, since they are already up to
date.) Each restart will cause the special variable
@code{MAKE_RESTARTS} to be updated (@pxref{Special Variables}).@refill
each as a goal target, in the order in which they were processed, and
attempt to update it. If parallel builds (@pxref{Parallel, ,Parallel
Execution}) are enabled then makefiles will be rebuilt in parallel as
well.
If a makefile has a rule which says how to update it (found either in
that very makefile or in another one) or if an implicit rule applies
to it (@pxref{Implicit Rules, ,Using Implicit Rules}), it will be
updated if necessary. After all makefiles have been checked, if any
have actually been changed, @code{make} starts with a clean slate and
reads all the makefiles over again. (It will also attempt to update
each of them over again, but normally this will not change them again,
since they are already up to date.) Each restart will cause the
special variable @code{MAKE_RESTARTS} to be updated (@pxref{Special
Variables}).@refill
If you know that one or more of your makefiles cannot be remade and
you want to keep @code{make} from performing an implicit rule search
@ -1384,12 +1389,11 @@ if a default makefile does not exist but can be created by running
@code{make} rules, you probably want the rules to be run so that the
makefile can be used.
Therefore, if none of the default makefiles exists, @code{make} will try
to make each of them in the same order in which they are searched for
(@pxref{Makefile Names, ,What Name to Give Your Makefile})
until it succeeds in making one, or it runs out of names to try. Note
that it is not an error if @code{make} cannot find or make any makefile;
a makefile is not always necessary.@refill
Therefore, if none of the default makefiles exists, @code{make} will
try to make each of them until it succeeds in making one, or it runs
out of names to try. Note that it is not an error if @code{make}
cannot find or make any makefile; a makefile is not always
necessary.@refill
When you use the @samp{-t} or @samp{--touch} option
(@pxref{Instead of Execution, ,Instead of Executing Recipes}),

View File

@ -2188,11 +2188,20 @@ main (int argc, char **argv, char **envp)
DB (DB_BASIC, (_("Updating makefiles....\n")));
/* Count the makefiles, and reverse the order so that we attempt to
rebuild them in the order they were read. */
{
struct goaldep *d;
unsigned int num_mkfiles = 0;
for (d = read_files; d != NULL; d = d->next)
++num_mkfiles;
struct goaldep *d = read_files;
read_files = NULL;
while (d != NULL)
{
struct goaldep *t = d;
d = d->next;
t->next = read_files;
read_files = t;
++num_mkfiles;
}
makefile_mtimes = alloca (num_mkfiles * sizeof (FILE_TIMESTAMP));
}

View File

@ -263,10 +263,6 @@ read_all_makefiles (const char **makefiles)
{
/* No default makefile was found. Add the default makefiles to the
'read_files' chain so they will be updated if possible. */
struct goaldep *tail = read_files;
/* Add them to the tail, after any MAKEFILES variable makefiles. */
while (tail != 0 && tail->next != 0)
tail = tail->next;
for (p = default_makefiles; *p != 0; ++p)
{
struct goaldep *d = alloc_goaldep ();
@ -274,14 +270,9 @@ read_all_makefiles (const char **makefiles)
/* Tell update_goal_chain to bail out as soon as this file is
made, and main not to die if we can't make this file. */
d->flags = RM_DONTCARE;
if (tail == 0)
read_files = d;
else
tail->next = d;
tail = d;
d->next = read_files;
read_files = d;
}
if (tail != 0)
tail->next = 0;
}
}

View File

@ -157,7 +157,7 @@ include inc1
include inc2
inc2:; echo > $@
!,
'', "echo > inc2\necho > inc1\nDONE\n");
'', "echo > inc1\necho > inc2\nDONE\n");
rmfiles('inc1', 'inc2');
@ -209,7 +209,7 @@ inc1:; echo > $@
include inc1
include inc2
!,
'', "#MAKEFILE#:7: inc2: $ERR_no_such_file\n#MAKE#: *** No rule to make target 'inc2'. Stop.\n", 512);
'', "echo > inc1\n#MAKEFILE#:7: inc2: $ERR_no_such_file\n#MAKE#: *** No rule to make target 'inc2'. Stop.\n", 512);
rmfiles('inc1');
@ -260,4 +260,25 @@ inc1:; @%s $@ && echo FOO := bar > $@
rmfiles('inc1');
}
# Check that the order of remaking include files is correct: should remake
# them in the same order they were encountered in the makefile. SV 58735
run_make_test(q!
-include i1 i2
-include i3
-include i4
%:;@echo $@
all:;
!,
'', "i1\ni2\ni3\ni4\n#MAKE#: 'all' is up to date.\n");
rmfiles('foo');
# Check the default makefiles... this requires us to invoke make with no
# arguments. Also check MAKEFILES
$ENV{MAKEFILES} = 'foobar barfoo';
run_make_with_options(undef, q!-E '%:;@echo $@' -E 'all:;' -E '-include bizbaz' -E '-include bazbiz'!, get_logfile(0));
$answer = "bizbaz\nbazbiz\nfoobar\nbarfoo\nGNUmakefile\nmakefile\nMakefile\n#MAKE#: 'all' is up to date.\n";
&compare_output(subst_make_string($answer), &get_logfile(1));
1;