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