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
.IOException
;
20 import java
.io
.LineNumberReader
;
21 import java
.util
.ArrayList
;
22 import java
.util
.Iterator
;
23 import java
.util
.List
;
25 import org
.apache
.tools
.ant
.BuildException
;
26 import org
.apache
.tools
.ant
.Project
;
27 import org
.apache
.tools
.ant
.Task
;
28 import org
.apache
.tools
.ant
.taskdefs
.Execute
;
29 import org
.apache
.tools
.ant
.taskdefs
.LogStreamHandler
;
30 import org
.apache
.tools
.ant
.types
.Commandline
;
31 import org
.apache
.tools
.ant
.types
.Path
;
33 import org
.tianocore
.common
.logger
.EdkLog
;
34 import org
.tianocore
.common
.cache
.FileTimeStamp
;
37 Class MakeDeps is used to wrap MakeDeps.exe as an ANT task.
39 public class MakeDeps
extends Task
{
42 // private members, use set/get to access them
44 private static final String toolName
= "MakeDeps";
45 private FileArg depsFile
= new FileArg();
46 private ToolArg subDir
= new ToolArg();
47 private ToolArg quietMode
= new ToolArg(" -", "q");
48 private ToolArg ignoreError
= new ToolArg(" -", "ignorenotfound");
49 private IncludePath includePathList
= new IncludePath();
50 private Input inputFileList
= new Input();
51 private ToolArg target
= new FileArg(" -target ", "dummy");
58 The Standard execute method for ANT task. It will check if it's necessary
59 to generate the dependency list file. If no file is found or the dependency
60 is changed, it will compose the command line and call MakeDeps.exe to
61 generate the dependency list file.
63 @throws BuildException
65 public void execute() throws BuildException
{
67 /// check if the dependency list file is uptodate or not
73 Project prj
= this.getOwningTarget().getProject();
74 String toolPath
= prj
.getProperty("env.FRAMEWORK_TOOLS_PATH");
77 /// compose full tool path
79 if (toolPath
== null || toolPath
.length() == 0) {
82 if (toolPath
.endsWith("/") || toolPath
.endsWith("\\")) {
83 toolPath
= toolPath
+ toolName
;
85 toolPath
= toolPath
+ File
.separator
+ toolName
;
90 /// compose tool arguments
92 String argument
= "" + inputFileList
+ includePathList
+ subDir
93 + quietMode
+ ignoreError
+ target
+ depsFile
;
96 /// prepare to execute the tool
98 Commandline cmd
= new Commandline();
99 cmd
.setExecutable(toolPath
);
100 cmd
.createArgument().setLine(argument
);
102 LogStreamHandler streamHandler
= new LogStreamHandler(this, Project
.MSG_INFO
, Project
.MSG_WARN
);
103 Execute runner
= new Execute(streamHandler
, null);
105 runner
.setAntRun(prj
);
106 runner
.setCommandline(cmd
.getCommandline());
108 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, Commandline
.toString(cmd
.getCommandline()));
112 result
= runner
.execute();
113 } catch (IOException e
) {
114 throw new BuildException(e
.getMessage());
118 EdkLog
.log(this, EdkLog
.EDK_INFO
, toolName
+ " failed!");
119 throw new BuildException(toolName
+ ": failed to generate dependency file!");
121 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, toolName
+ " succeeded!");
126 Set method for "DepsFile" attribute
128 @param name The name of dependency list file
130 public void setDepsFile(String name
) {
131 depsFile
.setArg(" -o ", name
);
135 Get method for "DepsFile" attribute
137 @returns The name of dependency list file
139 public String
getDepsFile() {
140 return depsFile
.getValue();
144 Set method for "IgnoreError" attribute
146 @param ignore flag to control error handling (true/false)
148 public void setIgnoreError(boolean ignore
) {
150 ignoreError
.setArg(" ", " ");
155 Get method for "IgnoreError" attribute
157 @returns The value of current IgnoreError flag
159 public boolean getIgnoreError() {
160 return ignoreError
.getValue().length() > 0;
164 Set method for "QuietMode" attribute
166 @param quiet flag to control the output information (true/false)
168 public void setQuietMode(boolean quiet
) {
170 quietMode
.setArg(" ", " ");
175 Get method for "QuietMode" attribute
177 @returns value of current QuietMode flag
179 public boolean getQuietMode() {
180 return quietMode
.getValue().length() > 0;
184 Set method for "SubDir" attribute
186 @param dir The name of sub-directory in which source files will be scanned
188 public void setSubDir(String dir
) {
189 subDir
.setArg(" -s ", dir
);
193 Get method for "SubDir" attribute
195 @returns The name of sub-directory
197 public String
getSubDir() {
198 return subDir
.getValue();
202 Add method for "IncludePath" nested element
204 @param path The IncludePath object from nested IncludePath type of element
206 public void addConfiguredIncludepath(IncludePath path
) {
207 includePathList
.insert(path
);
211 Add method for "Input" nested element
213 @param input The Input object from nested Input type of element
215 public void addConfiguredInput(Input inputFile
) {
216 inputFileList
.insert(inputFile
);
220 Check if the dependency list file should be (re-)generated or not.
222 @returns true The dependency list file is uptodate. No re-generation is needed.
223 @returns false The dependency list file is outofdate. Re-generation is needed.
225 private boolean isUptodate() {
226 String dfName
= depsFile
.getValue();
227 File df
= new File(dfName
);
229 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, dfName
+ " doesn't exist!");
234 // If the source file(s) is newer than dependency list file, we need to
235 // re-generate the dependency list file
237 long depsFileTimeStamp
= FileTimeStamp
.get(dfName
);
238 List
<String
> fileList
= inputFileList
.getNameList();
239 for (int i
= 0, length
= fileList
.size(); i
< length
; ++i
) {
240 String sf
= fileList
.get(i
);
241 if (FileTimeStamp
.get(sf
) > depsFileTimeStamp
) {
242 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, sf
+ " has been changed since last build!");
248 // If the source files haven't been changed since last time the dependency
249 // list file was generated, we need to check each file in the file list to
250 // see if any of them is changed or not. If anyone of them is newer than
251 // the dependency list file, MakeDeps.exe is needed to run again.
253 LineNumberReader lineReader
= null;
254 FileReader fileReader
= null;
257 fileReader
= new FileReader(df
);
258 lineReader
= new LineNumberReader(fileReader
);
262 while ((line
= lineReader
.readLine()) != null) {
264 // check file end flag "\t" to see if the .dep was generated correctly
266 if (line
.equals("\t")) {
274 if (line
.length() == 0) {
280 // If a file cannot be found (moved or removed) or newer, regenerate the dep file
282 File sourceFile
= new File(line
);
283 if ((!sourceFile
.exists()) || (FileTimeStamp
.get(line
) > depsFileTimeStamp
)) {
284 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, sourceFile
.getPath() + " has been (re)moved or changed since last build!");
291 // check if the .dep file is empty
294 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, dfName
+ " is empty!");
300 } catch (IOException e
) {
301 throw new BuildException(e
.getMessage());