tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: make: ignore stale .depend



So, it turns out

1/ that the problem I mentioned occurs even when using vanila NetBSD 
   make depend:

$ head obj/.depend
foo.o foo.ln: /homes/sjg/make-tests/stale/stale0/foo.c \
  /homes/sjg/make-tests/stale/stale0/foo.h
goo.o goo.ln: /homes/sjg/make-tests/stale/stale0/goo.c \
  /homes/sjg/make-tests/stale/stale0/h/goo.h
main.o main.ln: /homes/sjg/make-tests/stale/src/main.c /usr/include/stdlib.h \
  /usr/include/sys/cdefs.h /usr/include/machine/cdefs.h \
  /usr/include/sys/cdefs_elf.h /usr/include/sys/featuretest.h \
  /usr/include/sys/types.h /usr/include/machine/types.h \
  /usr/include/machine/int_types.h /usr/include/machine/ansi.h \
  /usr/include/sys/ansi.h /usr/include/machine/endian.h \
$ make
make: ignoring stale .depend for /homes/sjg/make-tests/stale/stale0/foo.c
make: ignoring stale .depend for /homes/sjg/make-tests/stale/stale0/foo.h
#   compile  src/foo.o
cc -O2 -g -I/homes/sjg/make-tests/stale/stale2/h   -Werror      -c    
/homes/sjg/make-tests/stale/stale0/foo.c
cc: /homes/sjg/make-tests/stale/stale0/foo.c: No such file or directory
cc: no input files
*** Error code 1

2/ that the fix I posed earlier, hoses meta mode (where we expect the
   depend file may contain "paths" which do not exist).

So I've reverted to my original fix, which fixes the above without
breaking meta mode:

$ /var/obj/NetBSD/current/usr.bin/make/make 
make: ignoring stale .depend for /homes/sjg/make-tests/stale/stale0/foo.c, 
found /homes/sjg/make-tests/stale/stale2/foo.c
make: ignoring stale .depend for /homes/sjg/make-tests/stale/stale0/foo.h, 
found /homes/sjg/make-tests/stale/stale2/foo.h
make: ignoring stale .depend for /homes/sjg/make-tests/stale/stale0/goo.c, 
found /homes/sjg/make-tests/stale/stale2/goo.c
make: ignoring stale .depend for /homes/sjg/make-tests/stale/stale0/h/goo.h
#   compile  src/goo.o
cc -O2 -g -I/homes/sjg/make-tests/stale/stale2/h   -Werror      -c    
/homes/sjg/make-tests/stale/stale2/goo.c
#      link  src/stale
cc           -o stale  main.o foo.o goo.o          -Wl,-rpath-link,/lib  -L/lib 
-Wl,-rpath-link,/usr/lib  -L/usr/lib
$

Current patch and log comment:

When a source file moves, make will ignore the stale dependency,
but if the file in question is one that needs to be compiled (.c or .cc), 
it still hands the bogus name to the compiler.

If Dir_MTime() cannot find such a file, see if the basename can be
found via .PATH, and if so, tweak gn->name to be that basename.  
This prevents the stale path being given to the compiler.

In meta_oodate(), if a referenced file no longer exists, consider the
target out-of-date.

Also, if meta_oodate() decides a target is out-of-date, and it
it uses .OODATE in its commands, we need .OODATE recomputed.
Undo our call to Make_DoAllVar() so that the call from Make_OODate()
will do the right thing.


Index: dir.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/dir.c,v
retrieving revision 1.61
diff -u -p -r1.61 dir.c
--- dir.c       24 Jan 2009 10:59:09 -0000      1.61
+++ dir.c       26 Nov 2010 05:12:44 -0000
@@ -1434,6 +1434,31 @@ Dir_MTime(GNode *gn)
            fullName = NULL;
        else {
            fullName = Dir_FindFile(gn->name, Suff_FindPath(gn));
+           if (fullName == NULL && gn->flags & FROM_DEPEND) {
+               char *cp;
+
+               cp = strrchr(gn->name, '/');
+               if (cp) {
+                   /*
+                    * It is possible the file has moved,
+                    * see if we can find it via the current .PATH
+                    */
+                   cp++;
+                       
+                   fullName = Dir_FindFile(cp, Suff_FindPath(gn));
+                   if (fullName) {
+                       char *old;
+                       
+                       fprintf(stdout, "%s: ignoring stale %s for %s, found 
%s\n",
+                               progname, makeDependfile, gn->name, fullName);
+                       
+                       old = gn->name;
+                       gn->name = bmake_strdup(cp);
+                       free(old);
+                       gn->path = bmake_strdup(fullName);
+                   }
+               }
+           }
            if (DEBUG(DIR))
                fprintf(debug_file, "Found '%s' as '%s'\n",
                        gn->name, fullName ? fullName : "(not found)" );
Index: meta.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/meta.c,v
retrieving revision 1.3
diff -u -p -r1.3 meta.c
--- meta.c      13 Sep 2010 21:31:59 -0000      1.3
+++ meta.c      26 Nov 2010 05:12:44 -0000
@@ -707,6 +707,9 @@ meta_oodate(GNode *gn, Boolean oodate)
     FILE *fp;
     Boolean ignoreOODATE = FALSE;
 
+    if (oodate)
+       return oodate;          /* we're done */
+
     /*
      * We need to check if the target is out-of-date. This includes
      * checking if the expanded command has changed. This in turn
@@ -715,9 +718,6 @@ meta_oodate(GNode *gn, Boolean oodate)
      */
     Make_DoAllVar(gn);
 
-    if (oodate)
-       return oodate;          /* we're done */
-
     if (getcwd(latestdir, sizeof(latestdir)) == NULL)
        err(1, "Could not get current working directory");
 
@@ -809,11 +809,16 @@ meta_oodate(GNode *gn, Boolean oodate)
                        p = fname1;
                    }
 
-                   if (stat(p, &fs) == 0 &&
-                       !S_ISDIR(fs.st_mode) &&
-                       fs.st_mtime > gn->mtime) {
+                   if (stat(p, &fs) == 0) {
+                       if (!S_ISDIR(fs.st_mode) &&
+                           fs.st_mtime > gn->mtime) {
+                           if (DEBUG(META))
+                               fprintf(debug_file, "%s: %d: file '%s' is newer 
than the target...\n", fname, lineno, p);
+                           oodate = TRUE;
+                       }
+                   } else if (errno == ENOENT) {
                        if (DEBUG(META))
-                           fprintf(debug_file, "%s: %d: file '%s' is newer 
than the target...\n", fname, lineno, p);
+                           fprintf(debug_file, "%s: %d: file '%s' may have 
moved?...\n", fname, lineno, p);
                        oodate = TRUE;
                    }
                    break;
@@ -904,6 +909,15 @@ meta_oodate(GNode *gn, Boolean oodate)
 
        fclose(fp);
     }
+    if (oodate && ignoreOODATE) {
+       /*
+        * Target uses .OODATE, so we need to re-compute it.
+        * We need to clean up what Make_DoAllVar() did.
+        */
+       Var_Delete(ALLSRC, gn);
+       Var_Delete(OODATE, gn);
+       gn->flags &= ~DONE_ALLSRC;
+    }
     return oodate;
 }
 


Home | Main Index | Thread Index | Old Index