Attached is an enhancement I made to make-3.97.1 which adds a new
feature: when a preqrequisite's file name begins with a hyphen, it is
marked dontcare (and the hyphen stripped).  Then during rebuilding, if
that file doesn't exist and can't be remade, 'make' silently proceeds.

This is useful for dependencies in automatically-generated dependency
lists: if a header file gets renamed or deleted, 'make' should not be
bothered by the nonexistence of the file, as long as the dependency info
is regenerated "soon".

More detail is available on a page I put together describing my solution
to the autodependency problem (which I think is superior to the approach
given in the manual):

  http://www.cs.berkeley.edu/~smcpeak/autodepend/autodepend.html

Thanks,

-Scott

Patch so that when prerequisite file names begin with a hyphen,
their absence is not an error.

diff -u make-3.79.1-orig/configure make-3.79.1/configure
--- make-3.79.1-orig/configure  Fri Jun 23 09:09:54 2000
+++ make-3.79.1/configure       Tue Nov 20 18:42:18 2001
@@ -802,7 +802,7 @@

 PACKAGE=make

-VERSION=3.79.1
+VERSION=3.79.1-sm

 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
   { echo "configure: error: source directory already configured; run "make distclean" 
there first" 1>&2; exit 1; }
diff -u make-3.79.1-orig/configure.in make-3.79.1/configure.in
--- make-3.79.1-orig/configure.in       Fri Jun 23 09:09:41 2000
+++ make-3.79.1/configure.in    Tue Nov 20 18:42:08 2001
@@ -3,7 +3,7 @@
 AC_PREREQ(2.13)dnl             dnl Minimum Autoconf version required.
 AC_INIT(vpath.c)dnl            dnl A distinctive file to look for in srcdir.

-AM_INIT_AUTOMAKE(make, 3.79.1)
+AM_INIT_AUTOMAKE(make, 3.79.1-sm)
 AM_CONFIG_HEADER(config.h)

 dnl Regular configure stuff
diff -u make-3.79.1-orig/file.c make-3.79.1/file.c
--- make-3.79.1-orig/file.c     Tue Jun 20 07:00:16 2000
+++ make-3.79.1/file.c  Tue Nov 20 17:55:14 2001
@@ -26,6 +26,7 @@
 #include "job.h"
 #include "commands.h"
 #include "variable.h"
+#include "debug.h"       /* DB, DB_VERBOSE */
 
 
 /* Hash table of files the makefile knows how to make.  */
@@ -56,6 +57,11 @@
 
   assert (*name != '\0');
 
+  if (*name == '-') {
+    /* sm: skip dontcare flag; it gets interpreted in enter_file */
+    name++;
+  }
+
   /* This is also done in parse_file_seq, so this is redundant
      for names read from makefiles.  It is here for names passed
      on the command line.  */
@@ -122,9 +128,35 @@
 #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
   char *lname, *ln;
 #endif
+  int dontcare_flag = 0;
 
   assert (*name != '\0');
 
+  if (*name == '-')
+    {
+      /* sm: skip and interpret new flag:
+
+         When the name of a prerequisite file begins with a leading hyphen 
+         ("-"), but that file doesn't exist and can't be remade, we consider
+         the file to be out of date (so the target gets rebuilt), but ignore
+         the error.
+
+         This is useful for autodependency rules, when one of the files that
+         was used to compile some .o file has been renamed or deleted.  The
+         .o file should be recompiled of course, but 'make' shouldn't
+         complain.  When the .o file is recompiled, the autodependency info
+         will be correctly updated, and the problem won't persist.
+
+         This is in contrast to user-written dependencies, where the user
+         should take responsibility for maintaining accuracy.
+         
+         (sm = Scott McPeak, 11/20/01)
+      */
+      name++;
+      dontcare_flag = 1;  /* originally for Makefiles, has (almost) right effect */
+      DB (DB_VERBOSE, (_("Setting dontcare for `%s'.\n"), name));
+    }
+
 #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
   lname = (char *)malloc (strlen (name) + 1);
   for (n = name, ln = lname; *n != '\0'; ++n, ++ln)
@@ -161,6 +193,7 @@
   bzero ((char *) new, sizeof (struct file));
   new->name = new->hname = name;
   new->update_status = -1;
+  new->dontcare = dontcare_flag;

   if (f == 0)
     {
diff -u make-3.79.1-orig/main.c make-3.79.1/main.c
--- make-3.79.1-orig/main.c     Tue Jun 13 07:24:45 2000
+++ make-3.79.1/main.c  Tue Nov 20 17:49:24 2001
@@ -1072,6 +1072,10 @@
   if (print_version_flag)
     die (0);

+  /* sm: I want programmatic access to version info inside the Makefile */
+  /* (maintainer: feel free to change what this variable is called) */
+  define_variable("GNUMAKE_VERSION", 15, VERSION, o_default, 0);
+
 #ifndef VMS
   /* Set the "MAKE_COMMAND" variable to the name we were invoked with.
      (If it is a relative pathname with a slash, prepend our directory name
@@ -1718,6 +1722,12 @@
                         mtime = file_mtime_no_search (d->file);
                         any_remade |= (mtime != NONEXISTENT_MTIME
                                        && mtime != makefile_mtimes[i]);
+                      }
+                    else
+                      {
+                        DB (DB_BASIC,     /* sm: helpful when hacking dontcare */
+                            (_("Igoring failed Makefile `%s' b/c of dontcare.\n"),
+                             d->file->name));
                       }
                   }
                 else
diff -u make-3.79.1-orig/remake.c make-3.79.1/remake.c
--- make-3.79.1-orig/remake.c   Tue Jun 20 07:00:17 2000
+++ make-3.79.1/remake.c        Tue Nov 20 17:53:48 2001
@@ -681,7 +681,19 @@
     }
 
   file->updated = 1;
-  return file->update_status;
+
+  if (file->update_status==2 && file->dontcare) 
+    {
+      /* sm: I don't change file->update_status, because I want to
+         minimize the effect of my changes, and I don't think it's
+         necessary, based on my reading of update_file */
+      DBF (DB_BASIC, _("Suppressing error with `%s' because of dontcare.\n"));
+      return 0;      /* interpreted as success by caller */
+    }
+  else
+    {
+      return file->update_status;
+    }
 }
 
 /* Set FILE's `updated' flag and re-check its mtime and the mtime's of all

Reply via email to