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 final static Object deamonSemaphore
= new Object();
50 private final 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;
68 public static ThreadGroup tg
= new ThreadGroup("Framework");
70 public static FpdModuleIdentification errorModule
= null;
73 Public construct method. It is necessary for ANT task.
75 public FpdParserForThread() {
82 public void execute() throws BuildException
{
84 this.setTaskName(".........");
93 isUnified
= OutputManager
.getInstance().prepareBuildDir(getProject());
94 String buildDir
= getProject().getProperty("BUILD_DIR");
97 // For every Target and ToolChain
99 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
100 for (int i
= 0; i
< targetList
.length
; i
++) {
101 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
102 for(int j
= 0; j
< toolchainList
.length
; j
++) {
106 String ffsCommonDir
= buildDir
+ File
.separatorChar
107 + targetList
[i
] + "_"
109 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
111 getProject().setProperty("FV_DIR", fvDir
.getPath().replaceAll("(\\\\)", "/"));
116 genFvInfFiles(ffsCommonDir
);
123 String platformBuildFile
= buildDir
+ File
.separatorChar
+ platformId
.getName() + "_build.xml";
124 PlatformBuildFileGenerator fileGenerator
= new PlatformBuildFileGenerator(getProject(), outfiles
, fvs
, isUnified
, saq
, platformBuildFile
);
125 fileGenerator
.genBuildFile();
130 queueList
.add("libqueue");
132 String
[] validFv
= saq
.getFpdValidImageNames();
134 for (int i
= 0; i
< validFv
.length
; i
++) {
135 queueList
.add(validFv
[i
]);
138 Iterator
<String
> fvsNameIter
= fvs
.keySet().iterator();
140 while (fvsNameIter
.hasNext()) {
141 String fvName
= fvsNameIter
.next();
142 if (!isContain(validFv
, fvName
)) {
143 queueList
.add(fvName
);
148 // Ant call ${PLATFORM}_build.xml
151 ant
.setProject(getProject());
152 ant
.setAntfile(platformBuildFile
);
153 ant
.setTarget("prebuild");
154 ant
.setInheritAll(true);
158 remainNumber
= totalNumber
= allThreads
.size();
160 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, "Total thread number is " + totalNumber
);
161 GenBuildLogger
.setCacheEnable(true);
163 // Waiting for all thread over, or time out
165 synchronized (deamonSemaphore
) {
169 // If all modules are already built
171 if (currentQueueCode
>= queueList
.size()) {
175 int percentage
= (totalNumber
- remainNumber
) * 100 / totalNumber
;
176 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, percentage
+ "% finished. Has built " + (totalNumber
- remainNumber
) + " modules of " + totalNumber
+ " total. ");
178 Set
<FpdModuleIdentification
> currentQueueModules
= fvs
.get(queueList
.get(currentQueueCode
));
180 if (currentQueueModules
== null) {
184 Iterator
<FpdModuleIdentification
> currentIter
= currentQueueModules
.iterator();
186 GenBuildThread a
= null;
188 boolean existNoneReady
= false;
190 while (currentIter
.hasNext()) {
191 GenBuildThread item
= allThreads
.get(currentIter
.next());
192 if (item
.getStatus() == STATUS_DEPENDENCY_NOT_READY
) {
193 existNoneReady
= true;
194 } else if (item
.getStatus() == STATUS_DEPENDENCY_READY
) {
198 if (currentRunNumber
== FrameworkBuildTask
.MAX_CONCURRENT_THREAD_NUMBER
) {
206 // Exist ready thread
208 // EdkLog.log(this, EdkLog.EDK_ALWAYS, "Exist ready thread");
210 } else if (existNoneReady
&& currentRunNumber
== 0) {
212 // No active thread, but still have dependency not read thread
214 throw new BuildException("Existing some modules can't resolve depedencies. ");
215 } else if (!existNoneReady
&& currentRunNumber
== 0) {
217 // Current queue build finish, move to next
219 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, "Current queue build finish, move to next");
224 // active thread exist, but no ready thread
226 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, "Active thread exist, but no ready thread. Current running number is " + currentRunNumber
);
230 deamonSemaphore
.wait();
233 // if find error. Let other threads to finish
235 if (errorModule
!= null) {
236 while (currentRunNumber
> 0) {
237 deamonSemaphore
.wait();
240 GenBuildLogger
.setCacheEnable(false);
242 GenBuildLogger
.flushErrorModuleLog(errorModule
);
244 EdkLog
.flushLogToFile(new File(buildDir
+ File
.separatorChar
+ "build.log"));
246 throw new BuildException(errorModule
+ " build error. ");
248 } catch (InterruptedException ex
) {
249 BuildException e
= new BuildException("Thread wait Error. \n" + ex
.getMessage());
250 e
.setStackTrace(ex
.getStackTrace());
256 GenBuildLogger
.setCacheEnable(false);
258 // call fvs, postbuild
261 ant
.setProject(getProject());
262 ant
.setAntfile(platformBuildFile
);
263 ant
.setTarget("fvs");
264 ant
.setInheritAll(true);
269 ant
.setProject(getProject());
270 ant
.setAntfile(platformBuildFile
);
271 ant
.setTarget("postbuild");
272 ant
.setInheritAll(true);
276 EdkLog
.flushLogToFile(new File(buildDir
+ File
.separatorChar
+ "build.log"));
281 Parse all modules listed in FPD file.
283 void parseModuleSAFiles() throws EdkException
{
285 Map
<FpdModuleIdentification
, Map
<String
, XmlObject
>> moduleSAs
= saq
.getFpdModules();
288 // For every Module lists in FPD file.
290 Set
<FpdModuleIdentification
> keys
= moduleSAs
.keySet();
291 Iterator
<FpdModuleIdentification
> iter
= keys
.iterator();
292 while (iter
.hasNext()) {
293 FpdModuleIdentification fpdModuleId
= iter
.next();
296 // Generate GenBuildThread
298 GenBuildThread genBuildThread
= new GenBuildThread(fpdModuleId
.getModule(), fpdModuleId
.getArch());
299 genBuildThread
.setParentModuleId(null);
300 genBuildThread
.setProject(getProject());
302 Set
<FpdModuleIdentification
> dependencies
= new LinkedHashSet
<FpdModuleIdentification
>();
304 GlobalData
.registerFpdModuleSA(fpdModuleId
, moduleSAs
.get(fpdModuleId
));
307 // Add all dependent Library Instance
309 saq
.push(GlobalData
.getDoc(fpdModuleId
));
311 ModuleIdentification
[] libinstances
= saq
.getLibraryInstance(fpdModuleId
.getArch());
314 for (int i
= 0; i
< libinstances
.length
; i
++) {
315 FpdModuleIdentification libFpdModuleId
= new FpdModuleIdentification(libinstances
[i
], fpdModuleId
.getArch());
317 // Add to dependencies
319 dependencies
.add(libFpdModuleId
);
322 // Create thread for library instances
324 GenBuildThread liBuildThread
= new GenBuildThread(libinstances
[i
], fpdModuleId
.getArch());
325 liBuildThread
.setParentModuleId(fpdModuleId
.getModule());
326 liBuildThread
.setProject(getProject());
327 liBuildThread
.setStatus(STATUS_DEPENDENCY_READY
);
328 liBuildThread
.setHighPriority(true);
329 allThreads
.put(libFpdModuleId
, liBuildThread
);
331 updateFvs("libqueue", libFpdModuleId
);
334 genBuildThread
.setDependencies(dependencies
);
336 // if (dependencies.size() == 0) {
337 genBuildThread
.setStatus(STATUS_DEPENDENCY_READY
);
340 allThreads
.put(fpdModuleId
, genBuildThread
);
343 // Put fpdModuleId to the corresponding FV
345 saq
.push(GlobalData
.getDoc(fpdModuleId
));
346 String fvBinding
= saq
.getModuleFvBindingKeyword();
348 fpdModuleId
.setFvBinding(fvBinding
);
349 updateFvs(fvBinding
, fpdModuleId
);
352 // Prepare for out put file name
354 ModuleIdentification moduleId
= fpdModuleId
.getModule();
356 String baseName
= saq
.getModuleOutputFileBasename();
358 if (baseName
== null) {
359 baseName
= moduleId
.getName();
361 outfiles
.put(fpdModuleId
, fpdModuleId
.getArch() + File
.separatorChar
362 + moduleId
.getGuid() + "-" + baseName
363 + getSuffix(moduleId
.getModuleType()));
366 // parse module build options, if any
368 GlobalData
.addModuleToolChainOption(fpdModuleId
, parseModuleBuildOptions(false));
369 GlobalData
.addModuleToolChainFamilyOption(fpdModuleId
, parseModuleBuildOptions(true));
374 private boolean isContain(String
[] list
, String item
) {
375 for (int i
= 0; i
< list
.length
; i
++) {
376 if (list
[i
].equalsIgnoreCase(item
)) {
383 public synchronized static void addCount() {
384 synchronized (countSemaphore
) {
389 public synchronized static void subCount() {
390 synchronized (countSemaphore
) {