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