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