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
;
17 import java
.io
.IOException
;
18 import java
.util
.Hashtable
;
19 import java
.util
.Iterator
;
20 import java
.util
.LinkedHashSet
;
24 import org
.apache
.tools
.ant
.BuildException
;
25 import org
.apache
.tools
.ant
.Task
;
26 import org
.tianocore
.build
.exception
.AutoGenException
;
27 import org
.tianocore
.build
.exception
.GenBuildException
;
28 import org
.tianocore
.build
.exception
.PcdAutogenException
;
29 import org
.tianocore
.build
.exception
.PlatformPcdPreprocessBuildException
;
30 import org
.tianocore
.build
.fpd
.FpdParserForThread
;
31 import org
.tianocore
.build
.fpd
.FpdParserTask
;
32 import org
.tianocore
.build
.global
.GenBuildLogger
;
33 import org
.tianocore
.build
.global
.GlobalData
;
34 import org
.tianocore
.build
.toolchain
.ConfigReader
;
35 import org
.tianocore
.build
.toolchain
.ToolChainInfo
;
36 import org
.tianocore
.common
.definitions
.ToolDefinitions
;
37 import org
.tianocore
.common
.exception
.EdkException
;
38 import org
.tianocore
.common
.logger
.EdkLog
;
42 <code>FrameworkBuildTask</code> is an Ant task. The main function is finding
43 and processing a FPD or MSA file, then building a platform or stand-alone
47 The task search current directory and find out all MSA and FPD files by file
48 extension. Base on ACTIVE_PLATFORM policy, decide to build a platform or a
49 stand-alone module. The ACTIVE_PLATFORM policy is:
52 1. More than one MSA files, report error;
53 2. Only one MSA file, but ACTIVE_PLATFORM is not specified, report error;
54 3. Only one MSA file, and ACTIVE_PLATFORM is also specified, build this module;
55 4. No MSA file, and ACTIVE_PLATFORM is specified, build the active platform;
56 5. No MSA file, no ACTIVE_PLATFORM, and no FPD file, report error;
57 6. No MSA file, no ACTIVE_PLATFORM, and only one FPD file, build the platform;
58 7. No MSA file, no ACTIVE_PLATFORM, and more than one FPD files, Report Error!
62 Framework build task also parse target file [${WORKSPACE_DIR}/Tools/Conf/target.txt].
63 And load all system environment variables to Ant properties.
66 The usage for this task is :
69 <FrameworkBuild type="cleanall" />
74 public class FrameworkBuildTask
extends Task
{
76 private Set
<File
> fpdFiles
= new LinkedHashSet
<File
>();
78 private Set
<File
> msaFiles
= new LinkedHashSet
<File
>();
81 // This is only for none-multi-thread build to reduce overriding message
83 public static Hashtable
<String
, String
> originalProperties
= new Hashtable
<String
, String
>();
85 String toolsDefFilename
= ToolDefinitions
.DEFAULT_TOOLS_DEF_FILE_PATH
;
87 String targetFilename
= ToolDefinitions
.TARGET_FILE_PATH
;
89 String dbFilename
= ToolDefinitions
.FRAMEWORK_DATABASE_FILE_PATH
;
91 String activePlatform
= null;
94 /// The flag to present current is multi-thread enabled
96 public static boolean multithread
= false;
99 /// The concurrent thread number
101 public static int MAX_CONCURRENT_THREAD_NUMBER
= 2;
104 /// there are three type: all (build), clean and cleanall
106 private String type
= "all";
108 public void execute() throws BuildException
{
112 GenBuildLogger logger
= new GenBuildLogger(getProject());
113 EdkLog
.setLogLevel(getProject().getProperty("env.LOGLEVEL"));
114 EdkLog
.setLogger(logger
);
117 processFrameworkBuild();
118 }catch (BuildException e
) {
120 // Add more logic process here
122 throw new BuildException(e
.getMessage());
123 } catch (PcdAutogenException e
) {
125 // Add more logic process here
127 throw new BuildException(e
.getMessage());
128 } catch (AutoGenException e
) {
130 // Add more logic process here
132 throw new BuildException(e
.getMessage());
133 } catch (PlatformPcdPreprocessBuildException e
) {
135 // Add more logic process here
137 throw new BuildException(e
.getMessage());
138 } catch (GenBuildException e
) {
140 // Add more logic process here
142 throw new BuildException(e
.getMessage());
143 } catch (EdkException e
) {
145 // Add more logic process here
147 throw new BuildException(e
.getMessage());
151 private void processFrameworkBuild() throws EdkException
, GenBuildException
, AutoGenException
, PcdAutogenException
, PlatformPcdPreprocessBuildException
{
154 // Get current working dir
156 File dummyFile
= new File(".");
157 File cwd
= dummyFile
.getCanonicalFile();
158 File
[] files
= cwd
.listFiles();
161 // Scan current dir, and find out all .FPD and .MSA files
163 for (int i
= 0; i
< files
.length
; i
++) {
164 if (files
[i
].isFile()) {
165 if (files
[i
].getName().endsWith(ToolDefinitions
.FPD_EXTENSION
)) {
169 fpdFiles
.add(files
[i
]);
170 } else if (files
[i
].getName().endsWith(ToolDefinitions
.MSA_EXTENSION
)) {
174 msaFiles
.add(files
[i
]);
178 } catch (IOException ex
) {
179 BuildException buildException
= new BuildException("Scanning current directory error. \n" + ex
.getMessage());
180 buildException
.setStackTrace(ex
.getStackTrace());
181 throw buildException
;
185 // Import all system environment variables to ANT properties
187 importSystemEnvVariables();
190 // Read target.txt file
195 // Global Data initialization
197 File workspacePath
= new File(getProject().getProperty("WORKSPACE"));
198 getProject().setProperty("WORKSPACE_DIR", workspacePath
.getPath().replaceAll("(\\\\)", "/"));
199 GlobalData
.initInfo(dbFilename
, workspacePath
.getPath(), toolsDefFilename
);
202 // If find MSA file and ACTIVE_PLATFORM is set, build the module;
204 // If without MSA file, and ACTIVE_PLATFORM is set, build the ACTIVE_PLATFORM.
205 // If ACTIVE_PLATFORM is not set, and only find one FPD file, build the platform;
206 // If find more than one FPD files, report error.
208 File buildFile
= null;
209 if (msaFiles
.size() > 1) {
210 throw new BuildException("Found " + msaFiles
.size() + " MSA files in current dir. ");
211 } else if (msaFiles
.size() == 1 && activePlatform
== null) {
212 throw new BuildException("If trying to build a single module, please set ACTIVE_PLATFORM in file [" + targetFilename
+ "]. ");
213 } else if (msaFiles
.size() == 1 && activePlatform
!= null) {
215 // Build the single module
217 buildFile
= msaFiles
.toArray(new File
[1])[0];
218 } else if (activePlatform
!= null) {
219 buildFile
= new File(GlobalData
.getWorkspacePath() + File
.separatorChar
+ activePlatform
);
220 } else if (fpdFiles
.size() == 1) {
221 buildFile
= fpdFiles
.toArray(new File
[1])[0];
222 } else if (fpdFiles
.size() > 1) {
223 throw new BuildException("Found " + fpdFiles
.size() + " FPD files in current dir. ");
227 // If there is no build files or FPD files or MSA files, stop build
230 throw new BuildException("Can't find any FPD or MSA files in the current directory. ");
234 // Build every FPD files (PLATFORM build)
236 if (buildFile
.getName().endsWith(ToolDefinitions
.FPD_EXTENSION
)) {
237 EdkLog
.log(this, "Processing the FPD file [" + buildFile
.getPath() + "] ..>> ");
239 // Iff for platform build will enable the multi-thread if set in target.txt
241 if (multithread
&& type
.equalsIgnoreCase("all")) {
242 EdkLog
.log(this, "Multi-thread build is enabled. ");
243 FpdParserForThread fpdParserForThread
= new FpdParserForThread();
244 fpdParserForThread
.setType(type
);
245 fpdParserForThread
.setProject(getProject());
246 fpdParserForThread
.setFpdFile(buildFile
);
247 fpdParserForThread
.perform();
251 FpdParserTask fpdParserTask
= new FpdParserTask();
252 fpdParserTask
.setType(type
);
253 fpdParserTask
.setProject(getProject());
254 fpdParserTask
.setFpdFile(buildFile
);
255 fpdParserTask
.perform();
258 // If cleanall delete the Platform_build.xml
260 if (type
.compareTo("cleanall") == 0) {
261 File platformBuildFile
=
262 new File(getProject().getProperty("BUILD_DIR")
264 + getProject().getProperty("PLATFORM")
266 platformBuildFile
.deleteOnExit();
271 // Build every MSA files (SINGLE MODULE BUILD)
273 else if (buildFile
.getName().endsWith(ToolDefinitions
.MSA_EXTENSION
)) {
275 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Multi-Thead do not take effect on Stand-Alone (Single) module build. ");
278 File tmpFile
= new File(GlobalData
.getWorkspacePath() + File
.separatorChar
+ activePlatform
);
279 EdkLog
.log(this, "Using the FPD file [" + tmpFile
.getPath() + "] for the active platform. ");
280 EdkLog
.log(this, "Processing the MSA file [" + buildFile
.getPath() + "] ..>> ");
281 GenBuildTask genBuildTask
= new GenBuildTask();
282 genBuildTask
.setSingleModuleBuild(true);
283 genBuildTask
.setType(type
);
284 getProject().setProperty("PLATFORM_FILE", activePlatform
);
286 originalProperties
.put("PLATFORM_FILE", activePlatform
);
288 genBuildTask
.setProject(getProject());
289 genBuildTask
.setMsaFile(buildFile
);
290 genBuildTask
.perform();
295 Import system environment variables to ANT properties. If system variable
296 already exiests in ANT properties, skip it.
299 private void importSystemEnvVariables() {
300 Map
<String
, String
> sysProperties
= System
.getenv();
301 Iterator
<String
> iter
= sysProperties
.keySet().iterator();
302 while (iter
.hasNext()) {
303 String name
= iter
.next();
306 // If system environment variable is not in ANT properties, add it
308 if (getProject().getProperty(name
) == null) {
309 getProject().setProperty(name
, sysProperties
.get(name
));
313 Hashtable allProperties
= getProject().getProperties();
314 Iterator piter
= allProperties
.keySet().iterator();
315 while (piter
.hasNext()) {
316 String name
= (String
)piter
.next();
317 originalProperties
.put(new String(name
), new String((String
)allProperties
.get(name
)));
321 public void setType(String type
) {
322 if (type
.equalsIgnoreCase("clean") || type
.equalsIgnoreCase("cleanall")) {
323 this.type
= type
.toLowerCase();
329 private void readTargetFile() throws EdkException
{
330 String targetFile
= getProject().getProperty("WORKSPACE_DIR") + File
.separatorChar
+ targetFilename
;
332 String
[][] targetFileInfo
= ConfigReader
.parse(targetFile
);
335 // Get ToolChain Info from target.txt
337 ToolChainInfo envToolChainInfo
= new ToolChainInfo();
338 String str
= getValue(ToolDefinitions
.TARGET_KEY_TARGET
, targetFileInfo
);
339 if (str
== null || str
.trim().equals("")) {
340 envToolChainInfo
.addTargets("*");
342 envToolChainInfo
.addTargets(str
);
344 str
= getValue(ToolDefinitions
.TARGET_KEY_TOOLCHAIN
, targetFileInfo
);
345 if (str
== null || str
.trim().equals("")) {
346 envToolChainInfo
.addTagnames("*");
348 envToolChainInfo
.addTagnames(str
);
350 str
= getValue(ToolDefinitions
.TARGET_KEY_ARCH
, targetFileInfo
);
351 if (str
== null || str
.trim().equals("")) {
352 envToolChainInfo
.addArchs("*");
354 envToolChainInfo
.addArchs(str
);
356 GlobalData
.setToolChainEnvInfo(envToolChainInfo
);
358 str
= getValue(ToolDefinitions
.TARGET_KEY_TOOLS_DEF
, targetFileInfo
);
359 if (str
!= null && str
.trim().length() > 0) {
360 toolsDefFilename
= str
;
363 str
= getValue(ToolDefinitions
.TARGET_KEY_ACTIVE_PLATFORM
, targetFileInfo
);
364 if (str
!= null && ! str
.trim().equals("")) {
365 if ( ! str
.endsWith(".fpd")) {
366 throw new BuildException("FPD file's extension must be \"" + ToolDefinitions
.FPD_EXTENSION
+ "\"!");
368 activePlatform
= str
;
371 str
= getValue(ToolDefinitions
.TARGET_KEY_MULTIPLE_THREAD
, targetFileInfo
);
372 if (str
!= null && str
.trim().equalsIgnoreCase("Enable")) {
376 str
= getValue(ToolDefinitions
.TARGET_KEY_MAX_CONCURRENT_THREAD_NUMBER
, targetFileInfo
);
379 int threadNum
= Integer
.parseInt(str
);
381 MAX_CONCURRENT_THREAD_NUMBER
= threadNum
;
383 } catch (Exception ex
) {
385 // Give a warning message, and keep the default value
387 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Incorrent number specified for MAX_CONCURRENT_THREAD_NUMBER in file [" + targetFilename
+ "]");
392 private String
getValue(String key
, String
[][] map
) {
393 for (int i
= 0; i
< map
[0].length
; i
++){
394 if (key
.equalsIgnoreCase(map
[0][i
])) {