]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/FrameworkTasks/org/tianocore/framework/tasks/MakeDeps.java
1) Add FileTimeStamp class to centralize the cache mechanism for file time stamp...
[mirror_edk2.git] / Tools / Source / FrameworkTasks / org / tianocore / framework / tasks / MakeDeps.java
CommitLineData
878ddf1f 1/** @file\r
2This file is to wrap MakeDeps.exe tool as ANT task, which is used to generate\r
3dependency files for source code.\r
4\r
5Copyright (c) 2006, Intel Corporation\r
6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15package org.tianocore.framework.tasks;\r
16\r
878ddf1f 17import java.io.File;\r
18import java.io.FileReader;\r
878ddf1f 19import java.io.IOException;\r
20import java.io.LineNumberReader;\r
21import java.util.ArrayList;\r
22import java.util.Iterator;\r
23import java.util.List;\r
878ddf1f 24\r
196ad8d7 25import org.apache.tools.ant.BuildException;\r
26import org.apache.tools.ant.Project;\r
27import org.apache.tools.ant.Task;\r
28import org.apache.tools.ant.taskdefs.Execute;\r
29import org.apache.tools.ant.taskdefs.LogStreamHandler;\r
30import org.apache.tools.ant.types.Commandline;\r
31import org.apache.tools.ant.types.Path;\r
ff225cbb 32\r
33import org.tianocore.common.logger.EdkLog;\r
4b134847 34import org.tianocore.common.cache.FileTimeStamp;\r
196ad8d7 35\r
878ddf1f 36/**\r
37 Class MakeDeps is used to wrap MakeDeps.exe as an ANT task.\r
38 **/\r
39public class MakeDeps extends Task {\r
40\r
41 //\r
42 // private members, use set/get to access them\r
43 //\r
0fdb42ac 44 private static final String toolName = "MakeDeps";\r
45 private FileArg depsFile = new FileArg();\r
46 private ToolArg subDir = new ToolArg();\r
47 private ToolArg quietMode = new ToolArg(" -", "q");\r
48 private ToolArg ignoreError = new ToolArg(" -", "ignorenotfound");\r
49 private IncludePath includePathList = new IncludePath();\r
50 private Input inputFileList = new Input();\r
51 private ToolArg target = new FileArg(" -target ", "dummy");\r
878ddf1f 52\r
53 public MakeDeps() {\r
54\r
55 }\r
56\r
57 /**\r
58 The Standard execute method for ANT task. It will check if it's necessary\r
59 to generate the dependency list file. If no file is found or the dependency\r
60 is changed, it will compose the command line and call MakeDeps.exe to\r
61 generate the dependency list file.\r
62\r
63 @throws BuildException\r
64 **/\r
65 public void execute() throws BuildException {\r
66 ///\r
67 /// check if the dependency list file is uptodate or not\r
68 ///\r
69 if (isUptodate()) {\r
70 return;\r
71 }\r
72\r
73 Project prj = this.getOwningTarget().getProject();\r
2da8968b 74 String toolPath = prj.getProperty("env.FRAMEWORK_TOOLS_PATH");\r
219e2247 75\r
878ddf1f 76 ///\r
77 /// compose full tool path\r
78 ///\r
79 if (toolPath == null || toolPath.length() == 0) {\r
0fdb42ac 80 toolPath = toolName;\r
878ddf1f 81 } else {\r
82 if (toolPath.endsWith("/") || toolPath.endsWith("\\")) {\r
0fdb42ac 83 toolPath = toolPath + toolName;\r
878ddf1f 84 } else {\r
0fdb42ac 85 toolPath = toolPath + File.separator + toolName;\r
878ddf1f 86 }\r
87 }\r
88\r
89 ///\r
90 /// compose tool arguments\r
91 ///\r
0fdb42ac 92 String argument = "" + inputFileList + includePathList + subDir\r
93 + quietMode + ignoreError + target + depsFile;\r
878ddf1f 94\r
95 ///\r
96 /// prepare to execute the tool\r
97 ///\r
98 Commandline cmd = new Commandline();\r
99 cmd.setExecutable(toolPath);\r
0fdb42ac 100 cmd.createArgument().setLine(argument);\r
878ddf1f 101\r
102 LogStreamHandler streamHandler = new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN);\r
103 Execute runner = new Execute(streamHandler, null);\r
104\r
105 runner.setAntRun(prj);\r
106 runner.setCommandline(cmd.getCommandline());\r
107\r
91f7d582 108 EdkLog.log(this, EdkLog.EDK_VERBOSE, Commandline.toString(cmd.getCommandline()));\r
219e2247 109\r
878ddf1f 110 int result = 0;\r
111 try {\r
112 result = runner.execute();\r
113 } catch (IOException e) {\r
114 throw new BuildException(e.getMessage());\r
115 }\r
116\r
117 if (result != 0) {\r
0fdb42ac 118 EdkLog.log(this, EdkLog.EDK_INFO, toolName + " failed!");\r
119 throw new BuildException(toolName + ": failed to generate dependency file!");\r
120 } else {\r
121 EdkLog.log(this, EdkLog.EDK_VERBOSE, toolName + " succeeded!");\r
878ddf1f 122 }\r
878ddf1f 123 }\r
124\r
878ddf1f 125 /**\r
126 Set method for "DepsFile" attribute\r
127\r
128 @param name The name of dependency list file\r
129 **/\r
130 public void setDepsFile(String name) {\r
0fdb42ac 131 depsFile.setArg(" -o ", name);\r
878ddf1f 132 }\r
133\r
134 /**\r
135 Get method for "DepsFile" attribute\r
136\r
137 @returns The name of dependency list file\r
138 **/\r
139 public String getDepsFile() {\r
0fdb42ac 140 return depsFile.getValue();\r
878ddf1f 141 }\r
142\r
143 /**\r
144 Set method for "IgnoreError" attribute\r
145\r
146 @param ignore flag to control error handling (true/false)\r
147 **/\r
148 public void setIgnoreError(boolean ignore) {\r
0fdb42ac 149 if (!ignore) {\r
150 ignoreError.setArg(" ", " ");\r
151 }\r
878ddf1f 152 }\r
153\r
154 /**\r
155 Get method for "IgnoreError" attribute\r
156\r
157 @returns The value of current IgnoreError flag\r
158 **/\r
159 public boolean getIgnoreError() {\r
0fdb42ac 160 return ignoreError.getValue().length() > 0;\r
878ddf1f 161 }\r
162\r
163 /**\r
164 Set method for "QuietMode" attribute\r
165\r
166 @param quiet flag to control the output information (true/false)\r
167 **/\r
168 public void setQuietMode(boolean quiet) {\r
0fdb42ac 169 if (!quiet) {\r
170 quietMode.setArg(" ", " ");\r
171 }\r
878ddf1f 172 }\r
173\r
174 /**\r
175 Get method for "QuietMode" attribute\r
176\r
177 @returns value of current QuietMode flag\r
178 **/\r
179 public boolean getQuietMode() {\r
0fdb42ac 180 return quietMode.getValue().length() > 0;\r
878ddf1f 181 }\r
182\r
183 /**\r
184 Set method for "SubDir" attribute\r
185\r
186 @param dir The name of sub-directory in which source files will be scanned\r
187 **/\r
188 public void setSubDir(String dir) {\r
0fdb42ac 189 subDir.setArg(" -s ", dir);\r
878ddf1f 190 }\r
191\r
192 /**\r
193 Get method for "SubDir" attribute\r
194\r
195 @returns The name of sub-directory\r
196 **/\r
197 public String getSubDir() {\r
0fdb42ac 198 return subDir.getValue();\r
878ddf1f 199 }\r
200\r
201 /**\r
202 Add method for "IncludePath" nested element\r
203\r
204 @param path The IncludePath object from nested IncludePath type of element\r
205 **/\r
0fdb42ac 206 public void addConfiguredIncludepath(IncludePath path) {\r
207 includePathList.insert(path);\r
878ddf1f 208 }\r
209\r
210 /**\r
211 Add method for "Input" nested element\r
212\r
213 @param input The Input object from nested Input type of element\r
214 **/\r
0fdb42ac 215 public void addConfiguredInput(Input inputFile) {\r
216 inputFileList.insert(inputFile);\r
878ddf1f 217 }\r
218\r
878ddf1f 219 /**\r
220 Check if the dependency list file should be (re-)generated or not.\r
221\r
222 @returns true The dependency list file is uptodate. No re-generation is needed.\r
223 @returns false The dependency list file is outofdate. Re-generation is needed.\r
224 **/\r
225 private boolean isUptodate() {\r
0fdb42ac 226 String dfName = depsFile.getValue();\r
227 File df = new File(dfName);\r
878ddf1f 228 if (!df.exists()) {\r
0fdb42ac 229 EdkLog.log(this, EdkLog.EDK_VERBOSE, dfName + " doesn't exist!");\r
878ddf1f 230 return false;\r
231 }\r
232\r
82810f3b 233 //\r
234 // If the source file(s) is newer than dependency list file, we need to\r
235 // re-generate the dependency list file\r
236 //\r
4b134847 237 long depsFileTimeStamp = FileTimeStamp.get(dfName);\r
0fdb42ac 238 List<String> fileList = inputFileList.getNameList();\r
239 for (int i = 0, length = fileList.size(); i < length; ++i) {\r
4b134847 240 String sf = fileList.get(i);\r
241 if (FileTimeStamp.get(sf) > depsFileTimeStamp) {\r
242 EdkLog.log(this, EdkLog.EDK_VERBOSE, sf + " has been changed since last build!");\r
0fdb42ac 243 return false;\r
878ddf1f 244 }\r
245 }\r
246\r
82810f3b 247 //\r
248 // If the source files haven't been changed since last time the dependency\r
249 // list file was generated, we need to check each file in the file list to\r
250 // see if any of them is changed or not. If anyone of them is newer than\r
251 // the dependency list file, MakeDeps.exe is needed to run again.\r
252 //\r
878ddf1f 253 LineNumberReader lineReader = null;\r
254 FileReader fileReader = null;\r
93f5dd0a 255 boolean ret = false;\r
878ddf1f 256 try {\r
257 fileReader = new FileReader(df);\r
258 lineReader = new LineNumberReader(fileReader);\r
259\r
260 String line = null;\r
93f5dd0a 261 int lines = 0;\r
878ddf1f 262 while ((line = lineReader.readLine()) != null) {\r
93f5dd0a 263 //\r
264 // check file end flag "\t" to see if the .dep was generated correctly\r
265 // \r
266 if (line.equals("\t")) {\r
267 ret = true;\r
268 continue;\r
269 }\r
270 line = line.trim();\r
271 //\r
272 // skip empty line\r
273 // \r
274 if (line.length() == 0) {\r
275 continue;\r
276 }\r
277 ++lines;\r
278\r
1f08e795 279 //\r
280 // If a file cannot be found (moved or removed) or newer, regenerate the dep file\r
281 // \r
93f5dd0a 282 File sourceFile = new File(line);\r
4b134847 283 if ((!sourceFile.exists()) || (FileTimeStamp.get(line) > depsFileTimeStamp)) {\r
93f5dd0a 284 EdkLog.log(this, EdkLog.EDK_VERBOSE, sourceFile.getPath() + " has been (re)moved or changed since last build!");\r
878ddf1f 285 ret = false;\r
286 break;\r
287 }\r
288 }\r
93f5dd0a 289\r
290 //\r
291 // check if the .dep file is empty\r
292 // \r
293 if (lines == 0) {\r
0fdb42ac 294 EdkLog.log(this, EdkLog.EDK_VERBOSE, dfName + " is empty!");\r
93f5dd0a 295 ret = false;\r
296 }\r
297\r
878ddf1f 298 lineReader.close();\r
299 fileReader.close();\r
300 } catch (IOException e) {\r
93f5dd0a 301 throw new BuildException(e.getMessage());\r
878ddf1f 302 }\r
303\r
304 return ret;\r
305 }\r
306}\r
307\r