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
.GlobalData
;
30 import org
.tianocore
.build
.toolchain
.ConfigReader
;
31 import org
.tianocore
.build
.toolchain
.ToolChainInfo
;
32 import org
.tianocore
.common
.definitions
.ToolDefinitions
;
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
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:
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.
57 Framework build task also parse target file [${WORKSPACE_DIR}/Tools/Conf/target.txt].
58 And load all system environment variables to Ant properties.
61 The usage for this task is :
64 <FrameworkBuild type="cleanall" />
69 public class FrameworkBuildTask
extends Task
{
71 private Set
<File
> buildFiles
= new LinkedHashSet
<File
>();
73 private Set
<File
> fpdFiles
= new LinkedHashSet
<File
>();
75 private Set
<File
> msaFiles
= new LinkedHashSet
<File
>();
78 // This is only for none-multi-thread build to reduce overriding message
80 public static Hashtable
<String
, String
> originalProperties
= new Hashtable
<String
, String
>();
82 String toolsDefFilename
= ToolDefinitions
.DEFAULT_TOOLS_DEF_FILE_PATH
;
84 String targetFilename
= ToolDefinitions
.TARGET_FILE_PATH
;
86 String dbFilename
= ToolDefinitions
.FRAMEWORK_DATABASE_FILE_PATH
;
88 String activePlatform
= null;
91 /// The flag to present current is multi-thread enabled
93 public static boolean multithread
= false;
96 /// The concurrent thread number
98 public static int MAX_CONCURRENT_THREAD_NUMBER
= 1;
101 /// there are three type: all (build), clean and cleanall
103 private String type
= "all";
105 public void execute() throws BuildException
{
107 // Seach build.xml -> .FPD -> .MSA file
111 // Gen Current Working Directory
113 File dummyFile
= new File(".");
114 File cwd
= dummyFile
.getCanonicalFile();
115 File
[] files
= cwd
.listFiles();
116 for (int i
= 0; i
< files
.length
; i
++) {
117 if (files
[i
].isFile()) {
118 if (files
[i
].getName().equalsIgnoreCase("build.xml")) {
120 // First, search build.xml, if found, ANT call it
122 buildFiles
.add(files
[i
]);
124 } else if (files
[i
].getName().endsWith(ToolDefinitions
.FPD_EXTENSION
)) {
126 // Second, search FPD file, if found, build it
128 fpdFiles
.add(files
[i
]);
129 } else if (files
[i
].getName().endsWith(ToolDefinitions
.MSA_EXTENSION
)) {
131 // Third, search MSA file, if found, build it
133 msaFiles
.add(files
[i
]);
137 } catch (Exception e
) {
138 throw new BuildException(e
.getMessage());
142 // Deal with all environment variable (Add them to properties)
144 backupSystemProperties();
147 // Read target.txt file
152 // Global Data initialization
154 File workspacePath
= new File(getProject().getProperty("WORKSPACE"));
155 getProject().setProperty("WORKSPACE_DIR", workspacePath
.getPath().replaceAll("(\\\\)", "/"));
156 GlobalData
.initInfo(dbFilename
, workspacePath
.getPath(), toolsDefFilename
);
159 // If find MSA file and ACTIVE_PLATFORM is set, build the module;
161 // If without MSA file, and ACTIVE_PLATFORM is set, build the ACTIVE_PLATFORM.
162 // If ACTIVE_PLATFORM is not set, and only find one FPD file, build the platform;
163 // If find more than one FPD files, let user select one.
165 File buildFile
= null;
166 if (msaFiles
.size() > 1) {
167 throw new BuildException("Having more than one MSA file in a directory is not allowed!");
168 } else if (msaFiles
.size() == 1 && activePlatform
== null) {
169 throw new BuildException("If trying to build a single module, please set ACTIVE_PLATFORM in file [" + targetFilename
+ "]. ");
170 } else if (msaFiles
.size() == 1 && activePlatform
!= null) {
172 // Build the single module
174 buildFile
= msaFiles
.toArray(new File
[1])[0];
175 } else if (activePlatform
!= null) {
176 buildFile
= new File(GlobalData
.getWorkspacePath() + File
.separatorChar
+ activePlatform
);
177 } else if (fpdFiles
.size() == 1) {
178 buildFile
= fpdFiles
.toArray(new File
[1])[0];
179 } else if (fpdFiles
.size() > 1) {
180 buildFile
= intercommuniteWithUser();
183 // If there is no build files or FPD files or MSA files, stop build
186 throw new BuildException("Can't find any FPD or MSA files in the current directory. ");
190 // Build every FPD files (PLATFORM build)
192 if (buildFile
.getName().endsWith(ToolDefinitions
.FPD_EXTENSION
)) {
193 System
.out
.println("Processing the FPD file [" + buildFile
.getPath() + "] ..>> ");
195 // Iff for platform build will enable the multi-thread if set in target.txt
197 if (multithread
&& type
.equalsIgnoreCase("all")) {
198 System
.out
.println("Multi-thread build is enabled. ");
199 FpdParserForThread fpdParserForThread
= new FpdParserForThread();
200 fpdParserForThread
.setType(type
);
201 fpdParserForThread
.setProject(getProject());
202 fpdParserForThread
.setFpdFile(buildFile
);
203 fpdParserForThread
.execute();
207 FpdParserTask fpdParserTask
= new FpdParserTask();
208 fpdParserTask
.setType(type
);
209 fpdParserTask
.setProject(getProject());
210 fpdParserTask
.setFpdFile(buildFile
);
211 fpdParserTask
.execute();
214 // If cleanall delete the Platform_build.xml
216 if (type
.compareTo("cleanall") == 0) {
217 File platformBuildFile
=
218 new File(getProject().getProperty("PLATFORM_DIR")
220 + getProject().getProperty("PLATFORM")
222 platformBuildFile
.deleteOnExit();
227 // Build every MSA files (SINGLE MODULE BUILD)
229 else if (buildFile
.getName().endsWith(ToolDefinitions
.MSA_EXTENSION
)) {
230 File tmpFile
= new File(GlobalData
.getWorkspacePath() + File
.separatorChar
+ activePlatform
);
231 System
.out
.println("Using the FPD file [" + tmpFile
.getPath() + "] for the active platform. ");
232 System
.out
.println("Processing the MSA file [" + buildFile
.getPath() + "] ..>> ");
233 GenBuildTask genBuildTask
= new GenBuildTask();
234 genBuildTask
.setSingleModuleBuild(true);
235 genBuildTask
.setType(type
);
236 getProject().setProperty("PLATFORM_FILE", activePlatform
);
238 originalProperties
.put("PLATFORM_FILE", activePlatform
);
240 genBuildTask
.setProject(getProject());
241 genBuildTask
.setMsaFile(buildFile
);
242 genBuildTask
.execute();
247 Transfer system environment variables to ANT properties. If system variable
248 already exiests in ANT properties, skip it.
251 private void backupSystemProperties() {
252 Map
<String
, String
> sysProperties
= System
.getenv();
253 Iterator
<String
> iter
= sysProperties
.keySet().iterator();
254 while (iter
.hasNext()) {
255 String name
= iter
.next();
258 // If system environment variable is not in ANT properties, add it
260 if (getProject().getProperty(name
) == null) {
261 getProject().setProperty(name
, sysProperties
.get(name
));
265 Hashtable allProperties
= getProject().getProperties();
266 Iterator piter
= allProperties
.keySet().iterator();
267 while (piter
.hasNext()) {
268 String name
= (String
)piter
.next();
269 originalProperties
.put(new String(name
), new String((String
)allProperties
.get(name
)));
274 private File
intercommuniteWithUser(){
276 if (fpdFiles
.size() > 1) {
277 File
[] allFiles
= new File
[fpdFiles
.size()];
279 Iterator
<File
> iter
= fpdFiles
.iterator();
280 while (iter
.hasNext()) {
281 allFiles
[index
] = iter
.next();
285 System
.out
.println("Finding " + allFiles
.length
+ " FPD files: ");
286 for (int i
= 0; i
< allFiles
.length
; i
++) {
287 System
.out
.println("[" + (i
+ 1) + "]: " + allFiles
[i
].getName());
291 System
.out
.print("Please select one of the following FPD files to build:[1] ");
293 BufferedReader br
= new BufferedReader(new InputStreamReader(System
.in
));
295 String str
= br
.readLine();
296 if (str
.trim().length() == 0) {
301 int indexSelect
= Integer
.parseInt(str
);
302 if (indexSelect
<=0 || indexSelect
> allFiles
.length
) {
303 System
.out
.print("Please enter a number between [1.." + allFiles
.length
+ "]:[1] ");
306 file
= allFiles
[indexSelect
- 1];
310 } catch (Exception e
) {
311 System
.out
.print("Please enter a valid number:[1] ");
315 } else if (fpdFiles
.size() == 1) {
316 file
= fpdFiles
.toArray(new File
[1])[0];
322 public void setType(String type
) {
323 if (type
.equalsIgnoreCase("clean") || type
.equalsIgnoreCase("cleanall")) {
324 this.type
= type
.toLowerCase();
330 private void readTargetFile(){
332 String targetFile
= getProject().getProperty("WORKSPACE_DIR") + File
.separatorChar
+ targetFilename
;
334 String
[][] targetFileInfo
= ConfigReader
.parse(targetFile
);
337 // Get ToolChain Info from target.txt
339 ToolChainInfo envToolChainInfo
= new ToolChainInfo();
340 String str
= getValue(ToolDefinitions
.TARGET_KEY_TARGET
, targetFileInfo
);
341 if (str
== null || str
.trim().equals("")) {
342 envToolChainInfo
.addTargets("*");
344 envToolChainInfo
.addTargets(str
);
346 str
= getValue(ToolDefinitions
.TARGET_KEY_TOOLCHAIN
, targetFileInfo
);
347 if (str
== null || str
.trim().equals("")) {
348 envToolChainInfo
.addTagnames("*");
350 envToolChainInfo
.addTagnames(str
);
352 str
= getValue(ToolDefinitions
.TARGET_KEY_ARCH
, targetFileInfo
);
353 if (str
== null || str
.trim().equals("")) {
354 envToolChainInfo
.addArchs("*");
356 envToolChainInfo
.addArchs(str
);
358 GlobalData
.setToolChainEnvInfo(envToolChainInfo
);
360 str
= getValue(ToolDefinitions
.TARGET_KEY_TOOLS_DEF
, targetFileInfo
);
361 if (str
!= null && str
.trim().length() > 0) {
362 toolsDefFilename
= str
;
365 str
= getValue(ToolDefinitions
.TARGET_KEY_ACTIVE_PLATFORM
, targetFileInfo
);
366 if (str
!= null && ! str
.trim().equals("")) {
367 if ( ! str
.endsWith(".fpd")) {
368 throw new BuildException("FPD file's extension must be \"" + ToolDefinitions
.FPD_EXTENSION
+ "\"!");
370 activePlatform
= str
;
373 str
= getValue("MULTIPLE_THREAD", targetFileInfo
);
374 if (str
!= null && str
.trim().equalsIgnoreCase("Enable")) {
378 str
= getValue("MAX_CONCURRENT_THREAD_NUMBER", targetFileInfo
);
381 int threadNum
= Integer
.parseInt(str
);
383 MAX_CONCURRENT_THREAD_NUMBER
= threadNum
;
385 } catch (Exception enuma
) {
390 catch (Exception ex
) {
391 throw new BuildException(ex
.getMessage());
395 private String
getValue(String key
, String
[][] map
) {
396 for (int i
= 0; i
< map
[0].length
; i
++){
397 if (key
.equalsIgnoreCase(map
[0][i
])) {