]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 102] Don't show unnecessary include file errors.
authorPaul Smith <psmith@gnu.org>
Sat, 9 Apr 2016 23:49:27 +0000 (19:49 -0400)
committerPaul Smith <psmith@gnu.org>
Sun, 10 Apr 2016 00:06:46 +0000 (20:06 -0400)
Delay the generation of error messages for included files until we
are sure that we can't rebuild that included file.
* dep.h (struct dep): Don't reuse "changed"; make a separate field
to keep "flags".  Get rid of dontcare and use the flag.
(struct goaldep): Create a new structure for goal prereqs
that tracks an errno value and the floc where the include happened.
Rework the structures to ensure they are supersets as expected.
In maintainer mode with GCC, use inline to get type checking.
* read.c (eval_makefile): Return a struct goaldep for the new
makefile.  Ensure errno is set properly to denote a failure.
(read_all_makefiles): Switch to goaldep and check errno.
(eval): Don't show included file errors; instead remember them.
* remake.c (update_goal_chain): Set global variables to the current
goaldep we're building, and the entire chain.
(show_goal_error): Check if the current failure is a consequence
of building an included makefile and if so print an error.
(complain): Call show_goal_error() on rule failure.
* job.c (child_error): Call show_goal_error() on child error.
* main.c (main): Switch from struct dep to goaldep.
* misc.c (free_dep_chain): Not used; make into a macro.
* tests/scripts/features/include: Update and include new tests.
* tests/scripts/options/dash-B, tests/scripts/options/dash-W,
tests/scripts/options/print-directory,
tests/scripts/variables/MAKE_RESTARTS: Update known-good-output.

dep.h
job.c
main.c
misc.c
read.c
remake.c
tests/scripts/features/include
tests/scripts/options/dash-B
tests/scripts/options/dash-W
tests/scripts/options/print-directory
tests/scripts/variables/MAKE_RESTARTS

diff --git a/dep.h b/dep.h
index 10bf947e43148e16db309e44740de26373b8b5ea..1cd6cb0b8e1ad357839d38e988ec854c2592d609 100644 (file)
--- a/dep.h
+++ b/dep.h
@@ -14,9 +14,21 @@ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 You should have received a copy of the GNU General Public License along with
 this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+
+/* Structure used in chains of names, for parsing and globbing.  */
+
+#define NAMESEQ(_t)     \
+    _t *next;           \
+    const char *name
+
+struct nameseq
+  {
+    NAMESEQ (struct nameseq);
+  };
+
 /* Flag bits for the second argument to 'read_makefile'.
-   These flags are saved in the 'changed' field of each
-   'struct dep' in the chain returned by 'read_all_makefiles'.  */
+   These flags are saved in the 'flags' field of each
+   'struct goaldep' in the chain returned by 'read_all_makefiles'.  */
 
 #define RM_NO_DEFAULT_GOAL      (1 << 0) /* Do not set default goal.  */
 #define RM_INCLUDED             (1 << 1) /* Search makefile search path.  */
@@ -25,34 +37,37 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #define RM_NOFLAG               0
 
 /* Structure representing one dependency of a file.
-   Each struct file's 'deps' points to a chain of these,
-   chained through the 'next'. 'stem' is the stem for this
-   dep line of static pattern rule or NULL.
-
-   Note that the first two words of this match a struct nameseq.  */
+   Each struct file's 'deps' points to a chain of these, through 'next'.
+   'stem' is the stem for this dep line of static pattern rule or NULL.  */
+
+#define DEP(_t)                                 \
+    NAMESEQ (_t);                               \
+    struct file *file;                          \
+    const char *stem;                           \
+    unsigned short flags : 8;                   \
+    unsigned short changed : 1;                 \
+    unsigned short ignore_mtime : 1;            \
+    unsigned short staticpattern : 1;           \
+    unsigned short need_2nd_expansion : 1
 
 struct dep
   {
-    struct dep *next;
-    const char *name;
-    const char *stem;
-    struct file *file;
-    unsigned int changed : 8;
-    unsigned int ignore_mtime : 1;
-    unsigned int staticpattern : 1;
-    unsigned int need_2nd_expansion : 1;
-    unsigned int dontcare : 1;
+    DEP (struct dep);
   };
 
+/* Structure representing one goal.
+   The goals to be built constitute a chain of these, chained through 'next'.
+   'stem' is not used, but it's simpler to include and ignore it.  */
 
