]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java
Adding new Logger instead of Ant's.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / fpd / FpdParserForThread.java
1 /** @file
2 This file is ANT task FpdParserTask.
3
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
9
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.
12 **/
13 package org.tianocore.build.fpd;
14
15 import java.io.File;
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;
21 import java.util.Map;
22 import java.util.Set;
23
24 import org.apache.tools.ant.BuildException;
25 import org.apache.tools.ant.taskdefs.Ant;
26 import org.apache.xmlbeans.XmlObject;
27
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;
37
38 /**
39
40 @since GenBuild 1.0
41 **/
42 public class FpdParserForThread extends FpdParserTask {
43
44 public static Map<FpdModuleIdentification, GenBuildThread> allThreads = new LinkedHashMap<FpdModuleIdentification, GenBuildThread>();
45
46 List<String> queueList = new ArrayList<String>();
47
48 public static Object deamonSemaphore = new Object();
49
50 static Object countSemaphore = new Object();
51
52 public static int STATUS_DEPENDENCY_NOT_READY = 1;
53
54 public static int STATUS_DEPENDENCY_READY = 2;
55
56 public static int STATUS_START_RUN = 3;
57
58 public static int STATUS_END_RUN = 4;
59
60 private int currentQueueCode = 0;
61
62 public static int currentRunNumber = 0;
63
64 public static int totalNumber = 0;
65
66 public static int remainNumber = 0;
67
68 /**
69 Public construct method. It is necessary for ANT task.
70 **/
71 public FpdParserForThread() {
72 }
73
74 /**
75
76
77 **/
78 public void execute() throws BuildException {
79
80 this.setTaskName(".........");
81 //
82 // Parse FPD file
83 //
84 parseFpdFile();
85
86 //
87 // Prepare BUILD_DIR
88 //
89 isUnified = OutputManager.getInstance().prepareBuildDir(getProject());
90 String buildDir = getProject().getProperty("BUILD_DIR");
91
92 //
93 // For every Target and ToolChain
94 //
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++) {
99 //
100 // Prepare FV_DIR
101 //
102 String ffsCommonDir = buildDir + File.separatorChar
103 + targetList[i] + "_"
104 + toolchainList[j];
105 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
106 fvDir.mkdirs();
107 getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/"));
108
109 //
110 // Gen Fv.inf files
111 //
112 genFvInfFiles(ffsCommonDir);
113 }
114 }
115
116 //
117 // Gen build.xml
118 //
119 String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml";
120 PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile);
121 fileGenerator.genBuildFile();
122
123 //
124 // Prepare Queue
125 //
126 queueList.add("libqueue");
127
128 String[] validFv = saq.getFpdValidImageNames();
129
130 for (int i = 0; i < validFv.length; i++) {
131 queueList.add(validFv[i]);
132 }
133
134 Iterator<String> fvsNameIter = fvs.keySet().iterator();
135
136 while (fvsNameIter.hasNext()) {
137 String fvName = fvsNameIter.next();
138 if (!isContain(validFv, fvName)) {
139 queueList.add(fvName);
140 }
141 }
142
143 //
144 // Ant call ${PLATFORM}_build.xml
145 //
146 Ant ant = new Ant();
147 ant.setProject(getProject());
148 ant.setAntfile(platformBuildFile);
149 ant.setTarget("prebuild");
150 ant.setInheritAll(true);
151 ant.init();
152 ant.execute();
153
154 remainNumber = totalNumber = allThreads.size();
155
156 EdkLog.log(this, EdkLog.EDK_ALWAYS, "Total thread number is " + totalNumber);
157 GenBuildLogger.setCacheEnable(true);
158 //
159 // Waiting for all thread over, or time out
160 //
161 synchronized (deamonSemaphore) {
162 //
163 // Initialize BUGBUG
164 //
165
166 while (true) {
167 //
168 // If all modules are already built
169 //
170 if (currentQueueCode >= queueList.size()) {
171 break ;
172 }
173
174 int percentage = (totalNumber - remainNumber) * 100 / totalNumber;
175 EdkLog.log(this, EdkLog.EDK_ALWAYS, percentage + "% finished. Has built " + (totalNumber - remainNumber) + " modules of " + totalNumber + " total. ");
176
177 Set<FpdModuleIdentification> currentQueueModules = fvs.get(queueList.get(currentQueueCode));
178
179 if (currentQueueModules == null) {
180 ++currentQueueCode;
181 continue ;
182 }
183 Iterator<FpdModuleIdentification> currentIter = currentQueueModules.iterator();
184
185 GenBuildThread a = null;
186
187 boolean existNoneReady = false;
188
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) {
194 a = item;
195 addCount();
196 a.start();
197 if (currentRunNumber == FrameworkBuildTask.MAX_CONCURRENT_THREAD_NUMBER) {
198 break ;
199 }
200 }
201 }
202
203 if (a != null) {
204 //
205 // Exist ready thread
206 //
207 // EdkLog.log(this, EdkLog.EDK_ALWAYS, "Exist ready thread");
208
209 } else if (existNoneReady && currentRunNumber == 0) {
210 //
211 // No active thread, but still have dependency not read thread
212 //
213 throw new BuildException("Existing some modules can't resolve depedencies. ");
214 } else if (!existNoneReady && currentRunNumber == 0) {
215 //
216 // Current queue build finish, move to next
217 //
218 EdkLog.log(this, EdkLog.EDK_ALWAYS, "Current queue build finish, move to next");
219 ++currentQueueCode;
220 continue ;
221 } else {
222 //
223 // active thread exist, but no ready thread
224 //
225 EdkLog.log(this, EdkLog.EDK_ALWAYS, "Active thread exist, but no ready thread. Current running number is " + currentRunNumber);
226 }
227
228 try {
229 deamonSemaphore.wait();
230 } catch (InterruptedException ex) {
231 BuildException e = new BuildException("Thread wait Error. \n" + ex.getMessage());
232 e.setStackTrace(ex.getStackTrace());
233 throw e;
234 }
235 }
236 }
237 GenBuildLogger.setCacheEnable(false);
238 //
239 // call fvs, postbuild
240 //
241 ant = new Ant();
242 ant.setProject(getProject());
243 ant.setAntfile(platformBuildFile);
244 ant.setTarget("fvs");
245 ant.setInheritAll(true);
246 ant.init();
247 ant.execute();
248
249 ant = new Ant();
250 ant.setProject(getProject());
251 ant.setAntfile(platformBuildFile);
252 ant.setTarget("postbuild");
253 ant.setInheritAll(true);
254 ant.init();
255 ant.execute();
256
257 EdkLog.flushLogToFile(new File(buildDir + File.separatorChar + "build.log"));
258
259 }
260
261
262 /**
263 Parse all modules listed in FPD file.
264 **/
265 void parseModuleSAFiles() throws EdkException{
266
267 Map<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = saq.getFpdModules();
268
269 //
270 // For every Module lists in FPD file.
271 //
272 Set<FpdModuleIdentification> keys = moduleSAs.keySet();
273 Iterator<FpdModuleIdentification> iter = keys.iterator();
274 while (iter.hasNext()) {
275 FpdModuleIdentification fpdModuleId = iter.next();
276
277 //
278 // Generate GenBuildThread
279 //
280 GenBuildThread genBuildThread = new GenBuildThread();
281 genBuildThread.setArch(fpdModuleId.getArch());
282 genBuildThread.setParentModuleId(null);
283 genBuildThread.setModuleId(fpdModuleId.getModule());
284 genBuildThread.setProject(getProject());
285
286 Set<FpdModuleIdentification> dependencies = new LinkedHashSet<FpdModuleIdentification>();
287
288 GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId));
289
290 //
291 // Add all dependent Library Instance
292 //
293 saq.push(GlobalData.getDoc(fpdModuleId));
294
295 ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());
296 saq.pop();
297
298 for (int i = 0; i < libinstances.length; i++) {
299 FpdModuleIdentification libFpdModuleId = new FpdModuleIdentification(libinstances[i], fpdModuleId.getArch());
300 //
301 // Add to dependencies
302 //
303 dependencies.add(libFpdModuleId);
304
305 //
306 // Create thread for library instances
307 //
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);
316
317 updateFvs("libqueue", libFpdModuleId);
318 }
319
320 genBuildThread.setDependencies(dependencies);
321 // if (dependencies.size() == 0) {
322 genBuildThread.setStatus(STATUS_DEPENDENCY_READY);
323 // }
324
325 allThreads.put(fpdModuleId, genBuildThread);
326
327 //
328 // Put fpdModuleId to the corresponding FV
329 //
330 saq.push(GlobalData.getDoc(fpdModuleId));
331 String fvBinding = saq.getModuleFvBindingKeyword();
332
333 fpdModuleId.setFvBinding(fvBinding);
334 updateFvs(fvBinding, fpdModuleId);
335
336 //
337 // Prepare for out put file name
338 //
339 ModuleIdentification moduleId = fpdModuleId.getModule();
340
341 String baseName = saq.getModuleOutputFileBasename();
342
343 if (baseName == null) {
344 baseName = moduleId.getName();
345 }
346 outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar
347 + moduleId.getGuid() + "-" + baseName
348 + getSuffix(moduleId.getModuleType()));
349
350 //
351 // parse module build options, if any
352 //
353 GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false));
354 GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true));
355 saq.pop();
356 }
357 }
358
359 private boolean isContain(String[] list, String item) {
360 for (int i = 0; i < list.length; i++) {
361 if (list[i].equalsIgnoreCase(item)) {
362 return true;
363 }
364 }
365 return false;
366 }
367
368 public synchronized static void addCount() {
369 synchronized (countSemaphore) {
370 ++currentRunNumber;
371 }
372 }
373
374 public synchronized static void subCount() {
375 synchronized (countSemaphore) {
376 --currentRunNumber;
377 --remainNumber;
378 }
379 }
380 }