summaryrefslogtreecommitdiffstats
path: root/Tools
diff options
context:
space:
mode:
authorjwang36 <jwang36@6f19259b-4bc3-4df7-8a09-765794883524>2006-10-08 06:28:06 +0000
committerjwang36 <jwang36@6f19259b-4bc3-4df7-8a09-765794883524>2006-10-08 06:28:06 +0000
commit5a4c434254011a0d193f884c5b608a3331df4aee (patch)
tree7e786b0e3543c60a4fd1fa8305642798994bd22e /Tools
parent5d28bc25af191eac074e777a6303b9a9533f6f1d (diff)
downloadedk2-5a4c434254011a0d193f884c5b608a3331df4aee.tar.gz
edk2-5a4c434254011a0d193f884c5b608a3331df4aee.tar.bz2
edk2-5a4c434254011a0d193f884c5b608a3331df4aee.zip
Removed the need of external MakeDeps.exe. Now parsing include files is built in makedeps task.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1683 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'Tools')
-rw-r--r--Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/MakeDeps.java301
-rw-r--r--Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/NestElement.java18
2 files changed, 197 insertions, 122 deletions
diff --git a/Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/MakeDeps.java b/Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/MakeDeps.java
index 8f5664f01d..27e0ed7be5 100644
--- a/Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/MakeDeps.java
+++ b/Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/MakeDeps.java
@@ -14,11 +14,22 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.framework.tasks;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
+import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Set;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -26,9 +37,8 @@ import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.taskdefs.LogStreamHandler;
import org.apache.tools.ant.types.Commandline;
-
-import org.tianocore.common.logger.EdkLog;
import org.tianocore.common.cache.FileTimeStamp;
+import org.tianocore.common.logger.EdkLog;
/**
Class MakeDeps is used to wrap MakeDeps.exe as an ANT task.
@@ -38,14 +48,17 @@ public class MakeDeps extends Task {
//
// private members, use set/get to access them
//
- private static final String toolName = "MakeDeps";
- private FileArg depsFile = new FileArg();
- private ToolArg subDir = new ToolArg();
- private ToolArg quietMode = new ToolArg(" -", "q");
- private ToolArg ignoreError = new ToolArg(" -", "ignorenotfound");
- private IncludePath includePathList = new IncludePath();
- private Input inputFileList = new Input();
- private ToolArg target = new FileArg(" -target ", "dummy");
+ private String depsFilePath = "";
+ private IncludePath includePathList = new IncludePath();
+ private Input inputFileList = new Input();
+ //
+ // cache the including files to speed up dependency check
+ //
+ private static HashMap<String, Set<String>> includesCache = new HashMap<String, Set<String>>();
+ //
+ // regular expression for "#include ..." directive
+ //
+ private static final Pattern incPattern = Pattern.compile("[\n\r \t]*#[ \t]*include[ \t\"<]+([^\n\r\"<>]+)");
public MakeDeps() {
@@ -60,63 +73,59 @@ public class MakeDeps extends Task {
@throws BuildException
**/
public void execute() throws BuildException {
- ///
- /// check if the dependency list file is uptodate or not
- ///
+ //
+ // check if the dependency list file is uptodate or not
+ //
if (isUptodate()) {
return;
}
- Project prj = this.getOwningTarget().getProject();
- String toolPath = prj.getProperty("env.FRAMEWORK_TOOLS_PATH");
-
- ///
- /// compose full tool path
- ///
- if (toolPath == null || toolPath.length() == 0) {
- toolPath = toolName;
- } else {
- if (toolPath.endsWith("/") || toolPath.endsWith("\\")) {
- toolPath = toolPath + toolName;
- } else {
- toolPath = toolPath + File.separator + toolName;
- }
+ //
+ // if no include path is specified, try locally
+ //
+ if (includePathList.isEmpty()) {
+ includePathList.insPath(".");
}
- ///
- /// compose tool arguments
- ///
- String argument = "" + inputFileList + includePathList + subDir
- + quietMode + ignoreError + target + depsFile;
+ Set<String> depFiles = getDependencies(inputFileList.toArray());
- ///
- /// prepare to execute the tool
- ///
- Commandline cmd = new Commandline();
- cmd.setExecutable(toolPath);
- cmd.createArgument().setLine(argument);
+ File depsFile = new File(depsFilePath);
+ FileWriter fileWriter = null;
+ BufferedWriter bufWriter = null;
- LogStreamHandler streamHandler = new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN);
- Execute runner = new Execute(streamHandler, null);
-
- runner.setAntRun(prj);
- runner.setCommandline(cmd.getCommandline());
+ try {
+ fileWriter = new FileWriter(depsFile);
+ bufWriter = new BufferedWriter(fileWriter);
- EdkLog.log(this, EdkLog.EDK_VERBOSE, Commandline.toString(cmd.getCommandline()));
- int result = 0;
- try {
- result = runner.execute();
- } catch (IOException e) {
+ for (Iterator it = depFiles.iterator(); it.hasNext();) {
+ String depFile = (String)it.next();
+ bufWriter.write(depFile, 0, depFile.length());
+ bufWriter.write("\n", 0, 1);
+ }
+ //
+ // put a "tab" at the end of file as file ending flag
+ //
+ bufWriter.write("\t", 0, 1);
+ } catch (Exception e) {
throw new BuildException(e.getMessage());
+ } finally {
+ try {
+ if (bufWriter != null) {
+ bufWriter.close();
+ }
+ if (fileWriter != null) {
+ fileWriter.close();
+ }
+ } catch (Exception e) {
+ throw new BuildException(e.getMessage());
+ }
}
- if (result != 0) {
- EdkLog.log(this, EdkLog.EDK_INFO, toolName + " failed!");
- throw new BuildException(toolName + ": failed to generate dependency file!");
- } else {
- EdkLog.log(this, EdkLog.EDK_VERBOSE, toolName + " succeeded!");
- }
+ //
+ // update time stamp of dependency file
+ //
+ FileTimeStamp.update(depsFilePath, depsFile.lastModified());
}
/**
@@ -125,7 +134,7 @@ public class MakeDeps extends Task {
@param name The name of dependency list file
**/
public void setDepsFile(String name) {
- depsFile.setArg(" -o ", name);
+ depsFilePath = name;
}
/**
@@ -134,65 +143,7 @@ public class MakeDeps extends Task {
@returns The name of dependency list file
**/
public String getDepsFile() {
- return depsFile.getValue();
- }
-
- /**
- Set method for "IgnoreError" attribute
-
- @param ignore flag to control error handling (true/false)
- **/
- public void setIgnoreError(boolean ignore) {
- if (!ignore) {
- ignoreError.setArg(" ", " ");
- }
- }
-
- /**
- Get method for "IgnoreError" attribute
-
- @returns The value of current IgnoreError flag
- **/
- public boolean getIgnoreError() {
- return ignoreError.getValue().length() > 0;
- }
-
- /**
- Set method for "QuietMode" attribute
-
- @param quiet flag to control the output information (true/false)
- **/
- public void setQuietMode(boolean quiet) {
- if (!quiet) {
- quietMode.setArg(" ", " ");
- }
- }
-
- /**
- Get method for "QuietMode" attribute
-
- @returns value of current QuietMode flag
- **/
- public boolean getQuietMode() {
- return quietMode.getValue().length() > 0;
- }
-
- /**
- Set method for "SubDir" attribute
-
- @param dir The name of sub-directory in which source files will be scanned
- **/
- public void setSubDir(String dir) {
- subDir.setArg(" -s ", dir);
- }
-
- /**
- Get method for "SubDir" attribute
-
- @returns The name of sub-directory
- **/
- public String getSubDir() {
- return subDir.getValue();
+ return depsFilePath;
}
/**
@@ -220,10 +171,9 @@ public class MakeDeps extends Task {
@returns false The dependency list file is outofdate. Re-generation is needed.
**/
private boolean isUptodate() {
- String dfName = depsFile.getValue();
- File df = new File(dfName);
+ File df = new File(depsFilePath);
if (!df.exists()) {
- EdkLog.log(this, EdkLog.EDK_VERBOSE, dfName + " doesn't exist!");
+ EdkLog.log(this, EdkLog.EDK_VERBOSE, depsFilePath + " doesn't exist!");
return false;
}
@@ -231,7 +181,7 @@ 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 = FileTimeStamp.get(dfName);
+ long depsFileTimeStamp = FileTimeStamp.get(depsFilePath);
List<String> fileList = inputFileList.getNameList();
for (int i = 0, length = fileList.size(); i < length; ++i) {
String sf = fileList.get(i);
@@ -288,17 +238,124 @@ public class MakeDeps extends Task {
// check if the .dep file is empty
//
if (lines == 0) {
- EdkLog.log(this, EdkLog.EDK_VERBOSE, dfName + " is empty!");
+ EdkLog.log(this, EdkLog.EDK_VERBOSE, depsFilePath + " is empty!");
ret = false;
}
-
- lineReader.close();
- fileReader.close();
} catch (IOException e) {
throw new BuildException(e.getMessage());
+ } finally {
+ try {
+ if (lineReader != null) {
+ lineReader.close();
+ }
+ if (fileReader != null) {
+ fileReader.close();
+ }
+ } catch (Exception e) {
+ throw new BuildException(e.getMessage());
+ }
}
return ret;
}
+
+ //
+ // get dependent files list by parsing "#include" directive
+ //
+ private synchronized Set<String> getDependencies(String[] sourceFiles) {
+ Set<String> dependencies = new LinkedHashSet<String>();
+ String[] searchPathList = includePathList.toArray();
+
+ Stack<String> pendingFiles = new Stack<String>();
+ for (int i = 0; i < sourceFiles.length; ++i) {
+ File srcFile = new File(sourceFiles[i]);
+ if (srcFile.exists()) {
+ //
+ // a file must depend itself
+ //
+ dependencies.add(srcFile.getAbsolutePath());
+ pendingFiles.push(sourceFiles[i]);
+ }
+ }
+
+ while (!pendingFiles.empty()) {
+ String src = pendingFiles.pop();
+ File srcFile = new File(src);
+ if (!srcFile.exists()) {
+ continue;
+ }
+
+ //
+ // try cache first
+ //
+ Set<String> incFiles = includesCache.get(src);
+ if (incFiles == null) {
+ incFiles = new HashSet<String>();
+ FileReader fileReader = null;
+ BufferedReader bufReader = null;
+ String fileContent = "";
+ int fileLength = (int)srcFile.length();
+
+ try {
+ fileReader = new FileReader(srcFile);
+ bufReader = new BufferedReader(fileReader);
+ char[] buf = new char[fileLength];
+
+ bufReader.read(buf, 0, fileLength);
+ fileContent = new String(buf);
+ } catch (IOException e) {
+ throw new BuildException(e.getMessage());
+ } finally {
+ try {
+ if (bufReader != null) {
+ bufReader.close();
+ }
+ if (fileReader != null) {
+ fileReader.close();
+ }
+ } catch (Exception e) {
+ throw new BuildException(e.getMessage());
+ }
+ }
+
+ //
+ // find out all "#include" lines
+ //
+ Matcher matcher = incPattern.matcher(fileContent);
+ while (matcher.find()) {
+ String incFilePath = fileContent.substring(matcher.start(1), matcher.end(1));
+ incFiles.add(incFilePath);
+ }
+
+ //
+ // put the includes in cache to avoid re-parsing
+ //
+ includesCache.put(src, incFiles);
+ }
+
+ //
+ // try each include search path to see if the include file exists or not
+ //
+ for (Iterator<String> it = incFiles.iterator(); it.hasNext();) {
+ String depFilePath = it.next();
+
+ for (int i = 0; i < searchPathList.length; ++i) {
+ File depFile = new File(searchPathList[i] + File.separator + depFilePath);
+ String filePath = depFile.getAbsolutePath();
+ //
+ // following check is a must. it can prevent dead loop if two
+ // files include each other
+ //
+ if (depFile.exists() && !dependencies.contains(filePath)) {
+ dependencies.add(filePath);
+ pendingFiles.push(filePath);
+ break;
+ }
+ }
+ }
+ }
+
+ return dependencies;
+ }
}
diff --git a/Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/NestElement.java b/Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/NestElement.java
index 271dee6c88..dd36c9127b 100644
--- a/Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/NestElement.java
+++ b/Tools/Java/Source/FrameworkTasks/org/tianocore/framework/tasks/NestElement.java
@@ -333,6 +333,24 @@ public class NestElement extends DataType {
return toFileList(" ");
}
+ /**
+ Get the array of names
+
+ @return String[] The array contains the names
+ **/
+ public String[] toArray() {
+ return nameList.toArray(new String[nameList.size()]);
+ }
+
+ /**
+ Check if we have any name or not
+
+ @return boolean
+ **/
+ public boolean isEmpty() {
+ return nameList.isEmpty();
+ }
+
//
// Remove any duplicated path separator or inconsistent path separator
//