2 This file is to wrap MakeDeps.exe tool as ANT task, which is used to generate
3 dependency files for source code.
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
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.
15 package org
.tianocore
.framework
.tasks
;
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
;
27 import java
.util
.StringTokenizer
;
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
;
37 import org
.tianocore
.common
.logger
.EdkLog
;
40 Class MakeDeps is used to wrap MakeDeps.exe as an ANT task.
42 public class MakeDeps
extends Task
{
45 // private members, use set/get to access them
47 private static final String cmdName
= "MakeDeps";
48 private String depsFile
= null;
49 private String subDir
= null;
50 private boolean quietMode
= true;
51 private boolean ignoreError
= true;
52 private String extraDeps
= "";
53 private List
<IncludePath
> includePathList
= new ArrayList
<IncludePath
>();
54 private List
<Input
> inputFileList
= new ArrayList
<Input
>();
61 The Standard execute method for ANT task. It will check if it's necessary
62 to generate the dependency list file. If no file is found or the dependency
63 is changed, it will compose the command line and call MakeDeps.exe to
64 generate the dependency list file.
66 @throws BuildException
68 public void execute() throws BuildException
{
70 /// check if the dependency list file is uptodate or not
76 Project prj
= this.getOwningTarget().getProject();
77 String toolPath
= prj
.getProperty("env.FRAMEWORK_TOOLS_PATH");
78 FrameworkLogger logger
= new FrameworkLogger(prj
, "makedeps");
79 EdkLog
.setLogLevel(prj
.getProperty("env.LOGLEVEL"));
80 EdkLog
.setLogger(logger
);
83 /// compose full tool path
85 if (toolPath
== null || toolPath
.length() == 0) {
88 if (toolPath
.endsWith("/") || toolPath
.endsWith("\\")) {
89 toolPath
= toolPath
+ cmdName
;
91 toolPath
= toolPath
+ File
.separator
+ cmdName
;
96 /// compose tool arguments
98 StringBuffer args
= new StringBuffer(4096);
100 args
.append(" -ignorenotfound ");
105 if (subDir
!= null && subDir
.length() > 0) {
111 /// if there's no source files, we can do nothing about dependency
113 if (inputFileList
.size() == 0) {
114 throw new BuildException("No source files specified to scan");
118 /// compose source file arguments
120 for (int i
= 0, listLength
= inputFileList
.size(); i
< listLength
; ++i
) {
121 args
.append(inputFileList
.get(i
).toString());
124 for (int i
= 0, listLength
= includePathList
.size(); i
< listLength
; ++i
) {
125 args
.append(includePathList
.get(i
).toString());
129 /// We don't need a real target. So just a "dummy" is given
131 args
.append(" -target dummy");
133 args
.append(depsFile
);
136 /// prepare to execute the tool
138 Commandline cmd
= new Commandline();
139 cmd
.setExecutable(toolPath
);
140 cmd
.createArgument().setLine(args
.toString());
142 LogStreamHandler streamHandler
= new LogStreamHandler(this, Project
.MSG_INFO
, Project
.MSG_WARN
);
143 Execute runner
= new Execute(streamHandler
, null);
145 runner
.setAntRun(prj
);
146 runner
.setCommandline(cmd
.getCommandline());
148 EdkLog
.log(EdkLog
.EDK_VERBOSE
, Commandline
.toString(cmd
.getCommandline()));
152 result
= runner
.execute();
153 } catch (IOException e
) {
154 throw new BuildException(e
.getMessage());
158 EdkLog
.log(EdkLog
.EDK_INFO
, "MakeDeps failed!");
159 throw new BuildException("MakeDeps: failed to generate dependency file!");
164 /// Remove any duplicated path separator or inconsistent path separator
166 private String
cleanupPathName(String path
) {
167 String separator
= "\\" + File
.separator
;
168 String duplicateSeparator
= separator
+ "{2}";
169 path
= Path
.translateFile(path
);
170 path
= path
.replaceAll(duplicateSeparator
, separator
);
175 Set method for "DepsFile" attribute
177 @param name The name of dependency list file
179 public void setDepsFile(String name
) {
180 depsFile
= cleanupPathName(name
);
184 Get method for "DepsFile" attribute
186 @returns The name of dependency list file
188 public String
getDepsFile() {
193 Set method for "IgnoreError" attribute
195 @param ignore flag to control error handling (true/false)
197 public void setIgnoreError(boolean ignore
) {
198 ignoreError
= ignore
;
202 Get method for "IgnoreError" attribute
204 @returns The value of current IgnoreError flag
206 public boolean getIgnoreError() {
211 Set method for "QuietMode" attribute
213 @param quiet flag to control the output information (true/false)
215 public void setQuietMode(boolean quiet
) {
220 Get method for "QuietMode" attribute
222 @returns value of current QuietMode flag
224 public boolean getQuietMode() {
229 Set method for "SubDir" attribute
231 @param dir The name of sub-directory in which source files will be scanned
233 public void setSubDir(String dir
) {
234 subDir
= cleanupPathName(dir
);
238 Get method for "SubDir" attribute
240 @returns The name of sub-directory
242 public String
getSubDir() {
247 Set method for "ExtraDeps" attribute
249 @param deps The name of dependency file specified separately
251 public void setExtraDeps(String deps
) {
252 extraDeps
= cleanupPathName(deps
);
256 Get method for "ExtraDeps" attribute
258 @returns The name of dependency file specified separately
260 public String
getExtraDeps () {
265 Add method for "IncludePath" nested element
267 @param path The IncludePath object from nested IncludePath type of element
269 public void addIncludepath(IncludePath path
) {
270 includePathList
.add(path
);
274 Add method for "Input" nested element
276 @param input The Input object from nested Input type of element
278 public void addInput(Input inputFile
) {
279 inputFileList
.add(inputFile
);
283 Check if the dependency list file should be (re-)generated or not.
285 @returns true The dependency list file is uptodate. No re-generation is needed.
286 @returns false The dependency list file is outofdate. Re-generation is needed.
288 private boolean isUptodate() {
289 File df
= new File(depsFile
);
295 // If the source file(s) is newer than dependency list file, we need to
296 // re-generate the dependency list file
298 long depsFileTimeStamp
= df
.lastModified();
299 Iterator
<Input
> iterator
= (Iterator
<Input
>)inputFileList
.iterator();
300 while (iterator
.hasNext()) {
301 Input inputFile
= iterator
.next();
302 List
<String
> fileList
= inputFile
.getNameList();
303 for (int i
= 0, length
= fileList
.size(); i
< length
; ++i
) {
304 File sf
= new File(fileList
.get(i
));
305 if (sf
.lastModified() > depsFileTimeStamp
) {
312 // If the source files haven't been changed since last time the dependency
313 // list file was generated, we need to check each file in the file list to
314 // see if any of them is changed or not. If anyone of them is newer than
315 // the dependency list file, MakeDeps.exe is needed to run again.
317 LineNumberReader lineReader
= null;
318 FileReader fileReader
= null;
321 fileReader
= new FileReader(df
);
322 lineReader
= new LineNumberReader(fileReader
);
325 while ((line
= lineReader
.readLine()) != null) {
326 File sourceFile
= new File(line
);
328 // If a file cannot be found (moved or removed) or newer, regenerate the dep file
330 if ((!sourceFile
.exists()) || (sourceFile
.lastModified() > depsFileTimeStamp
)) {
337 } catch (IOException e
) {
338 log (e
.getMessage());