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