-/* Structure used in chains of names, for parsing and globbing.  */
-
-struct nameseq
+struct goaldep
   {
-    struct nameseq *next;
-    const char *name;
+    DEP (struct goaldep);
+    unsigned short error;
+    gmk_floc floc;
   };
 
+/* Options for parsing lists of filenames.  */
+
 #define PARSEFS_NONE    0x0000
 #define PARSEFS_NOSTRIP 0x0001
 #define PARSEFS_NOAR    0x0002
@@ -78,15 +93,40 @@ char *tilde_expand (const char *name);
 struct nameseq *ar_glob (const char *arname, const char *member_pattern, unsigned int size);
 #endif
 
-#define dep_name(d)     ((d)->name == 0 ? (d)->file->name : (d)->name)
+#define dep_name(d)        ((d)->name ? (d)->name : (d)->file->name)
+
+#define alloc_seq_elt(_t)   xcalloc (sizeof (_t))
+void free_ns_chain (struct nameseq *n);
+
+#if defined(MAKE_MAINTAINER_MODE) && defined(__GNUC__)
+/* Use inline to get real type-checking.  */
+#define SI static inline
+SI struct nameseq *alloc_ns()      { return alloc_seq_elt (struct nameseq); }
+SI struct dep *alloc_dep()         { return alloc_seq_elt (struct dep); }
+SI struct goaldep *alloc_goaldep() { return alloc_seq_elt (struct goaldep); }
+
+SI void free_ns(struct nameseq *n)      { free (n); }
+SI void free_dep(struct dep *d)         { free_ns ((struct nameseq *)d); }
+SI void free_goaldep(struct goaldep *g) { free_dep ((struct dep *)g); }
 
-#define alloc_dep()     (xcalloc (sizeof (struct dep)))
-#define free_ns(_n)     free (_n)
-#define free_dep(_d)    free_ns (_d)
+SI void free_dep_chain(struct dep *d)      { free_ns_chain((struct nameseq *)d); }
+SI void free_goal_chain(struct goaldep *g) { free_dep_chain((struct dep *)g); }
+#else
+# define alloc_ns()          alloc_seq_elt (struct nameseq)
+# define alloc_dep()         alloc_seq_elt (struct dep)
+# define alloc_goaldep()     alloc_seq_elt (struct goaldep)
+
+# define free_ns(_n)         free (_n)
+# define free_dep(_d)        free_ns (_d)
+# define free_goaldep(_g)    free_dep (_g)
+
+# define free_dep_chain(_d)  free_ns_chain ((struct nameseq *)(_d))
+# define free_goal_chain(_g) free_ns_chain ((struct nameseq *)(_g))
+#endif
 
 struct dep *copy_dep_chain (const struct dep *d);
-void free_dep_chain (struct dep *d);
-void free_ns_chain (struct nameseq *n);
-struct dep *read_all_makefiles (const char **makefiles);
+
+struct goaldep *read_all_makefiles (const char **makefiles);
 void eval_buffer (char *buffer, const gmk_floc *floc);
