Bug 787658 - Recalculate mtime once the target is built. r=khuey, a=akeybl
authorSiddharth Agarwal <sid.bugzilla@gmail.com>
Tue, 04 Sep 2012 21:30:32 -0400
changeset 109629 e630a6baafe1ffcbf01068729611dce7c13cc196
parent 109628 a7b4aedef3faed0987dfacc98b83d5fb92a5cbaf
child 109630 f7d473f3a0679251509d8382026b711b777b9a29
push id1585
push userryanvm@gmail.com
push dateTue, 23 Oct 2012 03:49:51 +0000
treeherdermozilla-beta@121213ddf98b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey, akeybl
bugs787658
milestone17.0
Bug 787658 - Recalculate mtime once the target is built. r=khuey, a=akeybl
build/pymake/pymake/data.py
build/pymake/tests/remake-mtime.mk
--- a/build/pymake/pymake/data.py
+++ b/build/pymake/pymake/data.py
@@ -1179,41 +1179,55 @@ class Target(object):
                     self.mtime = None
                     return
 
         search = [self.target]
         if not os.path.isabs(self.target):
             search += [util.normaljoin(dir, self.target).replace('\\', '/')
                        for dir in makefile.getvpath(self.target)]
 
-        for t in search:
+        targetandtime = self.searchinlocs(makefile, search)
+        if targetandtime is not None:
+            (self.vpathtarget, self.mtime) = targetandtime
+            return
+
+        self.vpathtarget = self.target
+        self.mtime = None
+
+    def searchinlocs(self, makefile, locs):
+        """
+        Look in the given locations relative to the makefile working directory
+        for a file. Return a pair of the target and the mtime if found, None
+        if not.
+        """
+        for t in locs:
             fspath = util.normaljoin(makefile.workdir, t).replace('\\', '/')
             mtime = getmtime(fspath)
 #            _log.info("Searching %s ... checking %s ... mtime %r" % (t, fspath, mtime))
             if mtime is not None:
-                self.vpathtarget = t
-                self.mtime = mtime
-                return
+                return (t, mtime)
 
-        self.vpathtarget = self.target
-        self.mtime = None
+        return None
         
     def beingremade(self):
         """
-        When we remake ourself, we need to reset our mtime and vpathtarget.
-
-        We store our old mtime so that $? can calculate out-of-date prerequisites.
+        When we remake ourself, we have to drop any vpath prefixes.
         """
-        self.realmtime = self.mtime
-        self.mtime = None
         self.vpathtarget = self.target
         self.wasremade = True
 
     def notifydone(self, makefile):
         assert self._state == MAKESTATE_WORKING, "State was %s" % self._state
+        # If we were remade then resolve mtime again
+        if self.wasremade:
+            targetandtime = self.searchinlocs(makefile, [self.target])
+            if targetandtime is not None:
+                (_, self.mtime) = targetandtime
+            else:
+                self.mtime = None
 
         self._state = MAKESTATE_FINISHED
         for cb in self._callbacks:
             makefile.context.defer(cb, error=self.error, didanything=self.didanything)
         del self._callbacks 
 
     def make(self, makefile, targetstack, cb, avoidremakeloop=False, printerror=True):
         """
@@ -1310,17 +1324,17 @@ def setautomatic(v, name, plist):
     v.set(name, Variables.FLAVOR_SIMPLE, Variables.SOURCE_AUTOMATIC, ' '.join(plist))
     v.set(name + 'D', Variables.FLAVOR_SIMPLE, Variables.SOURCE_AUTOMATIC, ' '.join((dirpart(p) for p in plist)))
     v.set(name + 'F', Variables.FLAVOR_SIMPLE, Variables.SOURCE_AUTOMATIC, ' '.join((filepart(p) for p in plist)))
 
 def setautomaticvariables(v, makefile, target, prerequisites):
     prtargets = [makefile.gettarget(p) for p in prerequisites]
     prall = [pt.vpathtarget for pt in prtargets]
     proutofdate = [pt.vpathtarget for pt in withoutdups(prtargets)
-                   if target.realmtime is None or mtimeislater(pt.mtime, target.realmtime)]
+                   if target.mtime is None or mtimeislater(pt.mtime, target.mtime)]
     
     setautomatic(v, '@', [target.vpathtarget])
     if len(prall):
         setautomatic(v, '<', [prall[0]])
 
     setautomatic(v, '?', proutofdate)
     setautomatic(v, '^', list(withoutdups(prall)))
     setautomatic(v, '+', prall)
new file mode 100644
--- /dev/null
+++ b/build/pymake/tests/remake-mtime.mk
@@ -0,0 +1,14 @@
+# mtime(dep1) < mtime(target) so the target should not be made
+$(shell touch dep1; sleep 1; touch target)
+
+all: target
+	echo TEST-PASS
+
+target: dep1
+	echo TEST-FAIL target should not have been made
+
+dep1: dep2
+	@echo "Remaking dep1 (actually not)"
+
+dep2:
+	@echo "Making dep2 (actually not)"