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