-enum update_status update_goal_chain (struct dep *goals);
+enum update_status update_goal_chain (struct goaldep *goals);
+void show_goal_error ();
diff --git a/job.c b/job.c
index 66dde71c6e3301d50c32c86e9e4dc23d8ab660c6..59f51cd24c64eda3873ff1e08ab0448b64244ad4 100644 (file)
--- a/job.c
+++ b/job.c
@@ -508,6 +508,8 @@ child_error (struct child *child,
 
   OUTPUT_SET (&child->output);
 
+  show_goal_error ();
+
   if (exit_sig == 0)
     error (NILF, l + INTSTR_LENGTH,
            _("%s[%s: %s] Error %d%s"), pre, nm, f->name, exit_code, post);
diff --git a/main.c b/main.c
index ee08720ff724f25f719c18c8ed4ec144fb8e8091..73eaf18155780fc93c34c6e0ca3a54ffc4f00a06 100644 (file)
--- a/main.c
+++ b/main.c
@@ -503,7 +503,7 @@ static struct option long_option_aliases[] =
 
 /* List of goal targets.  */
 
-static struct dep *goals, *lastgoal;
+static struct goaldep *goals, *lastgoal;
 
 /* List of variables which were defined on the command line
    (or, equivalently, in MAKEFLAGS).  */
@@ -1079,7 +1079,7 @@ main (int argc, char **argv, char **envp)
 {
   static char *stdin_nm = 0;
   int makefile_status = MAKE_SUCCESS;
-  struct dep *read_files;
+  struct goaldep *read_files;
   PATH_VAR (current_directory);
   unsigned int restarts = 0;
   unsigned int syncing = 0;
@@ -2106,7 +2106,7 @@ main (int argc, char **argv, char **envp)
 
   define_makeflags (1, 0);
 
-  /* Make each 'struct dep' point at the 'struct file' for the file
+  /* Make each 'struct goaldep' point at the 'struct file' for the file
      depended on.  Also do magic for special targets.  */
 
   snap_deps ();
@@ -2184,7 +2184,7 @@ main (int argc, char **argv, char **envp)
       /* Remove any makefiles we don't want to try to update.
          Also record the current modtimes so we can compare them later.  */
       {
-        register struct dep *d, *last;
+        register struct goaldep *d, *last;
         last = 0;
         d = read_files;
         while (d != 0)
@@ -2213,7 +2213,7 @@ main (int argc, char **argv, char **envp)
                         last->next = d->next;
 
                       /* Free the storage.  */
-                      free_dep (d);
+                      free_goaldep (d);
 
                       d = last == 0 ? read_files : last->next;
 
@@ -2270,7 +2270,7 @@ main (int argc, char **argv, char **envp)
                in updating or could not be found at all.  */
             int any_failed = 0;
             unsigned int i;
-            struct dep *d;
+            struct goaldep *d;
 
             for (i = 0, d = read_files; d != 0; ++i, d = d->next)
               {
@@ -2287,7 +2287,7 @@ main (int argc, char **argv, char **envp)
                         any_remade |= (file_mtime_no_search (d->file)
                                        != makefile_mtimes[i]);
                       }
-                    else if (! (d->changed & RM_DONTCARE))
+                    else if (! (d->flags & RM_DONTCARE))
                       {
                         FILE_TIMESTAMP mtime;
                         /* The update failed and this makefile was not
@@ -2302,13 +2302,13 @@ main (int argc, char **argv, char **envp)
                   }
                 else
                   /* This makefile was not found at all.  */
-                  if (! (d->changed & RM_DONTCARE))
+                  if (! (d->flags & RM_DONTCARE))
                     {
                       const char *dnm = dep_name (d);
                       size_t l = strlen (dnm);
 
                       /* This is a makefile we care about.  See how much.  */
-                      if (d->changed & RM_INCLUDED)
+                      if (d->flags & RM_INCLUDED)
                         /* An included makefile.  We don't need to die, but we
                            do want to complain.  */
                         error (NILF, l,
@@ -2544,7 +2544,7 @@ main (int argc, char **argv, char **envp)
 
           if (f)
             {
-              goals = alloc_dep ();
+              goals = alloc_goaldep ();
               goals->file = f;
             }
         }
@@ -2730,12 +2730,12 @@ handle_non_switch_argument (const char *arg, int env)
 
       if (goals == 0)
         {
-          goals = alloc_dep ();
+          goals = alloc_goaldep ();
           lastgoal = goals;
         }
       else
         {
-          lastgoal->next = alloc_dep ();
+          lastgoal->next = alloc_goaldep ();
           lastgoal = lastgoal->next;
         }
 
diff --git a/misc.c b/misc.c
index f2fa24f172689812c2835188881bcacdb05c6029..e7ab809242932c958af27ec66fc3aca354bb0330 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -376,19 +376,6 @@ copy_dep_chain (const struct dep *d)
   return firstnew;
 }
 
-/* Free a chain of 'struct dep'.  */
-
-void
-free_dep_chain (struct dep *d)
-{
-  while (d != 0)
-    {
-      struct dep *df = d;
-      d = d->next;
-      free_dep (df);
-    }
-}
-
 /* Free a chain of struct nameseq.
    For struct dep chains use free_dep_chain.  */
 
@@ -399,7 +386,7 @@ free_ns_chain (struct nameseq *ns)
     {
       struct nameseq *t = ns;
       ns = ns->next;
-      free (t);
+      free_ns (t);
     }
 }
 \f
diff --git a/read.c b/read.c
index 08739a541f2376d348dbd3b4a6a11c14fbcd11f7..10b250e70d569f1945e1fd2c7015b605f7d33d6c 100644 (file)
--- a/read.c
+++ b/read.c
@@ -132,9 +132,9 @@ const gmk_floc *reading_file = 0;
 
 /* The chain of files read by read_all_makefiles.  */
 
-static struct dep *read_files = 0;
+static struct goaldep *read_files = 0;
 
-static int eval_makefile (const char *filename, int flags);
+static struct goaldep *eval_makefile (const char *filename, int flags);
 static void eval (struct ebuffer *buffer, int flags);
 
 static long readline (struct ebuffer *ebuf);
@@ -167,7 +167,7 @@ static char *unescape_char (char *string, int c);
 \f
 /* Read in all the makefiles and return a chain of targets to rebuild.  */
 
-struct dep *
+struct goaldep *
 read_all_makefiles (const char **makefiles)
 {
   unsigned int num_makefiles = 0;
@@ -217,17 +217,11 @@ read_all_makefiles (const char **makefiles)
   if (makefiles != 0)
     while (*makefiles != 0)
       {
-        struct dep *tail = read_files;
-        struct dep *d;
+        struct goaldep *d = eval_makefile (*makefiles, 0);
 
-        if (! eval_makefile (*makefiles, 0))
+        if (errno)
           perror_with_name ("", *makefiles);
 
-        /* Find the first element eval_makefile() added to read_files.  */
-        d = read_files;
-        while (d->next != tail)
-          d = d->next;
-
         /* Reuse the storage allocated for the read_file.  */
         *makefiles = dep_name (d);
         ++num_makefiles;
@@ -260,25 +254,25 @@ read_all_makefiles (const char **makefiles)
 
       if (*p != 0)
         {
-          if (! eval_makefile (*p, 0))
+          eval_makefile (*p, 0);
+          if (errno)
             perror_with_name ("", *p);
         }
       else
         {
           /* No default makefile was found.  Add the default makefiles to the
              'read_files' chain so they will be updated if possible.  */
-          struct dep *tail = read_files;
+          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 dep *d = alloc_dep ();
+              struct goaldep *d = alloc_goaldep ();
               d->file = enter_file (strcache_add (*p));
-              d->dontcare = 1;
               /* 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->changed = RM_DONTCARE;
+              d->flags = RM_DONTCARE;
               if (tail == 0)
                 read_files = d;
               else
@@ -319,10 +313,10 @@ restore_conditionals (struct conditionals *saved)
   conditionals = saved;
 }
 \f
-static int
+static struct goaldep *
 eval_makefile (const char *filename, int flags)
 {
-  struct dep *deps;
+  struct goaldep *deps;
   struct ebuffer ebuf;
   const gmk_floc *curfile;
   char *expanded = 0;
@@ -401,16 +395,14 @@ eval_makefile (const char *filename, int flags)
   filename = strcache_add (filename);
 
   /* Add FILENAME to the chain of read makefiles.  */
-  deps = alloc_dep ();
+  deps = alloc_goaldep ();
   deps->next = read_files;
   read_files = deps;
   deps->file = lookup_file (filename);
   if (deps->file == 0)
     deps->file = enter_file (filename);
   filename = deps->file->name;
-  deps->changed = flags;
-  if (flags & RM_DONTCARE)
-    deps->dontcare = 1;
+  deps->flags = flags;
 
   free (expanded);
 
@@ -419,10 +411,10 @@ eval_makefile (const char *filename, int flags)
   if (ebuf.fp == 0)
     {
       /* If we did some searching, errno has the error from the last
-         attempt, rather from FILENAME itself.  Restore it in case the
+         attempt, rather from FILENAME itself.  Store it in case the
          caller wants to use it in a message.  */
       errno = makefile_errno;
-      return 0;
+      return deps;
     }
 
   /* Set close-on-exec to avoid leaking the makefile to children, such as
@@ -452,7 +444,8 @@ eval_makefile (const char *filename, int flags)
   free (ebuf.bufstart);
   alloca (0);
 
-  return 1;
+  errno = 0;
+  return deps;
 }
 
 void
@@ -903,21 +896,20 @@ eval (struct ebuffer *ebuf, int set_default)
           while (files != 0)
             {
               struct nameseq *next = files->next;
-              const char *name = files->name;
-              int r;
+              int flags = (RM_INCLUDED | RM_NO_TILDE
+                           | (noerror ? RM_DONTCARE : 0)
+                           | (set_default ? 0 : RM_NO_DEFAULT_GOAL));
 
-              free_ns (files);
-              files = next;
+              struct goaldep *d = eval_makefile (files->name, flags);
 
-              r = eval_makefile (name,
-                                 (RM_INCLUDED | RM_NO_TILDE
-                                  | (noerror ? RM_DONTCARE : 0)
-                                  | (set_default ? 0 : RM_NO_DEFAULT_GOAL)));
-              if (!r && !noerror)
+              if (errno)
                 {
-                  const char *err = strerror (errno);
-                  OSS (error, fstart, "%s: %s", name, err);
+                  d->error = (unsigned short)errno;
+                  d->floc = *fstart;
                 }
+
+              free_ns (files);
+              files = next;
             }
 
           /* Restore conditional state.  */
@@ -957,7 +949,7 @@ eval (struct ebuffer *ebuf, int set_default)
             {
               struct nameseq *next = files->next;
               const char *name = files->name;
-              struct dep *deps;
+              struct goaldep *deps;
               int r;
 
               /* Load the file.  0 means failure.  */
@@ -973,7 +965,7 @@ eval (struct ebuffer *ebuf, int set_default)
                 continue;
 
               /* It succeeded, so add it to the list "to be rebuilt".  */
-              deps = alloc_dep ();
+              deps = alloc_goaldep ();
               deps->next = read_files;
               read_files = deps;
               deps->file = lookup_file (name);
index e7a7d495a4965d55618f5d15e41b2b6e0e1b968d..1722474a486bfa3c15b5585afde82b729b39db5c 100644 (file)
--- a/remake.c
+++ b/remake.c
@@ -55,6 +55,10 @@ extern int try_implicit_rule (struct file *file, unsigned int depth);
 /* Incremented when a command is started (under -n, when one would be).  */
 unsigned int commands_started = 0;
 
+/* Set to the goal dependency.  Mostly needed for remaking makefiles.  */
+static struct goaldep *goal_list;
+static struct dep *goal_dep;
+
 /* Current value for pruning the scan of the goal chain (toggle 0/1).  */
 static unsigned int considered;
 
@@ -77,32 +81,23 @@ static const char *library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr);
    one goal whose 'changed' member is nonzero is successfully made.  */
 
 enum update_status
-update_goal_chain (struct dep *goals)
+update_goal_chain (struct goaldep *goaldeps)
 {
   int t = touch_flag, q = question_flag, n = just_print_flag;
   enum update_status status = us_none;
 
-#define MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
-                     : file_mtime (file))
-
   /* Duplicate the chain so we can remove things from it.  */
 
-  goals = copy_dep_chain (goals);
-
-  {
-    /* Clear the 'changed' flag of each goal in the chain.
-       We will use the flag below to notice when any commands
-       have actually been run for a target.  When no commands
-       have been run, we give an "up to date" diagnostic.  */
+  struct dep *goals = copy_dep_chain ((struct dep *)goaldeps);
 
-    struct dep *g;
-    for (g = goals; g != 0; g = g->next)
-      g->changed = 0;
-  }
+  goal_list = rebuilding_makefiles ? goaldeps : NULL;
 
   /* All files start with the considered bit 0, so the global value is 1.  */
   considered = 1;
 
+#define MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
+                     : file_mtime (file))
+
   /* Update all the goals until they are all finished.  */
 
   while (goals != 0)
@@ -125,6 +120,8 @@ update_goal_chain (struct dep *goals)
           struct file *file;
           int stop = 0, any_not_updated = 0;
 
+          goal_dep = g;
+
           for (file = g->file->double_colon ? g->file->double_colon : g->file;
                file != NULL;
                file = file->prev)
@@ -132,7 +129,7 @@ update_goal_chain (struct dep *goals)
               unsigned int ocommands_started;
               enum update_status fail;
 
-              file->dontcare = g->dontcare;
+              file->dontcare = ANY_SET (g->flags, RM_DONTCARE);
 
               check_renamed (file);
               if (rebuilding_makefiles)
@@ -268,6 +265,28 @@ update_goal_chain (struct dep *goals)
   return status;
 }
 \f
+/* If we're rebuilding an included makefile that failed, and we care
+   about errors, show an error message the first time.  */
+
+void
+show_goal_error ()
+{
+  if ((goal_dep->flags & (RM_INCLUDED|RM_DONTCARE)) != RM_INCLUDED)
+    return;
+
+  for (struct goaldep *goal = goal_list; goal; goal = goal->next)
+    if (goal_dep->file == goal->file)
+      {
+        if (goal->error)
+          {
+            OSS (error, &goal->floc, "%s: %s",
+                 goal->file->name, strerror ((int)goal->error));
+            goal->error = 0;
+          }
+        return;
+      }
+}
+\f
 /* If FILE is not up to date, execute the commands for it.
    Return 0 if successful, non-0 if unsuccessful;
    but with some flag settings, just call 'exit' if unsuccessful.
@@ -380,29 +399,28 @@ complain (struct file *file)
 
   if (d == 0)
     {
+      show_goal_error ();
+
       /* Didn't find any dependencies to complain about. */
       if (file->parent)
         {
           size_t l = strlen (file->name) + strlen (file->parent->name) + 4;
+          const char *m = _("%sNo rule to make target '%s', needed by '%s'%s");
 
           if (!keep_going_flag)
-            fatal (NILF, l,
-                   _("%sNo rule to make target '%s', needed by '%s'%s"),
-                   "", file->name, file->parent->name, "");
+            fatal (NILF, l, m, "", file->name, file->parent->name, "");
 
-          error (NILF, l, _("%sNo rule to make target '%s', needed by '%s'%s"),
-                 "*** ", file->name, file->parent->name, ".");
+          error (NILF, l, m, "*** ", file->name, file->parent->name, ".");
         }
       else
         {
           size_t l = strlen (file->name) + 4;
+          const char *m = _("%sNo rule to make target '%s'%s");
 
           if (!keep_going_flag)
-            fatal (NILF, l,
-                   _("%sNo rule to make target '%s'%s"), "", file->name, "");
+            fatal (NILF, l, m, "", file->name, "");
 
-          error (NILF, l,
-                 _("%sNo rule to make target '%s'%s"), "*** ", file->name, ".");
+          error (NILF, l, m, "*** ", file->name, ".");
         }
 
       file->no_diag = 0;
index ee014bd8536f86a6947ee922c408dc3ab246616b..f78563f9ca5eda5f49a13262bf97853a91f88c6c 100644 (file)
@@ -165,6 +165,70 @@ baz: end
 #MAKE#: *** No rule to make target 'end', needed by 'baz'.  Stop.\n",
 512);
 
+# Test include of make-able file doesn't show an error (Savannah #102)
+run_make_test(q!
+.PHONY: default
+default:; @echo DONE
+
+inc1:; echo > $@
+include inc1
+include inc2
+inc2:; echo > $@
+!,
+              '', "echo > inc2\necho > inc1\nDONE\n");
+
+rmfiles('inc1', 'inc2');
+
+# Test include of non-make-able file does show an error (Savannah #102)
+run_make_test(q!
+.PHONY: default
+default:; @echo DONE
+
+inc1:; echo > $@
+include inc1
+include inc2
+!,
+              '', "#MAKEFILE#:7: inc2: No such file or directory\n#MAKE#: *** No rule to make target 'inc2'.  Stop.\n", 512);
+
+rmfiles('inc1');
+
+# Include same file multiple times
+
+run_make_test(q!
+default:; @echo DEFAULT
+include inc1
+inc1:; echo > $@
+include inc1
+!,
+              '', "echo > inc1\nDEFAULT\n");
+
+rmfiles('inc1');
+
+# Included file has a prerequisite that fails to build
+
+run_make_test(q!
+default:; @echo DEFAULT
+include inc1
+inc1: foo; echo > $@
+foo:; exit 1
+!,
+              '', "exit 1\n#MAKEFILE#:3: inc1: No such file or directory\n#MAKE#: *** [#MAKEFILE#:5: foo] Error 1\n", 512);
+
+rmfiles('inc1');
+
+# Included file has a prerequisite we don't know how to build
+
+run_make_test(q!
+default:; @echo DEFAULT
+include inc1
+inc1: foo; echo > $@
+!,
+              '', "#MAKEFILE#:3: inc1: No such file or directory\n#MAKE#: *** No rule to make target 'foo', needed by 'inc1'.  Stop.\n", 512);
+
+rmfiles('inc1');
+
+# include a directory
+
 if ($all_tests) {
     # Test that include of a rebuild-able file doesn't show a warning
     # Savannah bug #102
index 9c708b7779a95f03c2e690bc0772f19d3818455d..4c4c4cfb6c7db72c2eb1d2e47a9a35cf9c3c5f0b 100644 (file)
@@ -45,7 +45,6 @@ include foo.x
 foo.x: ; @touch $@
 ',
               '-B', 'MAKE_RESTARTS=
-#MAKEFILE#:4: foo.x: No such file or directory
 MAKE_RESTARTS=1');
 
 rmfiles('foo.x');
@@ -63,7 +62,6 @@ foo.x: ; @touch $@
 blah.x: ; @echo $@
 ',
               '-B', 'MAKE_RESTARTS=
-#MAKEFILE#:4: foo.x: No such file or directory
 MAKE_RESTARTS=1
 blah.x
 all');
@@ -83,3 +81,7 @@ x.a: x.b ; @echo $?
 unlink(qw(x.a x.b));
 
 1;
+
+### Local Variables:
+### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
+### End:
index 20b9f7451a6f9dbce5fdb8fa824a480803ca25b3..857b1cce09af866ca3c483bb1727a795618ff8dc 100644 (file)
@@ -42,8 +42,7 @@ foo.x: bar.x
 bar.x: ; echo >> $@
 baz.x: bar.x ; @echo "touch $@"
 ',
-              '', '#MAKEFILE#:3: foo.x: No such file or directory
-echo >> bar.x
+              '', 'echo >> bar.x
 touch foo.x
 restarts=1
 touch baz.x');
@@ -86,3 +85,7 @@ unlink(qw(y x-dir/x));
 rmdir('x-dir');
 
 1;
+
+### Local Variables:
+### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
+### End:
index a05bbee785e1a23c52944e276673ae271b572d73..db762b2c76a8ae25b23411bf3273655ddf03a881 100644 (file)
@@ -18,7 +18,7 @@ include foo
 all: ;@:
 foo: ; touch foo
 !,
-        "", "#MAKEFILE#:2: foo: No such file or directory\ntouch foo\n");
+        "", "touch foo\n");
 unlink('foo');
 
 # Test makefile rebuild with -w
@@ -27,7 +27,7 @@ include foo
 all: ;@:
 foo: ; touch foo
 !,
-        "-w", "#MAKE#: Entering directory '#PWD#'\n#MAKEFILE#:2: foo: No such file or directory\ntouch foo\n#MAKE#: Leaving directory '#PWD#'\n");
+        "-w", "#MAKE#: Entering directory '#PWD#'\ntouch foo\n#MAKE#: Leaving directory '#PWD#'\n");
 unlink('foo');
 
 1;
