1) Add FileTimeStamp class to centralize the cache mechanism for file time stamp...
authorjwang36 <jwang36@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 21 Sep 2006 05:11:58 +0000 (05:11 +0000)
committerjwang36 <jwang36@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 21 Sep 2006 05:11:58 +0000 (05:11 +0000)
2) Fixed the FlashMapTask dependency issue
3) Fixed empty target issue in OnDenpendency class

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1584 6f19259b-4bc3-4df7-8a09-765794883524

Tools/Source/Common/org/tianocore/common/cache/FileTimeStamp.java [new file with mode: 0644]
Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/FlashMapTask.java
Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/MakeDeps.java
Tools/Source/GenBuild/org/tianocore/build/global/OnDependency.java

diff --git a/Tools/Source/Common/org/tianocore/common/cache/FileTimeStamp.java b/Tools/Source/Common/org/tianocore/common/cache/FileTimeStamp.java
new file mode 100644 (file)
index 0000000..968d31f
--- /dev/null
@@ -0,0 +1,83 @@
+/** @file\r
+This file is to define the FileTimeStamp class for speeding up the dependency check.\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+package org.tianocore.common.cache;\r
+\r
+import java.io.File;\r
+import java.util.Map;\r
+import java.util.TreeMap;\r
+import java.util.HashMap;\r
+\r
+/**\r
+   FileTimeStamp class is used to cache the time stamp of accessing file, which\r
+   will speed up the dependency check for build\r
+ **/\r
+public class FileTimeStamp {\r
+    //\r
+    // cache the modified timestamp of files accessed, to speed up the depencey check\r
+    // \r
+    private static Map<String, Long> timeStampCache = new HashMap<String, Long>();\r
+\r
+    /**\r
+       Get the time stamp of given file. It will try the cache first and then\r
+       get from file system if no time stamp of the file is cached.\r
+\r
+       @param file      File name\r
+       \r
+       @return long     The time stamp of the file\r
+     **/\r
+    synchronized public static long get(String file) {\r
+        long timeStamp = 0;\r
+\r
+        Long value = timeStampCache.get(file);\r
+        if (value != null) {\r
+            timeStamp = value.longValue();\r
+        } else {\r
+            timeStamp = new File(file).lastModified();\r
+            timeStampCache.put(file, new Long(timeStamp));\r
+        }\r
+\r
+        return timeStamp;\r
+    }\r
+\r
+    /**\r
+       Force update the time stamp for the given file\r
+\r
+       @param file          File name\r
+       @param timeStamp     The time stamp of the file\r
+     **/\r
+    synchronized public static void update(String file, long timeStamp) {\r
+        timeStampCache.put(file, new Long(timeStamp));\r
+    }\r
+\r
+    /**\r
+       Force update the time stamp for the given file\r
+\r
+       @param file          File name\r
+     **/\r
+    synchronized public static void update(String file) {\r
+        long timeStamp = new File(file).lastModified();\r
+        timeStampCache.put(file, new Long(timeStamp));\r
+    }\r
+\r
+    /**\r
+       Check if the time stamp of given file has been cached for not\r
+\r
+       @param file      The file name\r
+       \r
+       @return boolean\r
+     **/\r
+    synchronized public static boolean containsKey(String file) {\r
+        return timeStampCache.containsKey(file);\r
+    }\r
+}\r
index 5c3e889..c6f5099 100644 (file)
 package org.tianocore.framework.tasks;\r
 \r
 import java.io.File;\r
+import java.io.FileReader;\r
+import java.io.BufferedReader;\r
+\r
+import java.util.List;\r
+import java.util.ArrayList;\r
+import java.util.regex.Pattern;\r
+import java.util.regex.Matcher;\r
+\r
 import org.apache.tools.ant.Task;\r
 import org.apache.tools.ant.Project;\r
 import org.apache.tools.ant.BuildException;\r
