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