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