@@ -35,8 +43,14 @@ public class FlashMapTask extends Task implements EfiDefine {
     //\r
     // tool name\r
     //\r
-    private final String toolName = "FlashMap";\r
+    private static final String toolName = "FlashMap";\r
 \r
+    //\r
+    // \r
+    // \r
+    private static Pattern fileBlock = Pattern.compile("\\s*File\\s*\\{([^\\{\\}]+)\\}");\r
+    private static Pattern fileNameDef = Pattern.compile("\\bName\\s*=\\s*\"([^\"]+)\"");\r
+    \r
     //\r
     // Flash definition file\r
     //\r
@@ -135,7 +149,6 @@ public class FlashMapTask extends Task implements EfiDefine {
       @throws BuidException\r
      **/\r
     public void execute() throws BuildException {\r
-        /*\r
         if (isUptodate()) {\r
             EdkLog.log(this, EdkLog.EDK_VERBOSE, headerFile.toFileList()\r
                                                  + imageOutFile.toFileList()\r
@@ -143,10 +156,9 @@ public class FlashMapTask extends Task implements EfiDefine {
                                                  + dscFile.toFileList()\r
                                                  + asmIncFile.toFileList()\r
                                                  + outStrFile\r
-                                                 + " is/are up-to-date!");\r
+                                                 + " is up-to-date!");\r
             return;\r
         }\r
-        */\r
 \r
         Project project = this.getOwningTarget().getProject();\r
         //\r
@@ -689,6 +701,13 @@ public class FlashMapTask extends Task implements EfiDefine {
                 EdkLog.log(this, EdkLog.EDK_VERBOSE, srcName + " has been changed since last build!");\r
                 return false;\r
             }\r
+\r
+            //\r
+            // we need to check the time stamp of each FV file specified in fdf file\r
+            // \r
+            if (!isFdUptodate(dstName, getFvFiles(flashDefFile.getValue()))) {\r
+                return false;\r
+            }\r
         }\r
 \r
         if (!mcoFile.isEmpty()) {\r
@@ -749,4 +768,82 @@ public class FlashMapTask extends Task implements EfiDefine {
 \r
         return true;\r
     }\r
+\r
+    //\r
+    // Parse the flash definition file and find out the FV file names\r
+    // \r
+    private List<String> getFvFiles(String fdfFileName) {\r
+        File fdfFile = new File(fdfFileName);\r
+        int fileLength = (int)fdfFile.length();\r
+        char[] fdfContent = new char[fileLength];\r
+        List<String> fileList = new ArrayList<String>();\r
+\r
+        try {\r
+            FileReader reader = new FileReader(fdfFile);\r
+            BufferedReader in = new BufferedReader(reader);\r
+\r
+            in.read(fdfContent, 0, fileLength);\r
+            String str = new String(fdfContent);\r
+\r
+            //\r
+            // match the \r
+            //      File {\r
+            //        ...\r
+            //      }\r
+            // block\r
+            // \r
+            Matcher matcher = fileBlock.matcher(str);\r
+            while (matcher.find()) {\r
+                String fileBlockContent = str.substring(matcher.start(1), matcher.end(1));\r
+                //\r
+                // match the definition like\r
+                //      Name = "..."\r
+                //  \r
+                Matcher nameMatcher = fileNameDef.matcher(fileBlockContent);\r
+                if (nameMatcher.find()) {\r
+                    fileList.add(fileBlockContent.substring(nameMatcher.start(1), nameMatcher.end(1)));\r
+                }\r
+            }\r
+\r
+            in.close();\r
+            reader.close();\r
+        } catch (Exception ex) {\r
+            throw new BuildException(ex.getMessage());\r
+        }\r
+\r
+        return fileList;\r
+    }\r
+\r
+    private boolean isFdUptodate(String fdFile, List<String> fvFileList) {\r
+        String fvDir = ".";\r
+        File fd = new File(fdFile);\r
+\r
+        if (outputDir.equals(".")) {\r
+            if (!fd.isAbsolute()) {\r
+                //\r
+                // If we cannot get the absolute path of fd file, we caanot\r
+                // get its time stamp. Re-generate it always in such situation.\r
+                // \r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, "Cannot retrieve the time stamp of " + fdFile);\r
+                return false;\r
+            }\r
+            fvDir = fd.getParent();\r
+        } else {\r
+            fvDir = outputDir;\r
+            if (!fd.isAbsolute()) {\r
+                fd = new File(fvDir + File.separator + fdFile);\r
+            }\r
+        }\r
+\r
+        long fdTimeStamp = fd.lastModified();\r
+        for (int i = 0; i < fvFileList.size(); ++i) {\r
+            File fv = new File(fvDir + File.separator + fvFileList.get(i));\r
+            if (fv.lastModified() > fdTimeStamp) {\r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, fv.getPath() + " has been changed since last build!");\r
+                return false;\r
+            }\r
+        }\r
+\r
+        return true;\r
+    }\r
 }\r
index bd305fa..1486bd3 100644 (file)
@@ -31,6 +31,7 @@ import org.apache.tools.ant.types.Commandline;
 import org.apache.tools.ant.types.Path;\r
 \r
 import org.tianocore.common.logger.EdkLog;\r
+import org.tianocore.common.cache.FileTimeStamp;\r
 \r
 /**\r
  Class MakeDeps is used to wrap MakeDeps.exe as an ANT task.\r
@@ -233,12 +234,12 @@ public class MakeDeps extends Task {
         // If the source file(s) is newer than dependency list file, we need to\r
         // re-generate the dependency list file\r
         //\r
-        long depsFileTimeStamp = df.lastModified();\r
+        long depsFileTimeStamp = FileTimeStamp.get(dfName);\r
         List<String> fileList = inputFileList.getNameList();\r
         for (int i = 0, length = fileList.size(); i < length; ++i) {\r
-            File sf = new File(fileList.get(i));\r
-            if (sf.lastModified() > depsFileTimeStamp) {\r
-                EdkLog.log(this, EdkLog.EDK_VERBOSE, sf.getPath() + " has been changed since last build!");\r
+            String sf = fileList.get(i);\r
+            if (FileTimeStamp.get(sf) > depsFileTimeStamp) {\r
+                EdkLog.log(this, EdkLog.EDK_VERBOSE, sf + " has been changed since last build!");\r
                 return false;\r
             }\r
         }\r
@@ -279,7 +280,7 @@ public class MakeDeps extends Task {
                 // If a file cannot be found (moved or removed) or newer, regenerate the dep file\r
                 // \r
                 File sourceFile = new File(line);\r
-                if ((!sourceFile.exists()) || (sourceFile.lastModified() > depsFileTimeStamp)) {\r
+                if ((!sourceFile.exists()) || (FileTimeStamp.get(line) > depsFileTimeStamp)) {\r
                     EdkLog.log(this, EdkLog.EDK_VERBOSE, sourceFile.getPath() + " has been (re)moved or changed since last build!");\r
                     ret = false;\r
                     break;\r
index 173528a..fbffb3b 100644 (file)
@@ -22,6 +22,7 @@ import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Task;\r
 import org.apache.tools.ant.taskdefs.Sequential;\r
 import org.tianocore.common.logger.EdkLog;\r
+import org.tianocore.common.cache.FileTimeStamp;\r
 \r
 /**\r
  Class OnDepdendency is used to check the timestamp between source files and\r
@@ -29,26 +30,24 @@ import org.tianocore.common.logger.EdkLog;
  be re-generated from source files.\r
  **/\r
 public class OnDependency extends Task {\r
-    ///\r
-    /// cache the modified timestamp of files accessed, to speed up the depencey check\r
-    /// \r
-    private Map<String, Long> timeStampCache = new HashMap<String, Long>();\r
-    ///\r
-    /// source files list\r
-    ///\r
+    //\r
+    // source files list\r
+    //\r
     private DpFileList sources = null;\r
-    ///\r
-    /// target files list\r
-    ///\r
+\r
+    //\r
+    // target files list\r
+    //\r
     private DpFileList targets = null;\r
-    ///\r
-    /// tasks to be performed to generate target files\r
-    ///\r
+\r
+    //\r
+    // tasks to be performed to generate target files\r
+    //\r
     private Sequential  task = null;\r
 \r
-    ///\r
-    /// An empty constructor for an ANT task can avoid some potential issues\r
-    ///\r
+    /**\r
+     An empty constructor for an ANT task can avoid some potential issues\r
+     **/\r
     public OnDependency(){\r
     }\r
 \r
@@ -59,11 +58,18 @@ public class OnDependency extends Task {
         if (isOutOfDate() && task != null) {\r
             task.perform();\r
         }\r
+\r
+        //\r
+        // Update the time stamp of target files since they are just re-generated\r
+        // \r
+        for (Iterator dstIt = targets.nameList.iterator(); dstIt.hasNext();) {\r
+            FileTimeStamp.update((String)dstIt.next());\r
+        }\r
     }\r
 \r
-    ///\r
-    /// check if the target files are outofdate\r
-    ///\r
+    //\r
+    // check if the target files are outofdate\r
+    //\r
     private boolean isOutOfDate() {\r
         ///\r
         /// if no source files specified, take it as a fresh start\r
@@ -87,21 +93,17 @@ public class OnDependency extends Task {
                 return true;\r
             }\r
 \r
-            long dstTimeStamp = dstFile.lastModified();\r
+            long dstTimeStamp = FileTimeStamp.get(dstFileName);\r
             Iterator srcIt = sources.nameList.iterator();\r
             while (srcIt.hasNext()) {\r
                 String srcFileName = (String)srcIt.next();\r
-                long srcTimeStamp;\r
-\r
-                if (timeStampCache.containsKey(srcFileName)) {\r
-                    srcTimeStamp = ((Long)timeStampCache.get(srcFileName)).longValue();\r
-                } else {\r
-                    File srcFile = new File(srcFileName);\r
-                    if (!srcFile.exists()) {\r
-                        throw new BuildException("Source File name: " + srcFileName + " doesn't exist!!!");\r
-                    }\r
-                    srcTimeStamp = srcFile.lastModified();\r
-                    timeStampCache.put(srcFileName, new Long(srcTimeStamp));\r
+                long srcTimeStamp = FileTimeStamp.get(srcFileName);\r
+\r
+                if (srcTimeStamp == 0) {\r
+                    //\r
+                    // time stamp 0 means that the file doesn't exist\r
+                    // \r
+                    throw new BuildException("Source File name: " + srcFileName + " doesn't exist!!!");\r
                 }\r
 \r
                 if (dstTimeStamp < srcTimeStamp) {\r