- Fixed EDKT146; The override warning message has been reduced to almost none.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / FrameworkBuildTask.java
1 /** @file FrameworkBuildTask.java
2
3 The file is ANT task to find MSA or FPD file and build them.
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 package org.tianocore.build;
15
16 import java.io.BufferedReader;
17 import java.io.File;
18 import java.io.InputStreamReader;
19 import java.util.Iterator;
20 import java.util.LinkedHashSet;
21 import java.util.Map;
22 import java.util.Set;
23
24 import org.apache.tools.ant.BuildException;
25 import org.apache.tools.ant.Task;
26 import org.tianocore.build.fpd.FpdParserTask;
27 import org.tianocore.build.global.GlobalData;
28 import org.tianocore.build.global.PropertyManager;
29 import org.tianocore.build.toolchain.ConfigReader;
30 import org.tianocore.build.toolchain.ToolChainInfo;
31 import org.tianocore.common.definitions.ToolDefinitions;
32
33 /**
34 <p>
35 <code>FrameworkBuildTask</code> is an Ant task. The main function is finding
36 and processing a FPD or MSA file, then building a platform or stand-alone
37 module.
38
39 <p>
40 The task search current directory and find out all MSA and FPD files by file
41 extension. Base on ACTIVE_PLATFORM policy, decide to build a platform or a
42 stand-alone module. The ACTIVE_PLATFORM policy is:
43
44 <pre>
45 1. More than one MSA files, report error;
46 2. Only one MSA file, but ACTIVE_PLATFORM is not specified, report error;
47 3. Only one MSA file, and ACTIVE_PLATFORM is also specified, build this module;
48 4. No MSA file, and ACTIVE_PLATFORM is specified, build the active platform;
49 5. No MSA file, no ACTIVE_PLATFORM, and no FPD file, report error;
50 6. No MSA file, no ACTIVE_PLATFORM, and only one FPD file, build the platform;
51 7. No MSA file, no ACTIVE_PLATFORM, and more than one FPD files, list all platform
52 and let user choose one.
53 </pre>
54
55 <p>
56 Framework build task also parse target file [${WORKSPACE_DIR}/Tools/Conf/target.txt].
57 And load all system environment variables to Ant properties.
58
59 <p>
60 The usage for this task is :
61
62 <pre>
63 &lt;FrameworkBuild type="cleanall" /&gt;
64 </pre>
65
66 @since GenBuild 1.0
67 **/
68 public class FrameworkBuildTask extends Task{
69
70 private Set<File> buildFiles = new LinkedHashSet<File>();
71
72 private Set<File> fpdFiles = new LinkedHashSet<File>();
73
74 private Set<File> msaFiles = new LinkedHashSet<File>();
75
76 String toolsDefFilename = ToolDefinitions.DEFAULT_TOOLS_DEF_FILE_PATH;
77
78 String targetFilename = ToolDefinitions.TARGET_FILE_PATH;
79
80 String dbFilename = ToolDefinitions.FRAMEWORK_DATABASE_FILE_PATH;
81
82 String activePlatform = null;
83
84 ///
85 /// there are three type: all (build), clean and cleanall
86 ///
87 private String type = "all";
88
89 public void execute() throws BuildException {
90 //
91 // Seach build.xml -> .FPD -> .MSA file
92 //
93 try {
94 //
95 // Gen Current Working Directory
96 //
97 File dummyFile = new File(".");
98 File cwd = dummyFile.getCanonicalFile();
99 File[] files = cwd.listFiles();
100 for (int i = 0; i < files.length; i++) {
101 if (files[i].isFile()) {
102 if (files[i].getName().equalsIgnoreCase("build.xml")) {
103 //
104 // First, search build.xml, if found, ANT call it
105 //
106 buildFiles.add(files[i]);
107
108 } else if (files[i].getName().endsWith(ToolDefinitions.FPD_EXTENSION)) {
109 //
110 // Second, search FPD file, if found, build it
111 //
112 fpdFiles.add(files[i]);
113 } else if (files[i].getName().endsWith(ToolDefinitions.MSA_EXTENSION)) {
114 //
115 // Third, search MSA file, if found, build it
116 //
117 msaFiles.add(files[i]);
118 }
119 }
120 }
121 } catch (Exception e) {
122 throw new BuildException(e.getMessage());
123 }
124
125 //
126 // Deal with all environment variable (Add them to properties)
127 //
128 backupSystemProperties();
129
130 //
131 // Read target.txt file
132 //
133 readTargetFile();
134
135 //
136 // Global Data initialization
137 //
138 File workspacePath = new File(getProject().getProperty("WORKSPACE"));
139 PropertyManager.setProperty(getProject(), "WORKSPACE_DIR", workspacePath.getPath().replaceAll("(\\\\)", "/"));
140 GlobalData.initInfo(dbFilename, workspacePath.getPath(), toolsDefFilename);
141
142 //
143 // If find MSA file and ACTIVE_PLATFORM is set, build the module;
144 // else fail build.
145 // If without MSA file, and ACTIVE_PLATFORM is set, build the ACTIVE_PLATFORM.
146 // If ACTIVE_PLATFORM is not set, and only find one FPD file, build the platform;
147 // If find more than one FPD files, let user select one.
148 //
149 File buildFile = null;
150 if (msaFiles.size() > 1) {
151 throw new BuildException("Having more than one MSA file in a directory is not allowed!");
152 } else if (msaFiles.size() == 1 && activePlatform == null) {
153 throw new BuildException("If trying to build a single module, please set ACTIVE_PLATFORM in file [" + targetFilename + "]. ");
154 } else if (msaFiles.size() == 1 && activePlatform != null) {
155 //
156 // Build the single module
157 //
158 buildFile = msaFiles.toArray(new File[1])[0];
159 } else if (activePlatform != null) {
160 buildFile = new File(GlobalData.getWorkspacePath() + File.separatorChar + activePlatform);
161 } else if (fpdFiles.size() == 1) {
162 buildFile = fpdFiles.toArray(new File[1])[0];
163 } else if (fpdFiles.size() > 1) {
164 buildFile = intercommuniteWithUser();
165 }
166 //
167 // If there is no build files or FPD files or MSA files, stop build
168 //
169 else {
170 throw new BuildException("Can't find any FPD or MSA files in the current directory. ");
171 }
172
173 //
174 // Build every FPD files (PLATFORM build)
175 //
176 if (buildFile.getName().endsWith(ToolDefinitions.FPD_EXTENSION)) {
177 System.out.println("Processing the FPD file [" + buildFile.getPath() + "] ..>> ");
178 FpdParserTask fpdParserTask = new FpdParserTask();
179 fpdParserTask.setType(type);
180 fpdParserTask.setProject(getProject());
181 fpdParserTask.setFpdFile(buildFile);
182 fpdParserTask.execute();
183
184 //
185 // If cleanall delete the Platform_build.xml
186 //
187 if (type.compareTo("cleanall") == 0) {
188 File platformBuildFile =
189 new File(getProject().getProperty("PLATFORM_DIR")
190 + File.separatorChar
191 + getProject().getProperty("PLATFORM")
192 + "_build.xml");
193 platformBuildFile.deleteOnExit();
194 }
195 }
196
197 //
198 // Build every MSA files (SINGLE MODULE BUILD)
199 //
200 else if (buildFile.getName().endsWith(ToolDefinitions.MSA_EXTENSION)) {
201 File tmpFile = new File(GlobalData.getWorkspacePath() + File.separatorChar + activePlatform);
202 System.out.println("Using the FPD file [" + tmpFile.getPath() + "] for the active platform. ");
203 System.out.println("Processing the MSA file [" + buildFile.getPath() + "] ..>> ");
204 GenBuildTask genBuildTask = new GenBuildTask();
205 genBuildTask.setSingleModuleBuild(true);
206 genBuildTask.setType(type);
207 PropertyManager.setProperty(getProject(), "PLATFORM_FILE", activePlatform);
208 genBuildTask.setProject(getProject());
209 genBuildTask.setMsaFile(buildFile);
210 genBuildTask.execute();
211 }
212 }
213
214 /**
215 Transfer system environment variables to ANT properties. If system variable
216 already exiests in ANT properties, skip it.
217
218 **/
219 private void backupSystemProperties() {
220 Map<String, String> sysProperties = System.getenv();
221 Set<String> keys = sysProperties.keySet();
222 Iterator<String> iter = keys.iterator();
223 while (iter.hasNext()) {
224 String name = iter.next();
225
226 //
227 // If system environment variable is not in ANT properties, add it
228 //
229 if (getProject().getProperty(name) == null) {
230 PropertyManager.setProperty(getProject(), name, sysProperties.get(name));
231 }
232 }
233 }
234
235 private File intercommuniteWithUser(){
236 File file = null;
237 if (fpdFiles.size() > 1) {
238 File[] allFiles = new File[fpdFiles.size()];
239 int index = 0;
240 Iterator<File> iter = fpdFiles.iterator();
241 while (iter.hasNext()) {
242 allFiles[index] = iter.next();
243 index++;
244 }
245
246 System.out.println("Finding " + allFiles.length + " FPD files: ");
247 for (int i = 0; i < allFiles.length; i++) {
248 System.out.println("[" + (i + 1) + "]: " + allFiles[i].getName());
249 }
250
251 boolean flag = true;
252 System.out.print("Please select one of the following FPD files to build:[1] ");
253 do{
254 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
255 try {
256 String str = br.readLine();
257 if (str.trim().length() == 0) {
258 file = allFiles[0];
259 flag = false;
260 continue ;
261 }
262 int indexSelect = Integer.parseInt(str);
263 if (indexSelect <=0 || indexSelect > allFiles.length) {
264 System.out.print("Please enter a number between [1.." + allFiles.length + "]:[1] ");
265 continue ;
266 } else {
267 file = allFiles[indexSelect - 1];
268 flag = false;
269 continue ;
270 }
271 } catch (Exception e) {
272 System.out.print("Please enter a valid number:[1] ");
273 flag = true;
274 }
275 } while (flag);
276 } else if (fpdFiles.size() == 1) {
277 file = fpdFiles.toArray(new File[1])[0];
278 }
279 return file;
280 }
281
282
283 public void setType(String type) {
284 if (type.equalsIgnoreCase("clean") || type.equalsIgnoreCase("cleanall")) {
285 this.type = type.toLowerCase();
286 } else {
287 this.type = "all";
288 }
289 }
290
291 private void readTargetFile(){
292 try {
293 String targetFile = getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + targetFilename;
294
295 String[][] targetFileInfo = ConfigReader.parse(targetFile);
296
297 //
298 // Get ToolChain Info from target.txt
299 //
300 ToolChainInfo envToolChainInfo = new ToolChainInfo();
301 String str = getValue(ToolDefinitions.TARGET_KEY_TARGET, targetFileInfo);
302 if (str == null || str.trim().equals("")) {
303 envToolChainInfo.addTargets("*");
304 } else {
305 envToolChainInfo.addTargets(str);
306 }
307 str = getValue(ToolDefinitions.TARGET_KEY_TOOLCHAIN, targetFileInfo);
308 if (str == null || str.trim().equals("")) {
309 envToolChainInfo.addTagnames("*");
310 } else {
311 envToolChainInfo.addTagnames(str);
312 }
313 str = getValue(ToolDefinitions.TARGET_KEY_ARCH, targetFileInfo);
314 if (str == null || str.trim().equals("")) {
315 envToolChainInfo.addArchs("*");
316 } else {
317 envToolChainInfo.addArchs(str);
318 }
319 GlobalData.setToolChainEnvInfo(envToolChainInfo);
320
321 str = getValue(ToolDefinitions.TARGET_KEY_TOOLS_DEF, targetFileInfo);
322 if (str != null && str.trim().length() > 0) {
323 toolsDefFilename = str;
324 }
325
326 str = getValue(ToolDefinitions.TARGET_KEY_ACTIVE_PLATFORM, targetFileInfo);
327 if (str != null && ! str.trim().equals("")) {
328 if ( ! str.endsWith(".fpd")) {
329 throw new BuildException("FPD file's extension must be \"" + ToolDefinitions.FPD_EXTENSION + "\"!");
330 }
331 activePlatform = str;
332 }
333 }
334 catch (Exception ex) {
335 throw new BuildException(ex.getMessage());
336 }
337 }
338
339 private String getValue(String key, String[][] map) {
340 for (int i = 0; i < map[0].length; i++){
341 if (key.equalsIgnoreCase(map[0][i])) {
342 return map[1][i];
343 }
344 }
345 return null;
346 }
347 }