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