2 This file is ANT task FpdParserTask.
4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 package org
.tianocore
.build
.fpd
;
16 import java
.util
.ArrayList
;
17 import java
.util
.Iterator
;
18 import java
.util
.LinkedHashMap
;
19 import java
.util
.LinkedHashSet
;
20 import java
.util
.List
;
24 import org
.apache
.tools
.ant
.BuildException
;
25 import org
.apache
.tools
.ant
.taskdefs
.Ant
;
26 import org
.apache
.xmlbeans
.XmlObject
;
28 import org
.tianocore
.build
.global
.GenBuildLogger
;
29 import org
.tianocore
.build
.global
.GlobalData
;
30 import org
.tianocore
.build
.global
.OutputManager
;
31 import org
.tianocore
.build
.id
.FpdModuleIdentification
;
32 import org
.tianocore
.build
.id
.ModuleIdentification
;
33 import org
.tianocore
.build
.FrameworkBuildTask
;
34 import org
.tianocore
.build
.GenBuildThread
;
35 import org
.tianocore
.common
.exception
.EdkException
;
36 import org
.tianocore
.common
.logger
.EdkLog
;
42 public class FpdParserForThread
extends FpdParserTask
{
44 public static Map
<FpdModuleIdentification
, GenBuildThread
> allThreads
= new LinkedHashMap
<FpdModuleIdentification
, GenBuildThread
>();
46 List
<String
> queueList
= new ArrayList
<String
>();
48 public static Object deamonSemaphore
= new Object();
50 static Object countSemaphore
= new Object();
52 public static int STATUS_DEPENDENCY_NOT_READY
= 1;
54 public static int STATUS_DEPENDENCY_READY
= 2;
56 public static int STATUS_START_RUN
= 3;
58 public static int STATUS_END_RUN
= 4;
60 private int currentQueueCode
= 0;
62 public static int currentRunNumber
= 0;
64 public static int totalNumber
= 0;
66 public static int remainNumber
= 0;
69 Public construct method. It is necessary for ANT task.
71 public FpdParserForThread() {
78 public void execute() throws BuildException
{
80 this.setTaskName(".........");
89 isUnified
= OutputManager
.getInstance().prepareBuildDir(getProject());
90 String buildDir
= getProject().getProperty("BUILD_DIR");
93 // For every Target and ToolChain
95 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
96 for (int i
= 0; i
< targetList
.length
; i
++) {
97 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
98 for(int j
= 0; j
< toolchainList
.length
; j
++) {
102 String ffsCommonDir
= buildDir
+ File
.separatorChar
103 + targetList
[i
] + "_"
105 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
107 getProject().setProperty("FV_DIR", fvDir
.getPath().replaceAll("(\\\\)", "/"));
112 genFvInfFiles(ffsCommonDir
);
119 String platformBuildFile
= buildDir
+ File
.separatorChar
+ platformId
.getName() + "_build.xml";
120 PlatformBuildFileGenerator fileGenerator
= new PlatformBuildFileGenerator(getProject(), outfiles
, fvs
, isUnified
, saq
, platformBuildFile
);
121 fileGenerator
.genBuildFile();
126 queueList
.add("libqueue");
128 String
[] validFv
= saq
.getFpdValidImageNames();
130 for (int i
= 0; i
< validFv
.length
; i
++) {
131 queueList
.add(validFv
[i
]);
134 Iterator
<String
> fvsNameIter
= fvs
.keySet().iterator();
136 while (fvsNameIter
.hasNext()) {
137 String fvName
= fvsNameIter
.next();
138 if (!isContain(validFv
, fvName
)) {
139 queueList
.add(fvName
);
144 // Ant call ${PLATFORM}_build.xml
147 ant
.setProject(getProject());
148 ant
.setAntfile(platformBuildFile
);
149 ant
.setTarget("prebuild");
150 ant
.setInheritAll(true);
154 remainNumber
= totalNumber
= allThreads
.size();
156 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, "Total thread number is " + totalNumber
);
157 GenBuildLogger
.setCacheEnable(true);
159 // Waiting for all thread over, or time out
161 synchronized (deamonSemaphore
) {
168 // If all modules are already built
170 if (currentQueueCode
>= queueList
.size()) {
174 int percentage
= (totalNumber
- remainNumber
) * 100 / totalNumber
;
175 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, percentage
+ "% finished. Has built " + (totalNumber
- remainNumber
) + " modules of " + totalNumber
+ " total. ");
177 Set
<FpdModuleIdentification
> currentQueueModules
= fvs
.get(queueList
.get(currentQueueCode
));
179 if (currentQueueModules
== null) {
183 Iterator
<FpdModuleIdentification
> currentIter
= currentQueueModules
.iterator();
185 GenBuildThread a
= null;
187 boolean existNoneReady
= false;
189 while (currentIter
.hasNext()) {
190 GenBuildThread item
= allThreads
.get(currentIter
.next());
191 if (item
.getStatus() == STATUS_DEPENDENCY_NOT_READY
) {
192 existNoneReady
= true;
193 } else if (item
.getStatus() == STATUS_DEPENDENCY_READY
) {
197 if (currentRunNumber
== FrameworkBuildTask
.MAX_CONCURRENT_THREAD_NUMBER
) {
205 // Exist ready thread
207 // EdkLog.log(this, EdkLog.EDK_ALWAYS, "Exist ready thread");
209 } else if (existNoneReady
&& currentRunNumber
== 0) {
211 // No active thread, but still have dependency not read thread
213 throw new BuildException("Existing some modules can't resolve depedencies. ");
214 } else if (!existNoneReady
&& currentRunNumber
== 0) {
216 // Current queue build finish, move to next
218 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, "Current queue build finish, move to next");
223 // active thread exist, but no ready thread
225 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, "Active thread exist, but no ready thread. Current running number is " + currentRunNumber
);
229 deamonSemaphore
.wait();
230 } catch (InterruptedException ex
) {
231 BuildException e
= new BuildException("Thread wait Error. \n" + ex
.getMessage());
232 e
.setStackTrace(ex
.getStackTrace());
237 GenBuildLogger
.setCacheEnable(false);
239 // call fvs, postbuild
242 ant
.setProject(getProject());
243 ant
.setAntfile(platformBuildFile
);
244 ant
.setTarget("fvs");
245 ant
.setInheritAll(true);
250 ant
.setProject(getProject());
251 ant
.setAntfile(platformBuildFile
);
252 ant
.setTarget("postbuild");
253 ant
.setInheritAll(true);
257 EdkLog
.flushLogToFile(new File(buildDir
+ File
.separatorChar
+ "build.log"));
263 Parse all modules listed in FPD file.
265 void parseModuleSAFiles() throws EdkException
{
267 Map
<FpdModuleIdentification
, Map
<String
, XmlObject
>> moduleSAs
= saq
.getFpdModules();
270 // For every Module lists in FPD file.
272 Set
<FpdModuleIdentification
> keys
= moduleSAs
.keySet();
273 Iterator
<FpdModuleIdentification
> iter
= keys
.iterator();
274 while (iter
.hasNext()) {
275 FpdModuleIdentification fpdModuleId
= iter
.next();
278 // Generate GenBuildThread
280 GenBuildThread genBuildThread
= new GenBuildThread();
281 genBuildThread
.setArch(fpdModuleId
.getArch());
282 genBuildThread
.setParentModuleId(null);
283 genBuildThread
.setModuleId(fpdModuleId
.getModule());
284 genBuildThread
.setProject(getProject());
286 Set
<FpdModuleIdentification
> dependencies
= new LinkedHashSet
<FpdModuleIdentification
>();
288 GlobalData
.registerFpdModuleSA(fpdModuleId
, moduleSAs
.get(fpdModuleId
));
291 // Add all dependent Library Instance
293 saq
.push(GlobalData
.getDoc(fpdModuleId
));
295 ModuleIdentification
[] libinstances
= saq
.getLibraryInstance(fpdModuleId
.getArch());
298 for (int i
= 0; i
< libinstances
.length
; i
++) {
299 FpdModuleIdentification libFpdModuleId
= new FpdModuleIdentification(libinstances
[i
], fpdModuleId
.getArch());
301 // Add to dependencies
303 dependencies
.add(libFpdModuleId
);
306 // Create thread for library instances
308 GenBuildThread liBuildThread
= new GenBuildThread();
309 liBuildThread
.setArch(fpdModuleId
.getArch());
310 liBuildThread
.setParentModuleId(fpdModuleId
.getModule());
311 liBuildThread
.setModuleId(libinstances
[i
]);
312 liBuildThread
.setProject(getProject());
313 liBuildThread
.setStatus(STATUS_DEPENDENCY_READY
);
314 liBuildThread
.setHighPriority(true);
315 allThreads
.put(libFpdModuleId
, liBuildThread
);
317 updateFvs("libqueue", libFpdModuleId
);
320 genBuildThread
.setDependencies(dependencies
);
321 // if (dependencies.size() == 0) {
322 genBuildThread
.setStatus(STATUS_DEPENDENCY_READY
);
325 allThreads
.put(fpdModuleId
, genBuildThread
);
328 // Put fpdModuleId to the corresponding FV
330 saq
.push(GlobalData
.getDoc(fpdModuleId
));
331 String fvBinding
= saq
.getModuleFvBindingKeyword();
333 fpdModuleId
.setFvBinding(fvBinding
);
334 updateFvs(fvBinding
, fpdModuleId
);
337 // Prepare for out put file name
339 ModuleIdentification moduleId
= fpdModuleId
.getModule();
341 String baseName
= saq
.getModuleOutputFileBasename();
343 if (baseName
== null) {
344 baseName
= moduleId
.getName();
346 outfiles
.put(fpdModuleId
, fpdModuleId
.getArch() + File
.separatorChar
347 + moduleId
.getGuid() + "-" + baseName
348 + getSuffix(moduleId
.getModuleType()));
351 // parse module build options, if any
353 GlobalData
.addModuleToolChainOption(fpdModuleId
, parseModuleBuildOptions(false));
354 GlobalData
.addModuleToolChainFamilyOption(fpdModuleId
, parseModuleBuildOptions(true));
359 private boolean isContain(String
[] list
, String item
) {
360 for (int i
= 0; i
< list
.length
; i
++) {
361 if (list
[i
].equalsIgnoreCase(item
)) {
368 public synchronized static void addCount() {
369 synchronized (countSemaphore
) {
374 public synchronized static void subCount() {
375 synchronized (countSemaphore
) {