1 /** @file FrameworkBuildTask.java
3 The file is ANT task to find MSA or FPD file and build them.
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.
14 package org
.tianocore
.build
;
16 import java
.io
.BufferedReader
;
18 import java
.io
.InputStreamReader
;
19 import java
.util
.Hashtable
;
20 import java
.util
.Iterator
;
21 import java
.util
.LinkedHashSet
;
25 import org
.apache
.tools
.ant
.BuildException
;
26 import org
.apache
.tools
.ant
.Task
;
27 import org
.tianocore
.build
.fpd
.FpdParserForThread
;
28 import org
.tianocore
.build
.fpd
.FpdParserTask
;
29 import org
.tianocore
.build
.global
.GenBuildLogger
;
30 import org
.tianocore
.build
.global
.GlobalData
;
31 import org
.tianocore
.build
.toolchain
.ConfigReader
;
32 import org
.tianocore
.build
.toolchain
.ToolChainInfo
;
33 import org
.tianocore
.common
.definitions
.ToolDefinitions
;
34 import org
.tianocore
.common
.logger
.EdkLog
;
38 <code>FrameworkBuildTask</code> is an Ant task. The main function is finding
39 and processing a FPD or MSA file, then building a platform or stand-alone
43 The task search current directory and find out all MSA and FPD files by file
44 extension. Base on ACTIVE_PLATFORM policy, decide to build a platform or a
45 stand-alone module. The ACTIVE_PLATFORM policy is:
48 1. More than one MSA files, report error;
49 2. Only one MSA file, but ACTIVE_PLATFORM is not specified, report error;
50 3. Only one MSA file, and ACTIVE_PLATFORM is also specified, build this module;
51 4. No MSA file, and ACTIVE_PLATFORM is specified, build the active platform;
52 5. No MSA file, no ACTIVE_PLATFORM, and no FPD file, report error;
53 6. No MSA file, no ACTIVE_PLATFORM, and only one FPD file, build the platform;
54 7. No MSA file, no ACTIVE_PLATFORM, and more than one FPD files, list all platform
55 and let user choose one.
59 Framework build task also parse target file [${WORKSPACE_DIR}/Tools/Conf/target.txt].
60 And load all system environment variables to Ant properties.
63 The usage for this task is :
66 <FrameworkBuild type="cleanall" />
71 public class FrameworkBuildTask
extends Task
{
73 private Set
<File
> buildFiles
= new LinkedHashSet
<File
>();
75 private Set
<File
> fpdFiles
= new LinkedHashSet
<File
>();
77 private Set
<File
> msaFiles
= new LinkedHashSet
<File
>();
80 // This is only for none-multi-thread build to reduce overriding message
82 public static Hashtable
<String
, String
> originalProperties
= new Hashtable
<String
, String
>();
84 String toolsDefFilename
= ToolDefinitions
.DEFAULT_TOOLS_DEF_FILE_PATH
;
86 String targetFilename
= ToolDefinitions
.TARGET_FILE_PATH
;
88 String dbFilename
= ToolDefinitions
.FRAMEWORK_DATABASE_FILE_PATH
;
90 String activePlatform
= null;
93 /// The flag to present current is multi-thread enabled
95 public static boolean multithread
= false;
98 /// The concurrent thread number
100 public static int MAX_CONCURRENT_THREAD_NUMBER
= 1;
103 /// there are three type: all (build), clean and cleanall
105 private String type
= "all";
107 public void execute() throws BuildException
{
111 GenBuildLogger logger
= new GenBuildLogger(getProject());
112 EdkLog
.setLogLevel(getProject().getProperty("env.LOGLEVEL"));
113 EdkLog
.setLogger(logger
);
116 // Seach build.xml -> .FPD -> .MSA file
120 // Gen Current Working Directory
122 File dummyFile
= new File(".");
123 File cwd
= dummyFile
.getCanonicalFile();
124 File
[] files
= cwd
.listFiles();
125 for (int i
= 0; i
< files
.length
; i
++) {
126 if (files
[i
].isFile()) {
127 if (files
[i
].getName().equalsIgnoreCase("build.xml")) {
129 // First, search build.xml, if found, ANT call it
131 buildFiles
.add(files
[i
]);
133 } else if (files
[i
].getName().endsWith(ToolDefinitions
.FPD_EXTENSION
)) {
135 // Second, search FPD file, if found, build it
137 fpdFiles
.add(files
[i
]);
138 } else if (files
[i
].getName().endsWith(ToolDefinitions
.MSA_EXTENSION
)) {
140 // Third, search MSA file, if found, build it
142 msaFiles
.add(files
[i
]);
146 } catch (Exception e
) {
147 throw new BuildException(e
.getMessage());
151 // Deal with all environment variable (Add them to properties)
153 backupSystemProperties();
156 // Read target.txt file
161 // Global Data initialization
163 File workspacePath
= new File(getProject().getProperty("WORKSPACE"));
164 getProject().setProperty("WORKSPACE_DIR", workspacePath
.getPath().replaceAll("(\\\\)", "/"));
165 GlobalData
.initInfo(dbFilename
, workspacePath
.getPath(), toolsDefFilename
);
168 // If find MSA file and ACTIVE_PLATFORM is set, build the module;
170 // If without MSA file, and ACTIVE_PLATFORM is set, build the ACTIVE_PLATFORM.
171 // If ACTIVE_PLATFORM is not set, and only find one FPD file, build the platform;
172 // If find more than one FPD files, let user select one.
174 File buildFile
= null;
175 if (msaFiles
.size() > 1) {
176 throw new BuildException("Having more than one MSA file in a directory is not allowed!");
177 } else if (msaFiles
.size() == 1 && activePlatform
== null) {
178 throw new BuildException("If trying to build a single module, please set ACTIVE_PLATFORM in file [" + targetFilename
+ "]. ");
179 } else if (msaFiles
.size() == 1 && activePlatform
!= null) {
181 // Build the single module
183 buildFile
= msaFiles
.toArray(new File
[1])[0];
184 } else if (activePlatform
!= null) {
185 buildFile
= new File(GlobalData
.getWorkspacePath() + File
.separatorChar
+ activePlatform
);
186 } else if (fpdFiles
.size() == 1) {
187 buildFile
= fpdFiles
.toArray(new File
[1])[0];
188 } else if (fpdFiles
.size() > 1) {
189 buildFile
= intercommuniteWithUser();
192 // If there is no build files or FPD files or MSA files, stop build
195 throw new BuildException("Can't find any FPD or MSA files in the current directory. ");
199 // Build every FPD files (PLATFORM build)
201 if (buildFile
.getName().endsWith(ToolDefinitions
.FPD_EXTENSION
)) {
202 System
.out
.println("Processing the FPD file [" + buildFile
.getPath() + "] ..>> ");
204 // Iff for platform build will enable the multi-thread if set in target.txt
206 if (multithread
&& type
.equalsIgnoreCase("all")) {
207 System
.out
.println("Multi-thread build is enabled. ");
208 FpdParserForThread fpdParserForThread
= new FpdParserForThread();
209 fpdParserForThread
.setType(type
);
210 fpdParserForThread
.setProject(getProject());
211 fpdParserForThread
.setFpdFile(buildFile
);
212 fpdParserForThread
.perform();
216 FpdParserTask fpdParserTask
= new FpdParserTask();
217 fpdParserTask
.setType(type
);
218 fpdParserTask
.setProject(getProject());
219 fpdParserTask
.setFpdFile(buildFile
);
220 fpdParserTask
.perform();
223 // If cleanall delete the Platform_build.xml
225 if (type
.compareTo("cleanall") == 0) {
226 File platformBuildFile
=
227 new File(getProject().getProperty("PLATFORM_DIR")
229 + getProject().getProperty("PLATFORM")
231 platformBuildFile
.deleteOnExit();
236 // Build every MSA files (SINGLE MODULE BUILD)
238 else if (buildFile
.getName().endsWith(ToolDefinitions
.MSA_EXTENSION
)) {
239 File tmpFile
= new File(GlobalData
.getWorkspacePath() + File
.separatorChar
+ activePlatform
);
240 System
.out
.println("Using the FPD file [" + tmpFile
.getPath() + "] for the active platform. ");
241 System
.out
.println("Processing the MSA file [" + buildFile
.getPath() + "] ..>> ");
242 GenBuildTask genBuildTask
= new GenBuildTask();
243 genBuildTask
.setSingleModuleBuild(true);
244 genBuildTask
.setType(type
);
245 getProject().setProperty("PLATFORM_FILE", activePlatform
);
247 originalProperties
.put("PLATFORM_FILE", activePlatform
);
249 genBuildTask
.setProject(getProject());
250 genBuildTask
.setMsaFile(buildFile
);
251 genBuildTask
.perform();
256 Transfer system environment variables to ANT properties. If system variable
257 already exiests in ANT properties, skip it.
260 private void backupSystemProperties() {
261 Map
<String
, String
> sysProperties
= System
.getenv();
262 Iterator
<String
> iter
= sysProperties
.keySet().iterator();
263 while (iter
.hasNext()) {
264 String name
= iter
.next();
267 // If system environment variable is not in ANT properties, add it
269 if (getProject().getProperty(name
) == null) {
270 getProject().setProperty(name
, sysProperties
.get(name
));
274 Hashtable allProperties
= getProject().getProperties();
275 Iterator piter
= allProperties
.keySet().iterator();
276 while (piter
.hasNext()) {
277 String name
= (String
)piter
.next();
278 originalProperties
.put(new String(name
), new String((String
)allProperties
.get(name
)));
282 private File
intercommuniteWithUser(){
284 if (fpdFiles
.size() > 1) {
285 File
[] allFiles
= new File
[fpdFiles
.size()];
287 Iterator
<File
> iter
= fpdFiles
.iterator();
288 while (iter
.hasNext()) {
289 allFiles
[index
] = iter
.next();
293 System
.out
.println("Finding " + allFiles
.length
+ " FPD files: ");
294 for (int i
= 0; i
< allFiles
.length
; i
++) {
295 System
.out
.println("[" + (i
+ 1) + "]: " + allFiles
[i
].getName());
299 System
.out
.print("Please select one of the following FPD files to build:[1] ");
301 BufferedReader br
= new BufferedReader(new InputStreamReader(System
.in
));
303 String str
= br
.readLine();
304 if (str
.trim().length() == 0) {
309 int indexSelect
= Integer
.parseInt(str
);
310 if (indexSelect
<=0 || indexSelect
> allFiles
.length
) {
311 System
.out
.print("Please enter a number between [1.." + allFiles
.length
+ "]:[1] ");
314 file
= allFiles
[indexSelect
- 1];
318 } catch (Exception e
) {
319 System
.out
.print("Please enter a valid number:[1] ");
323 } else if (fpdFiles
.size() == 1) {
324 file
= fpdFiles
.toArray(new File
[1])[0];
330 public void setType(String type
) {
331 if (type
.equalsIgnoreCase("clean") || type
.equalsIgnoreCase("cleanall")) {
332 this.type
= type
.toLowerCase();
338 private void readTargetFile(){
340 String targetFile
= getProject().getProperty("WORKSPACE_DIR") + File
.separatorChar
+ targetFilename
;
342 String
[][] targetFileInfo
= ConfigReader
.parse(targetFile
);
345 // Get ToolChain Info from target.txt
347 ToolChainInfo envToolChainInfo
= new ToolChainInfo();
348 String str
= getValue(ToolDefinitions
.TARGET_KEY_TARGET
, targetFileInfo
);
349 if (str
== null || str
.trim().equals("")) {
350 envToolChainInfo
.addTargets("*");
352 envToolChainInfo
.addTargets(str
);
354 str
= getValue(ToolDefinitions
.TARGET_KEY_TOOLCHAIN
, targetFileInfo
);
355 if (str
== null || str
.trim().equals("")) {
356 envToolChainInfo
.addTagnames("*");
358 envToolChainInfo
.addTagnames(str
);
360 str
= getValue(ToolDefinitions
.TARGET_KEY_ARCH
, targetFileInfo
);
361 if (str
== null || str
.trim().equals("")) {
362 envToolChainInfo
.addArchs("*");
364 envToolChainInfo
.addArchs(str
);
366 GlobalData
.setToolChainEnvInfo(envToolChainInfo
);
368 str
= getValue(ToolDefinitions
.TARGET_KEY_TOOLS_DEF
, targetFileInfo
);
369 if (str
!= null && str
.trim().length() > 0) {
370 toolsDefFilename
= str
;
373 str
= getValue(ToolDefinitions
.TARGET_KEY_ACTIVE_PLATFORM
, targetFileInfo
);
374 if (str
!= null && ! str
.trim().equals("")) {
375 if ( ! str
.endsWith(".fpd")) {
376 throw new BuildException("FPD file's extension must be \"" + ToolDefinitions
.FPD_EXTENSION
+ "\"!");
378 activePlatform
= str
;
381 str
= getValue(ToolDefinitions
.TARGET_KEY_MULTIPLE_THREAD
, targetFileInfo
);
382 if (str
!= null && str
.trim().equalsIgnoreCase("Enable")) {
386 str
= getValue(ToolDefinitions
.TARGET_KEY_MAX_CONCURRENT_THREAD_NUMBER
, targetFileInfo
);
389 int threadNum
= Integer
.parseInt(str
);
391 MAX_CONCURRENT_THREAD_NUMBER
= threadNum
;
393 } catch (Exception enuma
) {
398 catch (Exception ex
) {
399 throw new BuildException(ex
.getMessage());
403 private String
getValue(String key
, String
[][] map
) {
404 for (int i
= 0; i
< map
[0].length
; i
++){
405 if (key
.equalsIgnoreCase(map
[0][i
])) {