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(EdkLog
.EDK_DEBUG
);
114 EdkLog
.setLogLevel(getProject().getProperty("env.LOGLEVEL"));
115 EdkLog
.setLogger(logger
);
118 processFrameworkBuild();
119 }catch (BuildException e
) {
121 // Add more logic process here
123 BuildException buildException
= new BuildException(e
.getMessage());
124 buildException
.setStackTrace(e
.getStackTrace());
125 throw buildException
;
126 } catch (PcdAutogenException e
) {
128 // Add more logic process here
130 BuildException buildException
= new BuildException(e
.getMessage());
131 buildException
.setStackTrace(e
.getStackTrace());
132 throw buildException
;
133 } catch (AutoGenException e
) {
135 // Add more logic process here
137 BuildException buildException
= new BuildException(e
.getMessage());
138 buildException
.setStackTrace(e
.getStackTrace());
139 throw buildException
;
140 } catch (PlatformPcdPreprocessBuildException e
) {
142 // Add more logic process here
144 BuildException buildException
= new BuildException(e
.getMessage());
145 buildException
.setStackTrace(e
.getStackTrace());
146 throw buildException
;
147 } catch (GenBuildException e
) {
149 // Add more logic process here
151 BuildException buildException
= new BuildException(e
.getMessage());
152 buildException
.setStackTrace(e
.getStackTrace());
153 throw buildException
;
154 } catch (EdkException e
) {
156 // Add more logic process here
158 BuildException buildException
= new BuildException(e
.getMessage());
159 buildException
.setStackTrace(e
.getStackTrace());
160 throw buildException
;
164 private void processFrameworkBuild() throws EdkException
, GenBuildException
, AutoGenException
, PcdAutogenException
, PlatformPcdPreprocessBuildException
{
167 // Get current working dir
169 File dummyFile
= new File(".");
170 File cwd
= dummyFile
.getCanonicalFile();
171 File
[] files
= cwd
.listFiles();
174 // Scan current dir, and find out all .FPD and .MSA files
176 for (int i
= 0; i
< files
.length
; i
++) {
177 if (files
[i
].isFile()) {
178 if (files
[i
].getName().endsWith(ToolDefinitions
.FPD_EXTENSION
)) {
182 fpdFiles
.add(files
[i
]);
183 } else if (files
[i
].getName().endsWith(ToolDefinitions
.MSA_EXTENSION
)) {
187 msaFiles
.add(files
[i
]);
191 } catch (IOException ex
) {
192 BuildException buildException
= new BuildException("Scanning current directory error. \n" + ex
.getMessage());
193 buildException
.setStackTrace(ex
.getStackTrace());
194 throw buildException
;
198 // Import all system environment variables to ANT properties
200 importSystemEnvVariables();
203 // Read target.txt file
208 // Global Data initialization
210 File workspacePath
= new File(getProject().getProperty("WORKSPACE"));
211 getProject().setProperty("WORKSPACE_DIR", workspacePath
.getPath().replaceAll("(\\\\)", "/"));
212 GlobalData
.initInfo(getProject(), dbFilename
, workspacePath
.getPath(), toolsDefFilename
);
215 // If find MSA file and ACTIVE_PLATFORM is set, build the module;
217 // If without MSA file, and ACTIVE_PLATFORM is set, build the ACTIVE_PLATFORM.
218 // If ACTIVE_PLATFORM is not set, and only find one FPD file, build the platform;
219 // If find more than one FPD files, report error.
221 File buildFile
= null;
222 if (msaFiles
.size() > 0) {
223 if (activePlatform
== null) {
224 throw new BuildException("If trying to build a single module, please set ACTIVE_PLATFORM in file [" + targetFilename
+ "]. ");
227 // Build the single module
229 buildFile
= msaFiles
.toArray(new File
[1])[0];
230 } else if (activePlatform
!= null) {
231 buildFile
= new File(GlobalData
.getWorkspacePath() + File
.separatorChar
+ activePlatform
);
232 } else if (fpdFiles
.size() == 1) {
233 buildFile
= fpdFiles
.toArray(new File
[1])[0];
234 } else if (fpdFiles
.size() > 1) {
235 throw new BuildException("Found " + fpdFiles
.size() + " FPD files in current dir. ");
239 // If there is no build files or FPD files or MSA files, stop build
242 throw new BuildException("Can't find any FPD or MSA files in the current directory. ");
246 // Build every FPD files (PLATFORM build)
248 if (buildFile
.getName().endsWith(ToolDefinitions
.FPD_EXTENSION
)) {
249 EdkLog
.log(this, "Processing the FPD file [" + buildFile
.getPath() + "] ..>> ");
251 // Iff for platform build will enable the multi-thread if set in target.txt
253 if (multithread
&& type
.equalsIgnoreCase("all")) {
254 EdkLog
.log(this, "Multi-thread build is enabled. ");
255 FpdParserForThread fpdParserForThread
= new FpdParserForThread();
256 fpdParserForThread
.setType(type
);
257 fpdParserForThread
.setProject(getProject());
258 fpdParserForThread
.setFpdFile(buildFile
);
259 fpdParserForThread
.perform();
263 FpdParserTask fpdParserTask
= new FpdParserTask();
264 fpdParserTask
.setType(type
);
265 fpdParserTask
.setProject(getProject());
266 fpdParserTask
.setFpdFile(buildFile
);
267 fpdParserTask
.perform();
270 // If cleanall delete the Platform_build.xml
272 if (type
.compareTo("cleanall") == 0) {
273 File platformBuildFile
=
274 new File(getProject().getProperty("BUILD_DIR")
276 + getProject().getProperty("PLATFORM")
278 platformBuildFile
.deleteOnExit();
283 // Build every MSA files (SINGLE MODULE BUILD)
285 else if (buildFile
.getName().endsWith(ToolDefinitions
.MSA_EXTENSION
)) {
287 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Multi-Thead do not take effect on Stand-Alone (Single) module build. ");
290 File tmpFile
= new File(GlobalData
.getWorkspacePath() + File
.separatorChar
+ activePlatform
);
291 EdkLog
.log(this, "Using the FPD file [" + tmpFile
.getPath() + "] for the active platform. ");
293 File
[] moduleFiles
= msaFiles
.toArray(new File
[msaFiles
.size()]);
294 for (int i
= 0; i
< moduleFiles
.length
; ++i
) {
295 EdkLog
.log(this, "Processing the MSA file [" + moduleFiles
[i
].getPath() + "] ..>> ");
296 GenBuildTask genBuildTask
= new GenBuildTask();
297 genBuildTask
.setSingleModuleBuild(true);
298 genBuildTask
.setType(type
);
299 getProject().setProperty("PLATFORM_FILE", activePlatform
);
301 originalProperties
.put("PLATFORM_FILE", activePlatform
);
303 genBuildTask
.setProject(getProject());
304 genBuildTask
.setMsaFile(moduleFiles
[i
]);
305 genBuildTask
.perform();
311 Import system environment variables to ANT properties. If system variable
312 already exiests in ANT properties, skip it.
315 private void importSystemEnvVariables() {
316 Map
<String
, String
> sysProperties
= System
.getenv();
317 Iterator
<String
> iter
= sysProperties
.keySet().iterator();
318 while (iter
.hasNext()) {
319 String name
= iter
.next();
322 // If system environment variable is not in ANT properties, add it
324 if (getProject().getProperty(name
) == null) {
325 getProject().setProperty(name
, sysProperties
.get(name
));
329 Hashtable allProperties
= getProject().getProperties();
330 Iterator piter
= allProperties
.keySet().iterator();
331 while (piter
.hasNext()) {
332 String name
= (String
)piter
.next();
333 originalProperties
.put(new String(name
), new String((String
)allProperties
.get(name
)));
337 public void setType(String type
) {
338 this.type
= type
.toLowerCase();
341 private void readTargetFile() throws EdkException
{
342 String targetFile
= getProject().getProperty("WORKSPACE_DIR") + File
.separatorChar
+ targetFilename
;
344 String
[][] targetFileInfo
= ConfigReader
.parse(getProject(), targetFile
);
347 // Get ToolChain Info from target.txt
349 ToolChainInfo envToolChainInfo
= new ToolChainInfo();
350 String str
= getValue(ToolDefinitions
.TARGET_KEY_TARGET
, targetFileInfo
);
351 if (str
== null || str
.trim().equals("")) {
352 envToolChainInfo
.addTargets("*");
354 envToolChainInfo
.addTargets(str
);
356 str
= getValue(ToolDefinitions
.TARGET_KEY_TOOLCHAIN
, targetFileInfo
);
357 if (str
== null || str
.trim().equals("")) {
358 envToolChainInfo
.addTagnames("*");
360 envToolChainInfo
.addTagnames(str
);
362 str
= getValue(ToolDefinitions
.TARGET_KEY_ARCH
, targetFileInfo
);
363 if (str
== null || str
.trim().equals("")) {
364 envToolChainInfo
.addArchs("*");
366 envToolChainInfo
.addArchs(str
);
368 GlobalData
.setToolChainEnvInfo(envToolChainInfo
);
370 str
= getValue(ToolDefinitions
.TARGET_KEY_TOOLS_DEF
, targetFileInfo
);
371 if (str
!= null && str
.trim().length() > 0) {
372 toolsDefFilename
= str
;
375 str
= getValue(ToolDefinitions
.TARGET_KEY_ACTIVE_PLATFORM
, targetFileInfo
);
376 if (str
!= null && ! str
.trim().equals("")) {
377 if ( ! str
.endsWith(".fpd")) {
378 throw new BuildException("FPD file's extension must be \"" + ToolDefinitions
.FPD_EXTENSION
+ "\"!");
380 activePlatform
= str
;
383 str
= getValue(ToolDefinitions
.TARGET_KEY_MULTIPLE_THREAD
, targetFileInfo
);
384 if (str
!= null && str
.trim().equalsIgnoreCase("Enable")) {
388 str
= getValue(ToolDefinitions
.TARGET_KEY_MAX_CONCURRENT_THREAD_NUMBER
, targetFileInfo
);
390 // Need to check the # of threads iff multithread is enabled.
392 if ((multithread
) && (str
!= null )) {
394 int threadNum
= Integer
.parseInt(str
);
396 MAX_CONCURRENT_THREAD_NUMBER
= threadNum
;
398 } catch (Exception ex
) {
400 // Give a warning message, and keep the default value
402 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Incorrent number specified for MAX_CONCURRENT_THREAD_NUMBER in file [" + targetFilename
+ "]");
407 private String
getValue(String key
, String
[][] map
) {
408 for (int i
= 0; i
< map
[0].length
; i
++){
409 if (key
.equalsIgnoreCase(map
[0][i
])) {