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