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