- Fixed EDKT146; The override warning message has been reduced to almost none.
[mirror_edk2.git] / Tools / Source / FrameworkTasks / org / tianocore / framework / tasks / MakeDeps.java
1 /** @file
2 This file is to wrap MakeDeps.exe tool as ANT task, which is used to generate
3 dependency files for source code.
4
5 Copyright (c) 2006, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15 package org.tianocore.framework.tasks;
16
17 import java.io.File;
18 import java.io.FileReader;
19 import java.io.FileWriter;
20 import java.io.IOException;
21 import java.io.LineNumberReader;
22 import java.util.ArrayList;
23 import java.util.HashSet;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.StringTokenizer;
28
29 import org.apache.tools.ant.BuildException;
30 import org.apache.tools.ant.Project;
31 import org.apache.tools.ant.Task;
32 import org.apache.tools.ant.taskdefs.Execute;
33 import org.apache.tools.ant.taskdefs.LogStreamHandler;
34 import org.apache.tools.ant.types.Commandline;
35 import org.apache.tools.ant.types.Path;
36
37 import org.tianocore.common.logger.EdkLog;
38
39 /**
40 Class MakeDeps is used to wrap MakeDeps.exe as an ANT task.
41 **/
42 public class MakeDeps extends Task {
43
44 //
45 // private members, use set/get to access them
46 //
47 private static final String cmdName = "MakeDeps";
48 private String includePath = null;
49 private String depsFile = null;
50 private String subDir = null;
51 private boolean quietMode = true;
52 private boolean ignoreError = true;
53 private String extraDeps = "";
54 private List<IncludePath> includePathList = new ArrayList<IncludePath>();
55 private List<Input> inputFileList = new ArrayList<Input>();
56
57 public MakeDeps() {
58
59 }
60
61 /**
62 The Standard execute method for ANT task. It will check if it's necessary
63 to generate the dependency list file. If no file is found or the dependency
64 is changed, it will compose the command line and call MakeDeps.exe to
65 generate the dependency list file.
66
67 @throws BuildException
68 **/
69 public void execute() throws BuildException {
70 ///
71 /// check if the dependency list file is uptodate or not
72 ///
73 if (isUptodate()) {
74 return;
75 }
76
77 Project prj = this.getOwningTarget().getProject();
78 String toolPath = prj.getProperty("env.FRAMEWORK_TOOLS_PATH");
79 FrameworkLogger logger = new FrameworkLogger(prj, "makedeps");
80 EdkLog.setLogLevel(prj.getProperty("env.LOGLEVEL"));
81 EdkLog.setLogger(logger);
82
83 ///
84 /// compose full tool path
85 ///
86 if (toolPath == null || toolPath.length() == 0) {
87 toolPath = "./" + cmdName;
88 } else {
89 if (toolPath.endsWith("/") || toolPath.endsWith("\\")) {
90 toolPath = toolPath + cmdName;
91 } else {
92 toolPath = toolPath + "/" + cmdName;
93 }
94 }
95
96 ///
97 /// compose tool arguments
98 ///
99 StringBuffer args = new StringBuffer(4096);
100 if (ignoreError) {
101 args.append(" -ignorenotfound");
102 }
103 if (quietMode) {
104 args.append(" -q");
105 }
106 if (subDir != null && subDir.length() > 0) {
107 args.append(" -s ");
108 args.append(subDir);
109 }
110
111 ///
112 /// if there's no source files, we can do nothing about dependency
113 ///
114 if (inputFileList.size() == 0) {
115 throw new BuildException("No source files specified to scan");
116 }
117
118 ///
119 /// compose source file arguments
120 ///
121 Iterator iterator = inputFileList.iterator();
122 while (iterator.hasNext()) {
123 Input inputFile = (Input)iterator.next();
124 String inputFileString = cleanupPathName(inputFile.getFile());
125 args.append(" -f ");
126 args.append(inputFileString);
127 }
128
129 ///
130 /// compose search pathes argument
131 ///
132 StringBuffer includePathArg = new StringBuffer(4096);
133 if (includePath != null && includePath.length() > 0) {
134 StringTokenizer pathTokens = new StringTokenizer(includePath, ";");
135 while (pathTokens.hasMoreTokens()) {
136 String tmpPath = pathTokens.nextToken().trim();
137 if (tmpPath.length() == 0) {
138 continue;
139 }
140
141 includePathArg.append(" -i ");
142 includePathArg.append(cleanupPathName(tmpPath));
143 }
144 }
145 iterator = includePathList.iterator();
146 while (iterator.hasNext()) {
147 IncludePath path = (IncludePath)iterator.next();
148 includePathArg.append(cleanupPathName(path.getPath()));
149 }
150 args.append(includePathArg);
151
152 ///
153 /// We don't need a real target. So just a "dummy" is given
154 ///
155 args.append(" -target dummy");
156 args.append(" -o ");
157 args.append(cleanupPathName(depsFile));
158
159 ///
160 /// prepare to execute the tool
161 ///
162 Commandline cmd = new Commandline();
163 cmd.setExecutable(toolPath);
164 cmd.createArgument().setLine(args.toString());
165
166 LogStreamHandler streamHandler = new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN);
167 Execute runner = new Execute(streamHandler, null);
168
169 runner.setAntRun(prj);
170 runner.setCommandline(cmd.getCommandline());
171
172 EdkLog.log(EdkLog.EDK_VERBOSE, Commandline.toString(cmd.getCommandline()));
173
174 int result = 0;
175 try {
176 result = runner.execute();
177 } catch (IOException e) {
178 throw new BuildException(e.getMessage());
179 }
180
181 if (result != 0) {
182 EdkLog.log(EdkLog.EDK_INFO, "MakeDeps failed!");
183 return;
184 }
185 }
186
187 ///
188 /// Remove any duplicated path separator or inconsistent path separator
189 ///
190 private String cleanupPathName(String path) {
191 String separator = "\\" + File.separator;
192 String duplicateSeparator = separator + "{2}";
193 path = Path.translateFile(path);
194 path = path.replaceAll(duplicateSeparator, separator);
195 return path;
196 }
197
198 /**
199 Set method for "DepsFile" attribute
200
201 @param name The name of dependency list file
202 **/
203 public void setDepsFile(String name) {
204 depsFile = cleanupPathName(name);
205 }
206
207 /**
208 Get method for "DepsFile" attribute
209
210 @returns The name of dependency list file
211 **/
212 public String getDepsFile() {
213 return depsFile;
214 }
215
216 /**
217 Set method for "IgnoreError" attribute
218
219 @param ignore flag to control error handling (true/false)
220 **/
221 public void setIgnoreError(boolean ignore) {
222 ignoreError = ignore;
223 }
224
225 /**
226 Get method for "IgnoreError" attribute
227
228 @returns The value of current IgnoreError flag
229 **/
230 public boolean getIgnoreError() {
231 return ignoreError;
232 }
233
234 /**
235 Set method for "QuietMode" attribute
236
237 @param quiet flag to control the output information (true/false)
238 **/
239 public void setQuietMode(boolean quiet) {
240 quietMode = quiet;
241 }
242
243 /**
244 Get method for "QuietMode" attribute
245
246 @returns value of current QuietMode flag
247 **/
248 public boolean getQuietMode() {
249 return quietMode;
250 }
251
252 /**
253 Set method for "SubDir" attribute
254
255 @param dir The name of sub-directory in which source files will be scanned
256 **/
257 public void setSubDir(String dir) {
258 subDir = dir;
259 }
260
261 /**
262 Get method for "SubDir" attribute
263
264 @returns The name of sub-directory
265 **/
266 public String getSubDir() {
267 return subDir;
268 }
269
270 /**
271 Set method for "IncludePath" attribute
272
273 @param path The name of include path
274 **/
275 public void setIncludePath(String path) {
276 includePath = cleanupPathName(path);
277 }
278
279 /**
280 Get method for "IncludePath" attribute
281
282 @returns The name of include path
283 **/
284 public String getIncludePath() {
285 return includePath;
286 }
287
288 /**
289 Set method for "ExtraDeps" attribute
290
291 @param deps The name of dependency file specified separately
292 **/
293 public void setExtraDeps(String deps) {
294 extraDeps = deps;
295 }
296
297 /**
298 Get method for "ExtraDeps" attribute
299
300 @returns The name of dependency file specified separately
301 **/
302 public String getExtraDeps () {
303 return extraDeps;
304 }
305
306 /**
307 Add method for "IncludePath" nested element
308
309 @param path The IncludePath object from nested IncludePath type of element
310 **/
311 public void addIncludepath(IncludePath path) {
312 includePathList.add(path);
313 }
314
315 /**
316 Add method for "Input" nested element
317
318 @param input The Input object from nested Input type of element
319 **/
320 public void addInput(Input inputFile) {
321 inputFileList.add(inputFile);
322 }
323
324 /**
325 Check if the dependency list file should be (re-)generated or not.
326
327 @returns true The dependency list file is uptodate. No re-generation is needed.
328 @returns false The dependency list file is outofdate. Re-generation is needed.
329 **/
330 private boolean isUptodate() {
331 File df = new File(depsFile);
332 if (!df.exists()) {
333 return false;
334 }
335
336 ///
337 /// If the source file(s) is newer than dependency list file, we need to
338 /// re-generate the dependency list file
339 ///
340 long depsFileTimeStamp = df.lastModified();
341 Iterator iterator = inputFileList.iterator();
342 while (iterator.hasNext()) {
343 Input inputFile = (Input)iterator.next();
344 File sf = new File(inputFile.getFile());
345 if (sf.lastModified() > depsFileTimeStamp) {
346 return false;
347 }
348 }
349
350 ///
351 /// If the source files haven't been changed since last time the dependency
352 /// list file was generated, we need to check each file in the file list to
353 /// see if any of them is changed or not. If anyone of them is newer than
354 /// the dependency list file, MakeDeps.exe is needed to run again.
355 ///
356 LineNumberReader lineReader = null;
357 FileReader fileReader = null;
358 boolean ret = true;
359 try {
360 fileReader = new FileReader(df);
361 lineReader = new LineNumberReader(fileReader);
362
363 String line = null;
364 while ((line = lineReader.readLine()) != null) {
365 File sourceFile = new File(line);
366 if (sourceFile.lastModified() > depsFileTimeStamp) {
367 ret = false;
368 break;
369 }
370 }
371 lineReader.close();
372 fileReader.close();
373 } catch (IOException e) {
374 log (e.getMessage());
375 }
376
377 return ret;
378 }
379 }
380