--- /dev/null
+/** @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
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
//\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
@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
+ 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
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
\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
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
// 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
// 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
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
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
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
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