]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 58735] Define the order that makefiles are rebuilt.
authorPaul Smith <psmith@gnu.org>
Sun, 19 Jul 2020 17:56:23 +0000 (13:56 -0400)
committerPaul Smith <psmith@gnu.org>
Sun, 19 Jul 2020 17:56:23 +0000 (13:56 -0400)
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.

NEWS
doc/make.texi
src/main.c
src/read.c
tests/scripts/features/include

diff --git a/NEWS b/NEWS
index 6a04680e9138cceacded1908e5ab396bed23c7ce..81b5726a09464ed758bd8cb60c8bb9ca1822bf6f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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.
 
 \f
index 733c0b962de4f335db4edfa1a6900ccd6053586c..21573c00ed7dfea478e86c211ffcc32cd417cd2b 100644 (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}),
index bcba2d188deb85cbcb7eff9d3d6e10702c9fb2e1..c79a9f649bec5fbaee61888e7d5c7b8138ddd419 100644 (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));
       }
index db52a55bd6b24dcd2c176c40e5dd106ffb6739da..c55998c3dc7798dbc7be4bb605a9a50cfaecdd70 100644 (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;
         }
     }
 
index 0c63c067bc656c12db2d99a77776a20929488487..7dd17b5bfc9ed01ea8e3f0cb97c53e7df5fd15c0 100644 (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;