2 This file is ANT task FpdParserTask.
4 FpdParserTask is used to parse FPD (Framework Platform Description) and generate
5 build.out.xml. It is for Package or Platform build use.
7 Copyright (c) 2006, Intel Corporation
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 package org
.tianocore
.build
.fpd
;
19 import java
.util
.ArrayList
;
20 import java
.util
.Iterator
;
21 import java
.util
.LinkedHashMap
;
22 import java
.util
.LinkedHashSet
;
23 import java
.util
.List
;
27 import org
.apache
.tools
.ant
.BuildException
;
28 import org
.apache
.tools
.ant
.taskdefs
.Ant
;
29 import org
.apache
.xmlbeans
.XmlObject
;
31 import org
.tianocore
.build
.global
.GlobalData
;
32 import org
.tianocore
.build
.global
.OutputManager
;
33 import org
.tianocore
.build
.id
.FpdModuleIdentification
;
34 import org
.tianocore
.build
.id
.ModuleIdentification
;
35 import org
.tianocore
.build
.FrameworkBuildTask
;
36 import org
.tianocore
.build
.GenBuildThread
;
37 import org
.tianocore
.common
.exception
.EdkException
;
40 <code>FpdParserTask</code> is an ANT task. The main function is parsing Framework
41 Platform Descritpion (FPD) XML file and generating its ANT build script for
42 corresponding platform.
44 <p>The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR
47 <p>The task generates ${PLATFORM}_build.xml file which will be called by top level
48 build.xml. The task also generate Fv.inf files (File is for Tool GenFvImage)
49 and flash definition file (File is for Tool FlashMap) if necessary. </p>
51 <p>FpdParserTask task stores all FPD information to GlobalData. And parse
52 tools definition file to set up compiler options for different Target and
53 different ToolChainTag. </p>
55 <p>The method parseFpdFile is also prepared for single module build. </p>
57 <p>The usage is (take NT32 Platform for example):</p>
60 <FPDParser platformName="Nt32" />
63 <p>The task will initialize all information through parsing Framework Database,
64 SPD, Tool chain configuration files. </p>
68 public class FpdParserForThread
extends FpdParserTask
{
70 public static Map
<FpdModuleIdentification
, GenBuildThread
> allThreads
= new LinkedHashMap
<FpdModuleIdentification
, GenBuildThread
>();
72 List
<String
> queueList
= new ArrayList
<String
>();
74 public static Object deamonSemaphore
= new Object();
76 static Object countSemaphore
= new Object();
78 public static int STATUS_DEPENDENCY_NOT_READY
= 1;
80 public static int STATUS_DEPENDENCY_READY
= 2;
82 public static int STATUS_START_RUN
= 3;
84 public static int STATUS_END_RUN
= 4;
86 private int currentQueueCode
= 0;
88 public static int currentRunNumber
= 0;
91 Public construct method. It is necessary for ANT task.
93 public FpdParserForThread() {
97 ANT task's entry method. The main steps is described as following:
100 <li>Initialize global information (Framework DB, SPD files and all MSA files
101 listed in SPD). This step will execute only once in whole build process;</li>
102 <li>Parse specified FPD file; </li>
103 <li>Generate FV.inf files; </li>
104 <li>Generate PlatformName_build.xml file for Flatform build; </li>
105 <li>Collect PCD information. </li>
108 @throws BuildException
109 Surface area is not valid.
111 public void execute() throws BuildException
{
120 isUnified
= OutputManager
.getInstance().prepareBuildDir(getProject());
123 // For every Target and ToolChain
125 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
126 for (int i
= 0; i
< targetList
.length
; i
++) {
127 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
128 for(int j
= 0; j
< toolchainList
.length
; j
++) {
132 String ffsCommonDir
= getProject().getProperty("BUILD_DIR") + File
.separatorChar
133 + targetList
[i
] + File
.separatorChar
135 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
137 getProject().setProperty("FV_DIR", fvDir
.getPath().replaceAll("(\\\\)", "/"));
142 genFvInfFiles(ffsCommonDir
);
149 PlatformBuildFileGenerator fileGenerator
= new PlatformBuildFileGenerator(getProject(), outfiles
, fvs
, isUnified
, saq
);
150 fileGenerator
.genBuildFile();
155 queueList
.add("libqueue");
157 String
[] validFv
= saq
.getFpdValidImageNames();
159 for (int i
= 0; i
< validFv
.length
; i
++) {
160 queueList
.add(validFv
[i
]);
163 Iterator
<String
> fvsNameIter
= fvs
.keySet().iterator();
165 while (fvsNameIter
.hasNext()) {
166 String fvName
= fvsNameIter
.next();
167 if (!isContain(validFv
, fvName
)) {
168 queueList
.add(fvName
);
173 // Ant call ${PLATFORM}_build.xml
176 ant
.setProject(getProject());
177 ant
.setAntfile(platformId
.getFpdFile().getParent() + File
.separatorChar
+ platformId
.getName() + "_build.xml");
178 ant
.setTarget("prebuild");
179 ant
.setInheritAll(true);
183 System
.out
.println("Task number is " + allThreads
.size());
186 // Waiting for all thread over, or time out
188 synchronized (deamonSemaphore
) {
195 // If all modules are already built
197 if (currentQueueCode
>= queueList
.size()) {
201 Set
<FpdModuleIdentification
> currentQueueModules
= fvs
.get(queueList
.get(currentQueueCode
));
203 if (currentQueueModules
== null) {
207 Iterator
<FpdModuleIdentification
> currentIter
= currentQueueModules
.iterator();
209 GenBuildThread a
= null;
211 boolean existNoneReady
= false;
213 while (currentIter
.hasNext()) {
214 GenBuildThread item
= allThreads
.get(currentIter
.next());
215 if (item
.getStatus() == STATUS_DEPENDENCY_NOT_READY
) {
216 existNoneReady
= true;
217 } else if (item
.getStatus() == STATUS_DEPENDENCY_READY
) {
221 if (currentRunNumber
== FrameworkBuildTask
.MAX_CONCURRENT_THREAD_NUMBER
) {
229 // Exist ready thread
231 System
.out
.println("## Exist ready thread");
233 } else if (existNoneReady
&& currentRunNumber
== 0) {
235 // No active thread, but still have dependency not read thread
237 throw new BuildException("Found can't resolve dependencies. ");
238 } else if (!existNoneReady
&& currentRunNumber
== 0) {
240 // Current queue build finish, move to next
242 System
.out
.println("## Current queue build finish, move to next");
247 // active thread exist, but no ready thread
249 System
.out
.println("## active thread exist, but no ready thread" + currentRunNumber
);
253 deamonSemaphore
.wait();
254 } catch (InterruptedException e
) {
261 // call fvs, postbuild
264 ant
.setProject(getProject());
265 ant
.setAntfile(platformId
.getFpdFile().getParent() + File
.separatorChar
+ platformId
.getName() + "_build.xml");
266 ant
.setTarget("fvs");
267 ant
.setInheritAll(true);
272 ant
.setProject(getProject());
273 ant
.setAntfile(platformId
.getFpdFile().getParent() + File
.separatorChar
+ platformId
.getName() + "_build.xml");
274 ant
.setTarget("postbuild");
275 ant
.setInheritAll(true);
283 Parse all modules listed in FPD file.
285 void parseModuleSAFiles() throws EdkException
{
287 Map
<FpdModuleIdentification
, Map
<String
, XmlObject
>> moduleSAs
= saq
.getFpdModules();
290 // For every Module lists in FPD file.
292 Set
<FpdModuleIdentification
> keys
= moduleSAs
.keySet();
293 Iterator
<FpdModuleIdentification
> iter
= keys
.iterator();
294 while (iter
.hasNext()) {
295 FpdModuleIdentification fpdModuleId
= iter
.next();
298 // Generate GenBuildThread
300 GenBuildThread genBuildThread
= new GenBuildThread();
301 genBuildThread
.setArch(fpdModuleId
.getArch());
302 genBuildThread
.setParentModuleId(null);
303 genBuildThread
.setModuleId(fpdModuleId
.getModule());
304 genBuildThread
.setProject(getProject());
306 Set
<FpdModuleIdentification
> dependencies
= new LinkedHashSet
<FpdModuleIdentification
>();
308 GlobalData
.registerFpdModuleSA(fpdModuleId
, moduleSAs
.get(fpdModuleId
));
311 // Add all dependent Library Instance
313 saq
.push(GlobalData
.getDoc(fpdModuleId
));
315 ModuleIdentification
[] libinstances
= saq
.getLibraryInstance(fpdModuleId
.getArch());
318 for (int i
= 0; i
< libinstances
.length
; i
++) {
319 FpdModuleIdentification libFpdModuleId
= new FpdModuleIdentification(libinstances
[i
], fpdModuleId
.getArch());
321 // Add to dependencies
323 dependencies
.add(libFpdModuleId
);
326 // Create thread for library instances
328 GenBuildThread liBuildThread
= new GenBuildThread();
329 liBuildThread
.setArch(fpdModuleId
.getArch());
330 liBuildThread
.setParentModuleId(fpdModuleId
.getModule());
331 liBuildThread
.setModuleId(libinstances
[i
]);
332 liBuildThread
.setProject(getProject());
333 liBuildThread
.setStatus(STATUS_DEPENDENCY_READY
);
334 liBuildThread
.setHighPriority(true);
335 allThreads
.put(libFpdModuleId
, liBuildThread
);
337 updateFvs("libqueue", libFpdModuleId
);
340 genBuildThread
.setDependencies(dependencies
);
341 // if (dependencies.size() == 0) {
342 genBuildThread
.setStatus(STATUS_DEPENDENCY_READY
);
345 allThreads
.put(fpdModuleId
, genBuildThread
);
348 // Put fpdModuleId to the corresponding FV
350 saq
.push(GlobalData
.getDoc(fpdModuleId
));
351 String fvBinding
= saq
.getModuleFvBindingKeyword();
353 fpdModuleId
.setFvBinding(fvBinding
);
354 updateFvs(fvBinding
, fpdModuleId
);
357 // Prepare for out put file name
359 ModuleIdentification moduleId
= fpdModuleId
.getModule();
361 String baseName
= saq
.getModuleOutputFileBasename();
363 if (baseName
== null) {
364 baseName
= moduleId
.getName();
366 outfiles
.put(fpdModuleId
, fpdModuleId
.getArch() + File
.separatorChar
367 + moduleId
.getGuid() + "-" + baseName
368 + getSuffix(moduleId
.getModuleType()));
371 // parse module build options, if any
373 GlobalData
.addModuleToolChainOption(fpdModuleId
, parseModuleBuildOptions(false));
374 GlobalData
.addModuleToolChainFamilyOption(fpdModuleId
, parseModuleBuildOptions(true));
379 private boolean isContain(String
[] list
, String item
) {
380 for (int i
= 0; i
< list
.length
; i
++) {
381 if (list
[i
].equalsIgnoreCase(item
)) {
388 public synchronized static void addCount() {
389 synchronized (countSemaphore
) {
394 public synchronized static void subCount() {
395 synchronized (countSemaphore
) {