]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 60595] Restart whenever any makefile is rebuilt
authorPaul Smith <psmith@gnu.org>
Mon, 31 May 2021 18:37:09 +0000 (14:37 -0400)
committerPaul Smith <psmith@gnu.org>
Fri, 3 Sep 2021 16:08:11 +0000 (12:08 -0400)
Previously if an included makefile was rebuilt as a prerequisite of
another included makefile which didn't need to be rebuilt, make would
not realize that it needed to re-exec itself.

Ensure that if any included makefile target is rebuilt we re-exec.
Also ensure that if an included makefile is not readable, and our rule
for rebuilding it doesn't actually change it, we will still fail.

* src/remake.c (update_goal_chain): If a goal's update was successful
then check its status, even if no actual commands were run because it
was already up to date.
(show_goal_error): Remove superfluous cast.
* src/main.c (main): If the makefile remake did nothing, check that we
were able to successfully include all the makefiles we care about; if
not fail.  When generating error messages about included makefiles be
sure to show the filename/linenumber information.
* test/scripts/features/reinvoke: Add tests for this behavior.
* test/scripts/options/dash-k: Update error messages.

src/main.c
src/remake.c
tests/scripts/features/reinvoke
tests/scripts/options/dash-k

index 54060f2f55cb42966ee694d90d9bd02674260bf6..629f16654fe694941030289fb637d60c3905835f 100644 (file)
@@ -2295,10 +2295,28 @@ main (int argc, char **argv, char **envp)
              for one of the makefiles to be remade as a target on the command
              line.  Since we're not actually updating anything with -q we can
              treat this as "did nothing".  */
+          break;
 
         case us_none:
-          /* Did nothing.  */
-          break;
+          /* No makefiles needed to be updated.  If we couldn't read some
+             included file that we care about, fail.  */
+          {
+            int any_failed = 0;
+            struct goaldep *d;
+
+            for (d = read_files; d != 0; d = d->next)
+              if (d->error && ! (d->flags & RM_DONTCARE))
+                {
+                  /* This makefile couldn't be loaded, and we care.  */
+                  OSS (error, &d->floc,
+                       _("%s: %s"), dep_name (d), strerror (d->error));
+                  any_failed = 1;
+                }
+
+            if (any_failed)
+              die (MAKE_FAILURE);
+            break;
+          }
 
         case us_failed:
           /* Failed to update.  Figure out if we care.  */
@@ -2327,7 +2345,8 @@ main (int argc, char **argv, char **envp)
                         FILE_TIMESTAMP mtime;
                         /* The update failed and this makefile was not
                            from the MAKEFILES variable, so we care.  */
-                        OS (error, NILF, _("Failed to remake makefile '%s'."),
+                        OS (error, &d->floc,
+                            _("Failed to remake makefile '%s'."),
                             d->file->name);
                         mtime = file_mtime_no_search (d->file);
                         any_remade |= (mtime != NONEXISTENT_MTIME
@@ -2346,7 +2365,7 @@ main (int argc, char **argv, char **envp)
                       if (d->flags & RM_INCLUDED)
                         /* An included makefile.  We don't need to die, but we
                            do want to complain.  */
-                        error (NILF, l,
+                        error (&d->floc, l,
                                _("Included makefile '%s' was not found."), dnm);
                       else
                         {
index f7605fc062c5e0a916537f3b90f5d9f94af9625b..b20d37c71db86cba35c0f25831e5e62c7edfa2bf 100644 (file)
@@ -78,8 +78,8 @@ static FILE_TIMESTAMP name_mtime (const char *name);
 static const char *library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr);
 
 \f
-/* Remake all the goals in the 'struct dep' chain GOALS.  Return -1 if nothing
-   was done, 0 if all goals were updated successfully, or 1 if a goal failed.
+/* Remake all the goals in the 'struct dep' chain GOALS.  Return update_status
+   representing the totality of the status of the goals.
 
    If rebuilding_makefiles is nonzero, these goals are makefiles, so -t, -q,
    and -n should be disabled for them unless they were also command-line
@@ -185,8 +185,7 @@ update_goal_chain (struct goaldep *goaldeps)
                       FILE_TIMESTAMP mtime = MTIME (file);
                       check_renamed (file);
 
-                      if (file->updated && g->changed &&
-                           mtime != file->mtime_before_update)
+                      if (file->updated && mtime != file->mtime_before_update)
                         {
                           /* Updating was done.  If this is a makefile and
                              just_print_flag or question_flag is set (meaning
@@ -288,7 +287,7 @@ show_goal_error (void)
         if (goal->error)
           {
             OSS (error, &goal->floc, "%s: %s",
-                 goal->file->name, strerror ((int)goal->error));
+                 goal->file->name, strerror (goal->error));
             goal->error = 0;
           }
         return;
@@ -1421,7 +1420,7 @@ f_mtime (struct file *file, int search)
                     / 1e9));
               char from_now_string[100];
 
-              if (from_now >= 99 && from_now <= ULONG_MAX)
+              if (from_now >= 100.0 && from_now < (double) ULONG_MAX)
                 sprintf (from_now_string, "%lu", (unsigned long) from_now);
               else
                 sprintf (from_now_string, "%.2g", from_now);
index 657f6c9b57c4f99188f6b748acaa7c7e816c5df8..237c8385e768f92ec11f69cd2ba07c9265b1bc74 100644 (file)
@@ -17,9 +17,7 @@ $omkfile = $makefile;
 run_make_test('
 all: ; @echo running rules.
 
-#MAKEFILE# incl.mk: incl-1.mk
-       @echo rebuilding $@
-       @echo >> $@
+#MAKEFILE# incl.mk: incl-1.mk ; @echo rebuilding $@; echo >> $@
 
 include incl.mk',
               '', "rebuilding incl.mk\nrunning rules.\n");
@@ -74,9 +72,36 @@ foo30723: ; @touch $@
 
 unlink('foo30723');
 
+# If ANY makefile is rebuilt then we should re-exec
+
+run_make_test('
+all: ; @echo RESTARTS=$(MAKE_RESTARTS)
+
+m1.d: ; @echo $@; touch $@
+
+m2.d: m1.d ; @test -f $< || { echo $@; touch $@; }
+
+include m1.d
+-include m2.d
+',
+              '', "m1.d\nRESTARTS=1\n");
+
+unlink('m1.d', 'm2.d');
+
+# Same as before but be sure we get error messages for un-created makefiles
+
+run_make_test('
+all: ; @echo RESTARTS=$(MAKE_RESTARTS)
+
+m1.d: ; @echo $@; touch $@
+
+m2.d: m1.d ; @test -f $< || { echo $@; touch $@; }
+
+include m1.d m2.d
+',
+              '', "m1.d\n#MAKEFILE#:8: m2.d: $ERR_no_such_file\n", 512);
+
+unlink('m1.d', 'm2.d');
+
 # This tells the test driver that the perl test script executed properly.
 1;
-
-### Local Variables:
-### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
-### End:
index cd78e7f00ae8238113797fa5a439532f8ffd5463..323dff60c021d4211ab96b9966d6d2ed5de723b6 100644 (file)
@@ -108,7 +108,7 @@ ifile: no-such-file; @false
                   '-k',
                   "#MAKEFILE#:2: ifile: $ERR_no_such_file
 #MAKE#: *** No rule to make target 'no-such-file', needed by 'ifile'.
-#MAKE#: Failed to remake makefile 'ifile'.
+#MAKEFILE#:2: Failed to remake makefile 'ifile'.
 hi\n",
                   512);
 }