]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java
Support UserExtension in FPD.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / fpd / PlatformBuildFileGenerator.java
CommitLineData
a29c47e0 1/** @file\r
2 \r
3 Copyright (c) 2006, Intel Corporation\r
4 All rights reserved. This program and the accompanying materials\r
5 are licensed and made available under the terms and conditions of the BSD License\r
6 which accompanies this distribution. The full text of the license may be found at\r
7 http://opensource.org/licenses/bsd-license.php\r
8\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11 **/\r
12package org.tianocore.build.fpd;\r
13\r
14import java.io.File;\r
15import java.util.Iterator;\r
16import java.util.Map;\r
17import java.util.Set;\r
18\r
19import javax.xml.parsers.DocumentBuilder;\r
20import javax.xml.parsers.DocumentBuilderFactory;\r
21import javax.xml.transform.OutputKeys;\r
22import javax.xml.transform.Result;\r
23import javax.xml.transform.Source;\r
24import javax.xml.transform.Transformer;\r
25import javax.xml.transform.TransformerFactory;\r
26import javax.xml.transform.dom.DOMSource;\r
27import javax.xml.transform.stream.StreamResult;\r
28\r
29import org.apache.tools.ant.BuildException;\r
30import org.apache.tools.ant.Project;\r
31import org.tianocore.build.global.GlobalData;\r
32import org.tianocore.build.global.SurfaceAreaQuery;\r
33import org.tianocore.build.id.FpdModuleIdentification;\r
34import org.tianocore.build.id.ModuleIdentification;\r
35import org.w3c.dom.Comment;\r
36import org.w3c.dom.Document;\r
37import org.w3c.dom.Element;\r
8031d48d 38import org.w3c.dom.NamedNodeMap;\r
a29c47e0 39import org.w3c.dom.Node;\r
8031d48d 40import org.w3c.dom.NodeList;\r
a29c47e0 41\r
42public class PlatformBuildFileGenerator {\r
43\r
44 private String platformName;\r
45 \r
46 ///\r
47 /// Mapping from modules identification to out put file name\r
48 ///\r
49 private Map<FpdModuleIdentification, String> outfiles;\r
50\r
51 ///\r
52 /// Mapping from FV name to its modules\r
53 ///\r
54 private Map<String, Set<FpdModuleIdentification>> fvs;\r
55\r
56 ///\r
57 /// Mapping from sequence number to FV names\r
58 ///\r
59 private Map<String, Set<String>> sequences;\r
60 \r
61 private boolean isUnified = true;\r
62 \r
63 private Project project;\r
64 \r
65 private String info = "DO NOT EDIT \n" \r
66 + "File auto-generated by build utility\n" \r
67 + "\n" \r
68 + "Abstract:\n"\r
69 + "Auto-generated ANT build file for building of EFI Modules/Platforms\n";\r
70\r
71 public PlatformBuildFileGenerator(Project project, Map<FpdModuleIdentification, String> outfiles, Map<String, Set<FpdModuleIdentification>> fvs, Map<String, Set<String>> sequences, boolean isUnified){\r
72 this.project = project;\r
73 this.outfiles = outfiles;\r
74 this.fvs = fvs;\r
75 this.sequences = sequences;\r
76 this.isUnified = isUnified;\r
77 this.platformName = project.getProperty("PLATFORM");\r
78 }\r
79 \r
80 /**\r
81 Generate build.out.xml file.\r
82 \r
83 @throws BuildException\r
84 build.out.xml XML document create error\r
85 **/\r
86 public void genBuildFile() throws BuildException {\r
87 DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();\r
88 try {\r
89 DocumentBuilder dombuilder = domfac.newDocumentBuilder();\r
90 Document document = dombuilder.newDocument();\r
91 Comment rootComment = document.createComment(info);\r
92 //\r
93 // create root element and its attributes\r
94 //\r
95 Element root = document.createElement("project");\r
96 root.setAttribute("name", project.getProperty("PLATFORM"));\r
97 root.setAttribute("default", "all");\r
98 root.setAttribute("basedir", ".");\r
99 \r
100 //\r
101 // element for External ANT tasks\r
102 //\r
103 root.appendChild(document.createComment("Apply external ANT tasks"));\r
104 Element ele = document.createElement("taskdef");\r
105 ele.setAttribute("resource", "GenBuild.tasks");\r
106 root.appendChild(ele);\r
107\r
108 ele = document.createElement("taskdef");\r
109 ele.setAttribute("resource", "frameworktasks.tasks");\r
110 root.appendChild(ele);\r
111\r
112 ele = document.createElement("property");\r
113 ele.setAttribute("environment", "env");\r
114 root.appendChild(ele);\r
115 \r
116 Set<String> sequenceKeys = sequences.keySet();\r
117 Iterator sequenceIter = sequenceKeys.iterator();\r
118 String dependsStr = "";\r
119 while (sequenceIter.hasNext()) {\r
120 String num = (String)sequenceIter.next();\r
121 if (dependsStr.length() > 0) {\r
122 dependsStr += " , ";\r
123 }\r
124 dependsStr += "modules" + num + ", fvs" + num;\r
125 }\r
126 \r
127 //\r
128 // Default Target\r
129 //\r
130 root.appendChild(document.createComment("Default target"));\r
131 ele = document.createElement("target");\r
132 ele.setAttribute("name", "all");\r
133 ele.setAttribute("depends", dependsStr + ", userextensions");\r
134 root.appendChild(ele);\r
135 \r
136 //\r
137 // Modules and Fvs Target\r
138 //\r
139 sequenceIter = sequenceKeys.iterator();\r
140 while (sequenceIter.hasNext()) {\r
141 String num = (String)sequenceIter.next();\r
142 applyModules(document, root, num);\r
143 applyFvs(document, root, num);\r
144 }\r
145\r
146 //\r
147 // Clean Target\r
148 //\r
149 applyClean(document, root);\r
150 \r
151 //\r
152 // Deep Clean Target\r
153 //\r
154 applyCleanall(document, root);\r
155 \r
156 //\r
157 // User Extension\r
158 //\r
159 applyUserExtensions(document, root);\r
160 \r
161 document.appendChild(rootComment);\r
162 document.appendChild(root);\r
163 //\r
164 // Prepare the DOM document for writing\r
165 //\r
166 Source source = new DOMSource(document);\r
167 //\r
168 // Prepare the output file\r
169 //\r
170 File file = new File(project.getProperty("PLATFORM_DIR") + File.separatorChar + platformName + "_build.xml");\r
171 //\r
172 // generate all directory path\r
173 //\r
174 (new File(file.getParent())).mkdirs();\r
175 Result result = new StreamResult(file);\r
176 //\r
177 // Write the DOM document to the file\r
178 //\r
179 Transformer xformer = TransformerFactory.newInstance().newTransformer();\r
180 xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");\r
181 xformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
182 xformer.transform(source, result);\r
183 } catch (Exception ex) {\r
184 ex.printStackTrace();\r
185 throw new BuildException("Generate " + platformName + "_build.xml failed. \n" + ex.getMessage());\r
186 }\r
187 }\r
8031d48d 188 \r
a29c47e0 189 private void applyModules(Document document, Node root, String num) {\r
190 root.appendChild(document.createComment("Modules target"));\r
191 Element ele = document.createElement("target");\r
192 ele.setAttribute("name", "modules" + num);\r
193 \r
194 Set<String> fvNameSet = sequences.get(num);\r
195\r
196 Iterator fvNameIter = fvNameSet.iterator();\r
197 while (fvNameIter.hasNext()) {\r
198 String fvName = (String)fvNameIter.next();\r
199 Set<FpdModuleIdentification> set = fvs.get(fvName);\r
200 Iterator iter = set.iterator();\r
201 while (iter.hasNext()) {\r
202 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();\r
203 ModuleIdentification moduleId = fpdModuleId.getModule();\r
204 Element moduleEle = document.createElement("GenBuild");\r
205 moduleEle.setAttribute("type", "build");\r
206 //\r
207 // Inherit Properties.\r
208 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}\r
209 //\r
210 \r
211 //\r
212 // ARCH\r
213 //\r
214 Element property = document.createElement("property");\r
215 property.setAttribute("name", "ARCH");\r
216 property.setAttribute("value", fpdModuleId.getArch());\r
217 moduleEle.appendChild(property);\r
218\r
219 //\r
220 // MODULE_GUID\r
221 //\r
222 property = document.createElement("property");\r
223 property.setAttribute("name", "MODULE_GUID");\r
224 property.setAttribute("value", moduleId.getGuid());\r
225 moduleEle.appendChild(property);\r
226 \r
227 //\r
228 // MODULE_VERSION\r
229 //\r
230 property = document.createElement("property");\r
231 property.setAttribute("name", "MODULE_VERSION");\r
232 property.setAttribute("value", moduleId.getVersion());\r
233 moduleEle.appendChild(property);\r
234 \r
235 //\r
236 // PACKAGE_GUID\r
237 //\r
238 property = document.createElement("property");\r
239 property.setAttribute("name", "PACKAGE_GUID");\r
240 property.setAttribute("value", moduleId.getPackage().getGuid());\r
241 moduleEle.appendChild(property);\r
242 \r
243 //\r
244 // PACKAGE_VERSION\r
245 //\r
246 property = document.createElement("property");\r
247 property.setAttribute("name", "PACKAGE_VERSION");\r
248 property.setAttribute("value", moduleId.getPackage().getVersion());\r
249 moduleEle.appendChild(property);\r
250 \r
251 ele.appendChild(moduleEle);\r
252 }\r
253 }\r
254 root.appendChild(ele);\r
255 }\r
256 \r
257 private void applyFvs(Document document, Node root, String num) {\r
258 Set<String> fvNameSet = sequences.get(num);\r
259 //\r
260 // FVS Target\r
261 //\r
262 root.appendChild(document.createComment("FVs target"));\r
263 Element ele = document.createElement("target");\r
264 ele.setAttribute("name", "fvs" + num);\r
265\r
266 //\r
267 // For every Target and ToolChain\r
268 //\r
269 String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
270 for (int i = 0; i < targetList.length; i++){\r
271 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
272 for(int j = 0; j < toolchainList.length; j++){\r
273 String fvOutputDir = project.getProperty("BUILD_DIR") + File.separatorChar \r
274 + targetList[i] + File.separatorChar \r
275 + toolchainList[i] + File.separatorChar + "FV";\r
276 String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();\r
277 for (int k = 0; k < validFv.length; k++) {\r
278 if (fvNameSet.contains(validFv[k]) || ! isListInSequence(validFv[k])) {\r
279 String inputFile = fvOutputDir + "" + File.separatorChar + validFv[k].toUpperCase() + ".inf";\r
280 Element fvEle = document.createElement("genfvimage");\r
281 fvEle.setAttribute("infFile", inputFile);\r
282 fvEle.setAttribute("outputDir", fvOutputDir);\r
283 ele.appendChild(fvEle);\r
284 }\r
285 }\r
286 }\r
287 }\r
288 root.appendChild(ele);\r
289 }\r
290 \r
291 private void applyClean(Document document, Node root) {\r
292 //\r
293 // Clean Target\r
294 //\r
295 root.appendChild(document.createComment("Clean target"));\r
296 Element ele = document.createElement("target");\r
297 ele.setAttribute("name", "clean");\r
298\r
299 if (isUnified) {\r
300 Element cleanEle = document.createElement("delete");\r
301 cleanEle.setAttribute("includeemptydirs", "true");\r
302 Element filesetEle = document.createElement("fileset");\r
303 filesetEle.setAttribute("dir", project.getProperty("BUILD_DIR"));\r
304 filesetEle.setAttribute("includes", "**\\OUTPUT\\**");\r
305 cleanEle.appendChild(filesetEle);\r
306 ele.appendChild(cleanEle);\r
307 } else {\r
308 Set set = outfiles.keySet();\r
309 Iterator iter = set.iterator();\r
310 while (iter.hasNext()) {\r
311 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();\r
312 ModuleIdentification moduleId = fpdModuleId.getModule();\r
313\r
314 Element ifEle = document.createElement("if");\r
315 Element availableEle = document.createElement("available");\r
316 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar\r
317 + "build.xml");\r
318 ifEle.appendChild(availableEle);\r
319 Element elseEle = document.createElement("then");\r
320\r
321 Element moduleEle = document.createElement("ant");\r
322 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar\r
323 + "build.xml");\r
324 moduleEle.setAttribute("target", "clean");\r
325 //\r
326 // Inherit Properties.\r
327 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}\r
328 //\r
329 \r
330 //\r
331 // ARCH\r
332 //\r
333 Element property = document.createElement("property");\r
334 property.setAttribute("name", "ARCH");\r
335 property.setAttribute("value", fpdModuleId.getArch());\r
336 moduleEle.appendChild(property);\r
337\r
338 //\r
339 // PACKAGE\r
340 //\r
341 property = document.createElement("property");\r
342 property.setAttribute("name", "PACKAGE");\r
343 property.setAttribute("value", moduleId.getPackage().getName());\r
344 moduleEle.appendChild(property);\r
345 \r
346 //\r
347 // PACKAGE_GUID\r
348 //\r
349 property = document.createElement("property");\r
350 property.setAttribute("name", "PACKAGE_GUID");\r
351 property.setAttribute("value", moduleId.getPackage().getGuid());\r
352 moduleEle.appendChild(property);\r
353 \r
354 //\r
355 // PACKAGE_VERSION\r
356 //\r
357 property = document.createElement("property");\r
358 property.setAttribute("name", "PACKAGE_VERSION");\r
359 property.setAttribute("value", moduleId.getPackage().getVersion());\r
360 moduleEle.appendChild(property);\r
361 \r
362 //\r
363 // MODULE_DIR\r
364 //\r
365 property = document.createElement("property");\r
366 property.setAttribute("name", "MODULE_DIR");\r
367 property.setAttribute("value", moduleId.getMsaFile().getParent());\r
368 moduleEle.appendChild(property);\r
369 elseEle.appendChild(moduleEle);\r
370 ifEle.appendChild(elseEle);\r
371 ele.appendChild(ifEle);\r
372 }\r
373 }\r
374 root.appendChild(ele);\r
375 }\r
376 \r
377 private void applyCleanall(Document document, Node root) {\r
378 //\r
379 // Deep Clean Target\r
380 //\r
381 root.appendChild(document.createComment("Clean All target"));\r
382 Element ele = document.createElement("target");\r
383 ele.setAttribute("name", "cleanall");\r
384\r
385 if (isUnified) {\r
d3dfaf4b 386 String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
387 for (int i = 0; i < targetList.length; ++i) {\r
388 Element cleanAllEle = document.createElement("delete");\r
389 cleanAllEle.setAttribute("dir", project.getProperty("BUILD_DIR") + File.separatorChar + targetList[i]);\r
390 ele.appendChild(cleanAllEle);\r
391 }\r
a29c47e0 392 } else {\r
393 Set set = outfiles.keySet();\r
394 Iterator iter = set.iterator();\r
395 while (iter.hasNext()) {\r
396 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();\r
397 ModuleIdentification moduleId = fpdModuleId.getModule();\r
398\r
399 Element ifEle = document.createElement("if");\r
400 Element availableEle = document.createElement("available");\r
401 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar\r
402 + "build.xml");\r
403 ifEle.appendChild(availableEle);\r
404 Element elseEle = document.createElement("then");\r
405\r
406 Element moduleEle = document.createElement("ant");\r
407 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar\r
408 + "build.xml");\r
409 moduleEle.setAttribute("target", "cleanall");\r
410 //\r
411 // Inherit Properties.\r
412 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}\r
413 //\r
414 \r
415 //\r
416 // ARCH\r
417 //\r
418 Element property = document.createElement("property");\r
419 property.setAttribute("name", "ARCH");\r
420 property.setAttribute("value", fpdModuleId.getArch());\r
421 moduleEle.appendChild(property);\r
422\r
423 //\r
424 // PACKAGE\r
425 //\r
426 property = document.createElement("property");\r
427 property.setAttribute("name", "PACKAGE");\r
428 property.setAttribute("value", moduleId.getPackage().getName());\r
429 moduleEle.appendChild(property);\r
430 \r
431 //\r
432 // PACKAGE_GUID\r
433 //\r
434 property = document.createElement("property");\r
435 property.setAttribute("name", "PACKAGE_GUID");\r
436 property.setAttribute("value", moduleId.getPackage().getGuid());\r
437 moduleEle.appendChild(property);\r
438 \r
439 //\r
440 // PACKAGE_VERSION\r
441 //\r
442 property = document.createElement("property");\r
443 property.setAttribute("name", "PACKAGE_VERSION");\r
444 property.setAttribute("value", moduleId.getPackage().getVersion());\r
445 moduleEle.appendChild(property);\r
446 \r
447 //\r
448 // MODULE_DIR\r
449 //\r
450 property = document.createElement("property");\r
451 property.setAttribute("name", "MODULE_DIR");\r
452 property.setAttribute("value", moduleId.getMsaFile().getParent());\r
453 moduleEle.appendChild(property);\r
454 elseEle.appendChild(moduleEle);\r
455 ifEle.appendChild(elseEle);\r
456 ele.appendChild(ifEle);\r
457 }\r
458 }\r
459 root.appendChild(ele);\r
460 }\r
461 \r
462 private void applyUserExtensions(Document document, Node root) {\r
463 //\r
464 // User Extensions\r
465 //\r
466 root.appendChild(document.createComment("User Extensions"));\r
467 Element ele = document.createElement("target");\r
468 ele.setAttribute("name", "userextensions");\r
469 \r
8031d48d 470 Node node = SurfaceAreaQuery.getFpdUserExtension();\r
471 if (node != null) {\r
472 //\r
473 // For every Target and ToolChain\r
474 //\r
475 String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
476 for (int i = 0; i < targetList.length; i++){\r
477 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
478 for(int j = 0; j < toolchainList.length; j++){\r
479 //\r
480 // Prepare FV_DIR\r
481 //\r
482 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar \r
483 + targetList[i] + File.separatorChar \r
484 + toolchainList[j];\r
485 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");\r
486 Element fvEle = document.createElement("var");\r
487 fvEle.setAttribute("name", "FV_DIR");\r
488 fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));\r
489 ele.appendChild(fvEle);\r
490 \r
491 NodeList childNodes = node.getChildNodes();\r
492 for (int k = 0; k < childNodes.getLength(); k++) {\r
493 Node childItem = childNodes.item(k);\r
494 if (childItem.getNodeType() == Node.ELEMENT_NODE) {\r
495 ele.appendChild(recursiveNode(childItem, document));\r
496 }\r
497 }\r
498 \r
499 }\r
500 }\r
501 }\r
502 \r
a29c47e0 503 root.appendChild(ele);\r
504 }\r
505 \r
8031d48d 506 private Element recursiveNode(Node node, Document document) {\r
507 Element root = document.createElement(node.getNodeName());\r
508 NamedNodeMap attr = node.getAttributes();\r
509 for (int i = 0; i < attr.getLength(); i++) {\r
510 Node attrItem = attr.item(i);\r
511 root.setAttribute(attrItem.getNodeName(), attrItem.getNodeValue());\r
512 }\r
513 NodeList childNodes = node.getChildNodes();\r
514 for (int i = 0; i < childNodes.getLength(); i++) {\r
515 Node childItem = childNodes.item(i);\r
516 if (childItem.getNodeType() == Node.ELEMENT_NODE) {\r
517 root.appendChild(recursiveNode(childItem, document));\r
518 }\r
519 else if (childItem.getNodeType() == Node.TEXT_NODE){\r
520 if ( ! childItem.getNodeValue().trim().equalsIgnoreCase("")) {\r
521 root.setTextContent(childItem.getNodeValue());\r
522 }\r
523 }\r
524 }\r
525 return root;\r
526 }\r
a29c47e0 527 \r
528 private boolean isListInSequence(String fvName) {\r
529 Set<String> numbers = sequences.keySet();\r
530 Iterator<String> iter = numbers.iterator();\r
531 while (iter.hasNext()) {\r
532 Set<String> fvNameSet = sequences.get(iter.next());\r
533 if (fvNameSet.contains(fvName)) {\r
534 return true;\r
535 }\r
536 }\r
537 return false;\r
538 }\r
539}\r