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 boolean isError
= false;
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
) {
172 // If all modules are already built
174 if (currentQueueCode
>= queueList
.size()) {
178 int percentage
= (totalNumber
- remainNumber
) * 100 / totalNumber
;
179 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, percentage
+ "% finished. Has built " + (totalNumber
- remainNumber
) + " modules of " + totalNumber
+ " total. ");
181 Set
<FpdModuleIdentification
> currentQueueModules
= fvs
.get(queueList
.get(currentQueueCode
));
183 if (currentQueueModules
== null) {
187 Iterator
<FpdModuleIdentification
> currentIter
= currentQueueModules
.iterator();
189 GenBuildThread a
= null;
191 boolean existNoneReady
= false;
193 while (currentIter
.hasNext()) {
194 GenBuildThread item
= allThreads
.get(currentIter
.next());
195 if (item
.getStatus() == STATUS_DEPENDENCY_NOT_READY
) {
196 existNoneReady
= true;
197 } else if (item
.getStatus() == STATUS_DEPENDENCY_READY
) {
201 if (currentRunNumber
== FrameworkBuildTask
.MAX_CONCURRENT_THREAD_NUMBER
) {
209 // Exist ready thread
211 // EdkLog.log(this, EdkLog.EDK_ALWAYS, "Exist ready thread");
213 } else if (existNoneReady
&& currentRunNumber
== 0) {
215 // No active thread, but still have dependency not read thread
217 throw new BuildException("Existing some modules can't resolve depedencies. ");
218 } else if (!existNoneReady
&& currentRunNumber
== 0) {
220 // Current queue build finish, move to next
222 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, "Current queue build finish, move to next");
227 // active thread exist, but no ready thread
229 EdkLog
.log(this, EdkLog
.EDK_ALWAYS
, "Active thread exist, but no ready thread. Current running number is " + currentRunNumber
);
233 deamonSemaphore
.wait();
235 GenBuildLogger
.setCacheEnable(false);
236 EdkLog
.flushLogToFile(new File(buildDir
+ File
.separatorChar
+ "build.log"));
238 GenBuildLogger
.maskAllLog(true);
239 FpdParserForThread
.tg
.destroy();
240 GenBuildLogger
.maskAllLog(false);
242 throw new BuildException("One thread error. ");
244 } catch (InterruptedException ex
) {
245 BuildException e
= new BuildException("Thread wait Error. \n" + ex
.getMessage());
246 e
.setStackTrace(ex
.getStackTrace());
252 GenBuildLogger
.setCacheEnable(false);
254 // call fvs, postbuild
257 ant
.setProject(getProject());
258 ant
.setAntfile(platformBuildFile
);
259 ant
.setTarget("fvs");
260 ant
.setInheritAll(true);
265 ant
.setProject(getProject());
266 ant
.setAntfile(platformBuildFile
);
267 ant
.setTarget("postbuild");
268 ant
.setInheritAll(true);
272 EdkLog
.flushLogToFile(new File(buildDir
+ File
.separatorChar
+ "build.log"));
278 Parse all modules listed in FPD file.
280 void parseModuleSAFiles() throws EdkException
{
282 Map
<FpdModuleIdentification
, Map
<String
, XmlObject
>> moduleSAs
= saq
.getFpdModules();
285 // For every Module lists in FPD file.
287 Set
<FpdModuleIdentification
> keys
= moduleSAs
.keySet();
288 Iterator
<FpdModuleIdentification
> iter
= keys
.iterator();
289 while (iter
.hasNext()) {
290 FpdModuleIdentification fpdModuleId
= iter
.next();
293 // Generate GenBuildThread
295 GenBuildThread genBuildThread
= new GenBuildThread(fpdModuleId
.getModule(), fpdModuleId
.getArch());
296 genBuildThread
.setParentModuleId(null);
297 genBuildThread
.setProject(getProject());
299 Set
<FpdModuleIdentification
> dependencies
= new LinkedHashSet
<FpdModuleIdentification
>();
301 GlobalData
.registerFpdModuleSA(fpdModuleId
, moduleSAs
.get(fpdModuleId
));
304 // Add all dependent Library Instance
306 saq
.push(GlobalData
.getDoc(fpdModuleId
));
308 ModuleIdentification
[] libinstances
= saq
.getLibraryInstance(fpdModuleId
.getArch());
311 for (int i
= 0; i
< libinstances
.length
; i
++) {
312 FpdModuleIdentification libFpdModuleId
= new FpdModuleIdentification(libinstances
[i
], fpdModuleId
.getArch());
314 // Add to dependencies
316 dependencies
.add(libFpdModuleId
);
319 // Create thread for library instances
321 GenBuildThread liBuildThread
= new GenBuildThread(libinstances
[i
], fpdModuleId
.getArch());
322 liBuildThread
.setParentModuleId(fpdModuleId
.getModule());
323 liBuildThread
.setProject(getProject());
324 liBuildThread
.setStatus(STATUS_DEPENDENCY_READY
);
325 liBuildThread
.setHighPriority(true);
326 allThreads
.put(libFpdModuleId
, liBuildThread
);
328 updateFvs("libqueue", libFpdModuleId
);
331 genBuildThread
.setDependencies(dependencies
);
333 // if (dependencies.size() == 0) {
334 genBuildThread
.setStatus(STATUS_DEPENDENCY_READY
);
337 allThreads
.put(fpdModuleId
, genBuildThread
);
340 // Put fpdModuleId to the corresponding FV
342 saq
.push(GlobalData
.getDoc(fpdModuleId
));
343 String fvBinding
= saq
.getModuleFvBindingKeyword();
345 fpdModuleId
.setFvBinding(fvBinding
);
346 updateFvs(fvBinding
, fpdModuleId
);
349 // Prepare for out put file name
351 ModuleIdentification moduleId
= fpdModuleId
.getModule();
353 String baseName
= saq
.getModuleOutputFileBasename();
355 if (baseName
== null) {
356 baseName
= moduleId
.getName();
358 outfiles
.put(fpdModuleId
, fpdModuleId
.getArch() + File
.separatorChar
359 + moduleId
.getGuid() + "-" + baseName
360 + getSuffix(moduleId
.getModuleType()));
363 // parse module build options, if any
365 GlobalData
.addModuleToolChainOption(fpdModuleId
, parseModuleBuildOptions(false));
366 GlobalData
.addModuleToolChainFamilyOption(fpdModuleId
, parseModuleBuildOptions(true));
371 private boolean isContain(String
[] list
, String item
) {
372 for (int i
= 0; i
< list
.length
; i
++) {
373 if (list
[i
].equalsIgnoreCase(item
)) {
380 public synchronized static void addCount() {
381 synchronized (countSemaphore
) {
386 public synchronized static void subCount() {
387 synchronized (countSemaphore
) {