index ef8e368f9d62cf536bc86734fc77aadae52859a6..01bf55ec34682ef8344bc2e83b00bb3e1af845b4 100644 (file)
@@ -11,7 +11,6 @@ include foo.x
 foo.x: ; @touch $@
 ',
               '', 'MAKE_RESTARTS=
-#MAKEFILE#:4: foo.x: No such file or directory
 MAKE_RESTARTS=1');
 
 rmfiles('foo.x');
@@ -26,9 +25,7 @@ foo.x: ; @echo "include bar.x" > $@
 bar.x: ; @touch $@
 ',
               '', 'MAKE_RESTARTS=
-#MAKEFILE#:4: foo.x: No such file or directory
 MAKE_RESTARTS=1
-foo.x:1: bar.x: No such file or directory
 MAKE_RESTARTS=2');
 
 rmfiles('foo.x', 'bar.x');
@@ -47,9 +44,7 @@ foo.x: ; @echo "include bar.x" > $@
 bar.x: ; @touch $@
 ',
               '', "MAKE_RESTARTS=
-#MAKEFILE#:8: foo.x: No such file or directory
 MAKE_RESTARTS=1
-foo.x:1: bar.x: No such file or directory
 MAKE_RESTARTS=2
 recurse MAKE_RESTARTS=
 #MAKE#[1]: Entering directory '#PWD#'
@@ -60,3 +55,7 @@ all MAKE_RESTARTS=
 rmfiles('foo.x', 'bar.x');
 
 1;
+
+### Local Variables:
+### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
+### End: