]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - Tools/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java
Support prebuild and postbuild for UserExtension for Platform build. If UserExtension...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / fpd / PlatformBuildFileGenerator.java
... / ...
CommitLineData
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
38import org.w3c.dom.NamedNodeMap;\r
39import org.w3c.dom.Node;\r
40import org.w3c.dom.NodeList;\r
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("taskdef");\r
113 ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");\r
114 root.appendChild(ele);\r
115 \r
116 ele = document.createElement("property");\r
117 ele.setAttribute("environment", "env");\r
118 root.appendChild(ele);\r
119 \r
120 Set<String> sequenceKeys = sequences.keySet();\r
121 Iterator sequenceIter = sequenceKeys.iterator();\r
122 String dependsStr = "prebuild";\r
123 while (sequenceIter.hasNext()) {\r
124 String num = (String)sequenceIter.next();\r
125 if (dependsStr.length() > 0) {\r
126 dependsStr += " , ";\r
127 }\r
128 dependsStr += "modules" + num + ", fvs" + num;\r
129 }\r
130 \r
131 //\r
132 // Default Target\r
133 //\r
134 root.appendChild(document.createComment("Default target"));\r
135 ele = document.createElement("target");\r
136 ele.setAttribute("name", "all");\r
137 ele.setAttribute("depends", dependsStr + ", postbuild");\r
138 root.appendChild(ele);\r
139 \r
140 //\r
141 // Modules and Fvs Target\r
142 //\r
143 sequenceIter = sequenceKeys.iterator();\r
144 while (sequenceIter.hasNext()) {\r
145 String num = (String)sequenceIter.next();\r
146 applyModules(document, root, num);\r
147 applyFvs(document, root, num);\r
148 }\r
149\r
150 //\r
151 // Clean Target\r
152 //\r
153 applyClean(document, root);\r
154 \r
155 //\r
156 // Deep Clean Target\r
157 //\r
158 applyCleanall(document, root);\r
159 \r
160 //\r
161 // User Extension pre build\r
162 //\r
163 applyUserExtensionsPreBuild(document, root);\r
164 \r
165 //\r
166 // User Extension Post build\r
167 //\r
168 applyUserExtensionsPostBuild(document, root);\r
169 \r
170 document.appendChild(rootComment);\r
171 document.appendChild(root);\r
172 //\r
173 // Prepare the DOM document for writing\r
174 //\r
175 Source source = new DOMSource(document);\r
176 //\r
177 // Prepare the output file\r
178 //\r
179 File file = new File(project.getProperty("PLATFORM_DIR") + File.separatorChar + platformName + "_build.xml");\r
180 //\r
181 // generate all directory path\r
182 //\r
183 (new File(file.getParent())).mkdirs();\r
184 Result result = new StreamResult(file);\r
185 //\r
186 // Write the DOM document to the file\r
187 //\r
188 Transformer xformer = TransformerFactory.newInstance().newTransformer();\r
189 xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");\r
190 xformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
191 xformer.transform(source, result);\r
192 } catch (Exception ex) {\r
193 ex.printStackTrace();\r
194 throw new BuildException("Generate " + platformName + "_build.xml failed. \n" + ex.getMessage());\r
195 }\r
196 }\r
197 \r
198 private void applyModules(Document document, Node root, String num) {\r
199 root.appendChild(document.createComment("Modules target"));\r
200 Element ele = document.createElement("target");\r
201 ele.setAttribute("name", "modules" + num);\r
202 \r
203 Set<String> fvNameSet = sequences.get(num);\r
204\r
205 Iterator fvNameIter = fvNameSet.iterator();\r
206 while (fvNameIter.hasNext()) {\r
207 String fvName = (String)fvNameIter.next();\r
208 Set<FpdModuleIdentification> set = fvs.get(fvName);\r
209 Iterator iter = set.iterator();\r
210 while (iter.hasNext()) {\r
211 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();\r
212 ModuleIdentification moduleId = fpdModuleId.getModule();\r
213 Element moduleEle = document.createElement("GenBuild");\r
214 moduleEle.setAttribute("type", "build");\r
215 //\r
216 // Inherit Properties.\r
217 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}\r
218 //\r
219 \r
220 //\r
221 // ARCH\r
222 //\r
223 Element property = document.createElement("property");\r
224 property.setAttribute("name", "ARCH");\r
225 property.setAttribute("value", fpdModuleId.getArch());\r
226 moduleEle.appendChild(property);\r
227\r
228 //\r
229 // MODULE_GUID\r
230 //\r
231 property = document.createElement("property");\r
232 property.setAttribute("name", "MODULE_GUID");\r
233 property.setAttribute("value", moduleId.getGuid());\r
234 moduleEle.appendChild(property);\r
235 \r
236 //\r
237 // MODULE_VERSION\r
238 //\r
239 property = document.createElement("property");\r
240 property.setAttribute("name", "MODULE_VERSION");\r
241 property.setAttribute("value", moduleId.getVersion());\r
242 moduleEle.appendChild(property);\r
243 \r
244 //\r
245 // PACKAGE_GUID\r
246 //\r
247 property = document.createElement("property");\r
248 property.setAttribute("name", "PACKAGE_GUID");\r
249 property.setAttribute("value", moduleId.getPackage().getGuid());\r
250 moduleEle.appendChild(property);\r
251 \r
252 //\r
253 // PACKAGE_VERSION\r
254 //\r
255 property = document.createElement("property");\r
256 property.setAttribute("name", "PACKAGE_VERSION");\r
257 property.setAttribute("value", moduleId.getPackage().getVersion());\r
258 moduleEle.appendChild(property);\r
259 \r
260 ele.appendChild(moduleEle);\r
261 }\r
262 }\r
263 root.appendChild(ele);\r
264 }\r
265 \r
266 private void applyFvs(Document document, Node root, String num) {\r
267 Set<String> fvNameSet = sequences.get(num);\r
268 //\r
269 // FVS Target\r
270 //\r
271 root.appendChild(document.createComment("FVs target"));\r
272 Element ele = document.createElement("target");\r
273 ele.setAttribute("name", "fvs" + num);\r
274\r
275 //\r
276 // For every Target and ToolChain\r
277 //\r
278 String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
279 for (int i = 0; i < targetList.length; i++){\r
280 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
281 for(int j = 0; j < toolchainList.length; j++){\r
282 String fvOutputDir = project.getProperty("BUILD_DIR") + File.separatorChar \r
283 + targetList[i] + File.separatorChar \r
284 + toolchainList[i] + File.separatorChar + "FV";\r
285 String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();\r
286 for (int k = 0; k < validFv.length; k++) {\r
287 if (fvNameSet.contains(validFv[k]) || ! isListInSequence(validFv[k])) {\r
288 String inputFile = fvOutputDir + "" + File.separatorChar + validFv[k].toUpperCase() + ".inf";\r
289 Element fvEle = document.createElement("genfvimage");\r
290 fvEle.setAttribute("infFile", inputFile);\r
291 fvEle.setAttribute("outputDir", fvOutputDir);\r
292 ele.appendChild(fvEle);\r
293 }\r
294 }\r
295 }\r
296 }\r
297 root.appendChild(ele);\r
298 }\r
299 \r
300 private void applyClean(Document document, Node root) {\r
301 //\r
302 // Clean Target\r
303 //\r
304 root.appendChild(document.createComment("Clean target"));\r
305 Element ele = document.createElement("target");\r
306 ele.setAttribute("name", "clean");\r
307\r
308 if (isUnified) {\r
309 Element cleanEle = document.createElement("delete");\r
310 cleanEle.setAttribute("includeemptydirs", "true");\r
311 Element filesetEle = document.createElement("fileset");\r
312 filesetEle.setAttribute("dir", project.getProperty("BUILD_DIR"));\r
313 filesetEle.setAttribute("includes", "**\\OUTPUT\\**");\r
314 cleanEle.appendChild(filesetEle);\r
315 ele.appendChild(cleanEle);\r
316 } else {\r
317 Set set = outfiles.keySet();\r
318 Iterator iter = set.iterator();\r
319 while (iter.hasNext()) {\r
320 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();\r
321 ModuleIdentification moduleId = fpdModuleId.getModule();\r
322\r
323 Element ifEle = document.createElement("if");\r
324 Element availableEle = document.createElement("available");\r
325 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar\r
326 + "build.xml");\r
327 ifEle.appendChild(availableEle);\r
328 Element elseEle = document.createElement("then");\r
329\r
330 Element moduleEle = document.createElement("ant");\r
331 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar\r
332 + "build.xml");\r
333 moduleEle.setAttribute("target", "clean");\r
334 //\r
335 // Inherit Properties.\r
336 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}\r
337 //\r
338 \r
339 //\r
340 // ARCH\r
341 //\r
342 Element property = document.createElement("property");\r
343 property.setAttribute("name", "ARCH");\r
344 property.setAttribute("value", fpdModuleId.getArch());\r
345 moduleEle.appendChild(property);\r
346\r
347 //\r
348 // PACKAGE\r
349 //\r
350 property = document.createElement("property");\r
351 property.setAttribute("name", "PACKAGE");\r
352 property.setAttribute("value", moduleId.getPackage().getName());\r
353 moduleEle.appendChild(property);\r
354 \r
355 //\r
356 // PACKAGE_GUID\r
357 //\r
358 property = document.createElement("property");\r
359 property.setAttribute("name", "PACKAGE_GUID");\r
360 property.setAttribute("value", moduleId.getPackage().getGuid());\r
361 moduleEle.appendChild(property);\r
362 \r
363 //\r
364 // PACKAGE_VERSION\r
365 //\r
366 property = document.createElement("property");\r
367 property.setAttribute("name", "PACKAGE_VERSION");\r
368 property.setAttribute("value", moduleId.getPackage().getVersion());\r
369 moduleEle.appendChild(property);\r
370 \r
371 //\r
372 // MODULE_DIR\r
373 //\r
374 property = document.createElement("property");\r
375 property.setAttribute("name", "MODULE_DIR");\r
376 property.setAttribute("value", moduleId.getMsaFile().getParent());\r
377 moduleEle.appendChild(property);\r
378 elseEle.appendChild(moduleEle);\r
379 ifEle.appendChild(elseEle);\r
380 ele.appendChild(ifEle);\r
381 }\r
382 }\r
383 root.appendChild(ele);\r
384 }\r
385 \r
386 private void applyCleanall(Document document, Node root) {\r
387 //\r
388 // Deep Clean Target\r
389 //\r
390 root.appendChild(document.createComment("Clean All target"));\r
391 Element ele = document.createElement("target");\r
392 ele.setAttribute("name", "cleanall");\r
393\r
394 if (isUnified) {\r
395 String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
396 for (int i = 0; i < targetList.length; ++i) {\r
397 Element cleanAllEle = document.createElement("delete");\r
398 cleanAllEle.setAttribute("dir", project.getProperty("BUILD_DIR") + File.separatorChar + targetList[i]);\r
399 ele.appendChild(cleanAllEle);\r
400 }\r
401 } else {\r
402 Set set = outfiles.keySet();\r
403 Iterator iter = set.iterator();\r
404 while (iter.hasNext()) {\r
405 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();\r
406 ModuleIdentification moduleId = fpdModuleId.getModule();\r
407\r
408 Element ifEle = document.createElement("if");\r
409 Element availableEle = document.createElement("available");\r
410 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar\r
411 + "build.xml");\r
412 ifEle.appendChild(availableEle);\r
413 Element elseEle = document.createElement("then");\r
414\r
415 Element moduleEle = document.createElement("ant");\r
416 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar\r
417 + "build.xml");\r
418 moduleEle.setAttribute("target", "cleanall");\r
419 //\r
420 // Inherit Properties.\r
421 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}\r
422 //\r
423 \r
424 //\r
425 // ARCH\r
426 //\r
427 Element property = document.createElement("property");\r
428 property.setAttribute("name", "ARCH");\r
429 property.setAttribute("value", fpdModuleId.getArch());\r
430 moduleEle.appendChild(property);\r
431\r
432 //\r
433 // PACKAGE\r
434 //\r
435 property = document.createElement("property");\r
436 property.setAttribute("name", "PACKAGE");\r
437 property.setAttribute("value", moduleId.getPackage().getName());\r
438 moduleEle.appendChild(property);\r
439 \r
440 //\r
441 // PACKAGE_GUID\r
442 //\r
443 property = document.createElement("property");\r
444 property.setAttribute("name", "PACKAGE_GUID");\r
445 property.setAttribute("value", moduleId.getPackage().getGuid());\r
446 moduleEle.appendChild(property);\r
447 \r
448 //\r
449 // PACKAGE_VERSION\r
450 //\r
451 property = document.createElement("property");\r
452 property.setAttribute("name", "PACKAGE_VERSION");\r
453 property.setAttribute("value", moduleId.getPackage().getVersion());\r
454 moduleEle.appendChild(property);\r
455 \r
456 //\r
457 // MODULE_DIR\r
458 //\r
459 property = document.createElement("property");\r
460 property.setAttribute("name", "MODULE_DIR");\r
461 property.setAttribute("value", moduleId.getMsaFile().getParent());\r
462 moduleEle.appendChild(property);\r
463 elseEle.appendChild(moduleEle);\r
464 ifEle.appendChild(elseEle);\r
465 ele.appendChild(ifEle);\r
466 }\r
467 }\r
468 root.appendChild(ele);\r
469 }\r
470 \r
471 private void applyUserExtensionsPreBuild(Document document, Node root) {\r
472 //\r
473 // User Extensions\r
474 //\r
475 root.appendChild(document.createComment("Pre Build Processing"));\r
476 Element ele = document.createElement("target");\r
477 ele.setAttribute("name", "prebuild");\r
478 \r
479 Node node = SurfaceAreaQuery.getFpdUserExtensionPreBuild();\r
480 if (node != null) {\r
481 //\r
482 // For every Target and ToolChain\r
483 //\r
484 String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
485 for (int i = 0; i < targetList.length; i++){\r
486 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
487 for(int j = 0; j < toolchainList.length; j++){\r
488 //\r
489 // Prepare FV_DIR\r
490 //\r
491 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar \r
492 + targetList[i] + File.separatorChar \r
493 + toolchainList[j];\r
494 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");\r
495 Element fvEle = document.createElement("var");\r
496 fvEle.setAttribute("name", "FV_DIR");\r
497 fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));\r
498 ele.appendChild(fvEle);\r
499 \r
500 NodeList childNodes = node.getChildNodes();\r
501 for (int k = 0; k < childNodes.getLength(); k++) {\r
502 Node childItem = childNodes.item(k);\r
503 if (childItem.getNodeType() == Node.ELEMENT_NODE) {\r
504 ele.appendChild(recursiveNode(childItem, document));\r
505 }\r
506 }\r
507 \r
508 }\r
509 }\r
510 }\r
511 \r
512 root.appendChild(ele);\r
513 }\r
514 \r
515 private void applyUserExtensionsPostBuild(Document document, Node root) {\r
516 //\r
517 // User Extensions\r
518 //\r
519 root.appendChild(document.createComment("Post Build Processing"));\r
520 Element ele = document.createElement("target");\r
521 ele.setAttribute("name", "postbuild");\r
522 \r
523 Node node = SurfaceAreaQuery.getFpdUserExtensionPostBuild();\r
524 if (node != null) {\r
525 //\r
526 // For every Target and ToolChain\r
527 //\r
528 String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
529 for (int i = 0; i < targetList.length; i++){\r
530 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
531 for(int j = 0; j < toolchainList.length; j++){\r
532 //\r
533 // Prepare FV_DIR\r
534 //\r
535 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar \r
536 + targetList[i] + File.separatorChar \r
537 + toolchainList[j];\r
538 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");\r
539 Element fvEle = document.createElement("var");\r
540 fvEle.setAttribute("name", "FV_DIR");\r
541 fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));\r
542 ele.appendChild(fvEle);\r
543 \r
544 NodeList childNodes = node.getChildNodes();\r
545 for (int k = 0; k < childNodes.getLength(); k++) {\r
546 Node childItem = childNodes.item(k);\r
547 if (childItem.getNodeType() == Node.ELEMENT_NODE) {\r
548 ele.appendChild(recursiveNode(childItem, document));\r
549 }\r
550 }\r
551 \r
552 }\r
553 }\r
554 }\r
555 \r
556 root.appendChild(ele);\r
557 }\r
558 \r
559 private Element recursiveNode(Node node, Document document) {\r
560 Element root = document.createElement(node.getNodeName());\r
561 NamedNodeMap attr = node.getAttributes();\r
562 for (int i = 0; i < attr.getLength(); i++) {\r
563 Node attrItem = attr.item(i);\r
564 root.setAttribute(attrItem.getNodeName(), attrItem.getNodeValue());\r
565 }\r
566 NodeList childNodes = node.getChildNodes();\r
567 for (int i = 0; i < childNodes.getLength(); i++) {\r
568 Node childItem = childNodes.item(i);\r
569 if (childItem.getNodeType() == Node.ELEMENT_NODE) {\r
570 root.appendChild(recursiveNode(childItem, document));\r
571 }\r
572 else if (childItem.getNodeType() == Node.TEXT_NODE){\r
573 if ( ! childItem.getNodeValue().trim().equalsIgnoreCase("")) {\r
574 root.setTextContent(childItem.getNodeValue());\r
575 }\r
576 }\r
577 }\r
578 return root;\r
579 }\r
580 \r
581 private boolean isListInSequence(String fvName) {\r
582 Set<String> numbers = sequences.keySet();\r
583 Iterator<String> iter = numbers.iterator();\r
584 while (iter.hasNext()) {\r
585 Set<String> fvNameSet = sequences.get(iter.next());\r
586 if (fvNameSet.contains(fvName)) {\r
587 return true;\r
588 }\r
589 }\r
590 return false;\r
591 }\r
592}\r