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