3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 package org
.tianocore
.build
.fpd
;
15 import java
.util
.HashMap
;
16 import java
.util
.Iterator
;
20 import javax
.xml
.parsers
.DocumentBuilder
;
21 import javax
.xml
.parsers
.DocumentBuilderFactory
;
22 import javax
.xml
.transform
.OutputKeys
;
23 import javax
.xml
.transform
.Result
;
24 import javax
.xml
.transform
.Source
;
25 import javax
.xml
.transform
.Transformer
;
26 import javax
.xml
.transform
.TransformerFactory
;
27 import javax
.xml
.transform
.dom
.DOMSource
;
28 import javax
.xml
.transform
.stream
.StreamResult
;
30 import org
.apache
.tools
.ant
.BuildException
;
31 import org
.apache
.tools
.ant
.Project
;
32 import org
.tianocore
.build
.global
.GlobalData
;
33 import org
.tianocore
.build
.global
.SurfaceAreaQuery
;
34 import org
.tianocore
.build
.id
.FpdModuleIdentification
;
35 import org
.tianocore
.build
.id
.ModuleIdentification
;
36 import org
.w3c
.dom
.Comment
;
37 import org
.w3c
.dom
.Document
;
38 import org
.w3c
.dom
.Element
;
39 import org
.w3c
.dom
.NamedNodeMap
;
40 import org
.w3c
.dom
.Node
;
41 import org
.w3c
.dom
.NodeList
;
44 class PlatformBuildFileGenerator is used to generate ${PLATFORM}_build.xml file.
48 public class PlatformBuildFileGenerator
{
51 /// Mapping from modules identification to out put file name
53 private Map
<FpdModuleIdentification
, String
> outfiles
;
56 /// Mapping from FV name to its modules
58 private Map
<String
, Set
<FpdModuleIdentification
>> fvs
= new HashMap
<String
, Set
<FpdModuleIdentification
>>();
61 private boolean isUnified
= true;
63 private SurfaceAreaQuery saq
= null;
65 private File platformBuildFile
= null;
67 private Project project
;
69 private String info
= "DO NOT EDIT \n"
70 + "This file is auto-generated by the build utility\n"
73 + "Auto-generated ANT build file for building EFI Modules and Platforms\n";
75 public PlatformBuildFileGenerator(Project project
, Map
<FpdModuleIdentification
, String
> outfiles
, Map
<String
, Set
<FpdModuleIdentification
>> fvs
, boolean isUnified
, SurfaceAreaQuery saq
, String platformBuildFile
){
76 this.project
= project
;
77 this.outfiles
= outfiles
;
78 this.isUnified
= isUnified
;
81 this.platformBuildFile
= new File(platformBuildFile
);
85 Generate build.out.xml file.
87 @throws BuildException
88 build.out.xml XML document create error
90 public void genBuildFile() throws BuildException
{
91 DocumentBuilderFactory domfac
= DocumentBuilderFactory
.newInstance();
93 DocumentBuilder dombuilder
= domfac
.newDocumentBuilder();
94 Document document
= dombuilder
.newDocument();
95 Comment rootComment
= document
.createComment(info
);
97 // create root element and its attributes
99 Element root
= document
.createElement("project");
100 root
.setAttribute("name", project
.getProperty("PLATFORM"));
101 root
.setAttribute("default", "all");
102 root
.setAttribute("basedir", ".");
105 // element for External ANT tasks
107 root
.appendChild(document
.createComment("Apply external ANT tasks"));
108 Element ele
= document
.createElement("taskdef");
109 ele
.setAttribute("resource", "GenBuild.tasks");
110 root
.appendChild(ele
);
112 ele
= document
.createElement("taskdef");
113 ele
.setAttribute("resource", "frameworktasks.tasks");
114 root
.appendChild(ele
);
116 ele
= document
.createElement("taskdef");
117 ele
.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
118 root
.appendChild(ele
);
120 ele
= document
.createElement("property");
121 ele
.setAttribute("environment", "env");
122 root
.appendChild(ele
);
127 root
.appendChild(document
.createComment("Default target"));
128 ele
= document
.createElement("target");
129 ele
.setAttribute("name", "all");
130 ele
.setAttribute("depends", "prebuild, modules, fvs, postbuild");
131 root
.appendChild(ele
);
134 // Modules and Fvs Target
136 applyModules(document
, root
);
138 applyFvs(document
, root
);
143 applyClean(document
, root
);
148 applyCleanall(document
, root
);
151 // User Extension pre build
153 applyUserExtensionsPreBuild(document
, root
);
156 // User Extension Post build
158 applyUserExtensionsPostBuild(document
, root
);
160 document
.appendChild(rootComment
);
161 document
.appendChild(root
);
163 // Prepare the DOM document for writing
165 Source source
= new DOMSource(document
);
167 // generate all directory path
169 (new File(platformBuildFile
.getParent())).mkdirs();
170 Result result
= new StreamResult(platformBuildFile
);
172 // Write the DOM document to the file
174 Transformer xformer
= TransformerFactory
.newInstance().newTransformer();
175 xformer
.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
176 xformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
177 xformer
.transform(source
, result
);
178 } catch (Exception ex
) {
179 throw new BuildException("Generating platform build file [" + platformBuildFile
.getPath() + "_build.xml] failed. \n" + ex
.getMessage());
184 1. Get All valid Fv Image Names in sequence
185 2. For each FV, get modules by sequences
188 @param document XML document
191 private void applyModules(Document document
, Node root
) {
192 root
.appendChild(document
.createComment("Modules target"));
193 Element ele
= document
.createElement("target");
194 ele
.setAttribute("name", "modules");
197 // Get all valid FV name
199 String
[] validFv
= saq
.getFpdValidImageNames();
202 // For each valid FV, get all modules in sequence
204 for (int i
= 0; i
< validFv
.length
; i
++) {
205 if (fvs
.containsKey(validFv
[i
])) {
206 Set
<FpdModuleIdentification
> set
= fvs
.get(validFv
[i
]);
207 Iterator
<FpdModuleIdentification
> iter
= set
.iterator();
208 while (iter
.hasNext()) {
209 FpdModuleIdentification fpdModuleId
= iter
.next();
210 applySingleModule(document
, ele
, fpdModuleId
);
216 // Get all other modules
218 Iterator
<String
> fvsNameIter
= fvs
.keySet().iterator();
220 while (fvsNameIter
.hasNext()) {
221 String fvName
= fvsNameIter
.next();
222 if (!isContain(validFv
, fvName
)) {
223 Set
<FpdModuleIdentification
> set
= fvs
.get(fvName
);
224 Iterator iter
= set
.iterator();
225 while (iter
.hasNext()) {
226 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
227 applySingleModule(document
, ele
, fpdModuleId
);
232 root
.appendChild(ele
);
235 private void applySingleModule(Document document
, Node root
, FpdModuleIdentification fpdModuleId
) {
236 ModuleIdentification moduleId
= fpdModuleId
.getModule();
237 Element moduleEle
= document
.createElement("GenBuild");
238 moduleEle
.setAttribute("type", "build");
240 // Inherit Properties.
241 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
247 Element property
= document
.createElement("property");
248 property
.setAttribute("name", "ARCH");
249 property
.setAttribute("value", fpdModuleId
.getArch());
250 moduleEle
.appendChild(property
);
255 property
= document
.createElement("property");
256 property
.setAttribute("name", "MODULE_GUID");
257 property
.setAttribute("value", moduleId
.getGuid());
258 moduleEle
.appendChild(property
);
263 property
= document
.createElement("property");
264 property
.setAttribute("name", "MODULE_VERSION");
265 property
.setAttribute("value", moduleId
.getVersion());
266 moduleEle
.appendChild(property
);
271 property
= document
.createElement("property");
272 property
.setAttribute("name", "PACKAGE_GUID");
273 property
.setAttribute("value", moduleId
.getPackage().getGuid());
274 moduleEle
.appendChild(property
);
279 property
= document
.createElement("property");
280 property
.setAttribute("name", "PACKAGE_VERSION");
281 property
.setAttribute("value", moduleId
.getPackage().getVersion());
282 moduleEle
.appendChild(property
);
284 root
.appendChild(moduleEle
);
287 private boolean isContain(String
[] list
, String item
) {
288 for (int i
= 0; i
< list
.length
; i
++) {
289 if (list
[i
].equalsIgnoreCase(item
)) {
296 private void applyFvs(Document document
, Node root
) {
300 root
.appendChild(document
.createComment("FVs target"));
301 Element ele
= document
.createElement("target");
302 ele
.setAttribute("name", "fvs");
305 // For every Target and ToolChain
307 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
308 for (int i
= 0; i
< targetList
.length
; i
++){
309 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
310 for(int j
= 0; j
< toolchainList
.length
; j
++){
311 String fvOutputDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
312 + targetList
[i
] + "_"
313 + toolchainList
[j
] + File
.separatorChar
+ "FV";
314 String
[] validFv
= saq
.getFpdValidImageNames();
315 for (int k
= 0; k
< validFv
.length
; k
++) {
316 String inputFile
= fvOutputDir
+ "" + File
.separatorChar
+ validFv
[k
].toUpperCase() + ".inf";
317 Element fvEle
= document
.createElement("genfvimage");
318 fvEle
.setAttribute("infFile", inputFile
);
319 fvEle
.setAttribute("outputDir", fvOutputDir
);
320 ele
.appendChild(fvEle
);
324 root
.appendChild(ele
);
327 private void applyClean(Document document
, Node root
) {
331 root
.appendChild(document
.createComment("Clean target"));
332 Element ele
= document
.createElement("target");
333 ele
.setAttribute("name", "clean");
336 Element cleanEle
= document
.createElement("delete");
337 cleanEle
.setAttribute("includeemptydirs", "true");
338 Element filesetEle
= document
.createElement("fileset");
339 filesetEle
.setAttribute("dir", project
.getProperty("BUILD_DIR"));
340 filesetEle
.setAttribute("includes", "**\\OUTPUT\\**");
341 cleanEle
.appendChild(filesetEle
);
342 ele
.appendChild(cleanEle
);
344 Set set
= outfiles
.keySet();
345 Iterator iter
= set
.iterator();
346 while (iter
.hasNext()) {
347 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
348 ModuleIdentification moduleId
= fpdModuleId
.getModule();
350 Element ifEle
= document
.createElement("if");
351 Element availableEle
= document
.createElement("available");
352 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
354 ifEle
.appendChild(availableEle
);
355 Element elseEle
= document
.createElement("then");
357 Element moduleEle
= document
.createElement("ant");
358 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
360 moduleEle
.setAttribute("target", "clean");
362 // Inherit Properties.
363 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
369 Element property
= document
.createElement("property");
370 property
.setAttribute("name", "ARCH");
371 property
.setAttribute("value", fpdModuleId
.getArch());
372 moduleEle
.appendChild(property
);
377 property
= document
.createElement("property");
378 property
.setAttribute("name", "PACKAGE");
379 property
.setAttribute("value", moduleId
.getPackage().getName());
380 moduleEle
.appendChild(property
);
385 property
= document
.createElement("property");
386 property
.setAttribute("name", "PACKAGE_GUID");
387 property
.setAttribute("value", moduleId
.getPackage().getGuid());
388 moduleEle
.appendChild(property
);
393 property
= document
.createElement("property");
394 property
.setAttribute("name", "PACKAGE_VERSION");
395 property
.setAttribute("value", moduleId
.getPackage().getVersion());
396 moduleEle
.appendChild(property
);
401 property
= document
.createElement("property");
402 property
.setAttribute("name", "MODULE_DIR");
403 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
404 moduleEle
.appendChild(property
);
405 elseEle
.appendChild(moduleEle
);
406 ifEle
.appendChild(elseEle
);
407 ele
.appendChild(ifEle
);
410 root
.appendChild(ele
);
413 private void applyCleanall(Document document
, Node root
) {
417 root
.appendChild(document
.createComment("Target: cleanall"));
418 Element ele
= document
.createElement("target");
419 ele
.setAttribute("name", "cleanall");
422 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
423 for (int i
= 0; i
< targetList
.length
; ++i
) {
424 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
425 for(int j
= 0; j
< toolchainList
.length
; j
++) {
426 Element cleanAllEle
= document
.createElement("delete");
427 cleanAllEle
.setAttribute("dir", project
.getProperty("BUILD_DIR") + File
.separatorChar
+ targetList
[i
] + "_" + toolchainList
[j
]);
428 ele
.appendChild(cleanAllEle
);
432 Set set
= outfiles
.keySet();
433 Iterator iter
= set
.iterator();
434 while (iter
.hasNext()) {
435 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
436 ModuleIdentification moduleId
= fpdModuleId
.getModule();
438 Element ifEle
= document
.createElement("if");
439 Element availableEle
= document
.createElement("available");
440 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
442 ifEle
.appendChild(availableEle
);
443 Element elseEle
= document
.createElement("then");
445 Element moduleEle
= document
.createElement("ant");
446 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
448 moduleEle
.setAttribute("target", "cleanall");
450 // Inherit Properties.
451 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
457 Element property
= document
.createElement("property");
458 property
.setAttribute("name", "ARCH");
459 property
.setAttribute("value", fpdModuleId
.getArch());
460 moduleEle
.appendChild(property
);
465 property
= document
.createElement("property");
466 property
.setAttribute("name", "PACKAGE");
467 property
.setAttribute("value", moduleId
.getPackage().getName());
468 moduleEle
.appendChild(property
);
473 property
= document
.createElement("property");
474 property
.setAttribute("name", "PACKAGE_GUID");
475 property
.setAttribute("value", moduleId
.getPackage().getGuid());
476 moduleEle
.appendChild(property
);
481 property
= document
.createElement("property");
482 property
.setAttribute("name", "PACKAGE_VERSION");
483 property
.setAttribute("value", moduleId
.getPackage().getVersion());
484 moduleEle
.appendChild(property
);
489 property
= document
.createElement("property");
490 property
.setAttribute("name", "MODULE_DIR");
491 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
492 moduleEle
.appendChild(property
);
493 elseEle
.appendChild(moduleEle
);
494 ifEle
.appendChild(elseEle
);
495 ele
.appendChild(ifEle
);
498 root
.appendChild(ele
);
501 private void applyUserExtensionsPreBuild(Document document
, Node root
) {
505 root
.appendChild(document
.createComment("Pre-Build Processing"));
506 Element ele
= document
.createElement("target");
507 ele
.setAttribute("name", "prebuild");
509 Node node
= saq
.getFpdUserExtensionPreBuild();
512 // For every Target and ToolChain
514 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
515 for (int i
= 0; i
< targetList
.length
; i
++){
516 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
517 for(int j
= 0; j
< toolchainList
.length
; j
++){
521 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
522 + targetList
[i
] + "_"
524 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
525 Element fvEle
= document
.createElement("var");
526 fvEle
.setAttribute("name", "FV_DIR");
527 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
528 ele
.appendChild(fvEle
);
530 Element targetDirEle
= document
.createElement("var");
531 targetDirEle
.setAttribute("name", "TARGET_DIR");
532 targetDirEle
.setAttribute("value", ffsCommonDir
.replaceAll("(\\\\)", "/"));
533 ele
.appendChild(targetDirEle
);
535 NodeList childNodes
= node
.getChildNodes();
536 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
537 Node childItem
= childNodes
.item(k
);
538 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
539 ele
.appendChild(recursiveNode(childItem
, document
));
546 root
.appendChild(ele
);
549 private void applyUserExtensionsPostBuild(Document document
, Node root
) {
553 root
.appendChild(document
.createComment("Post-Build Processing"));
554 Element ele
= document
.createElement("target");
555 ele
.setAttribute("name", "postbuild");
557 Node node
= saq
.getFpdUserExtensionPostBuild();
560 // For every Target and ToolChain
562 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
563 for (int i
= 0; i
< targetList
.length
; i
++){
564 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
565 for(int j
= 0; j
< toolchainList
.length
; j
++){
569 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
570 + targetList
[i
] + "_"
572 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
573 Element fvEle
= document
.createElement("var");
574 fvEle
.setAttribute("name", "FV_DIR");
575 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
576 ele
.appendChild(fvEle
);
578 Element targetDirEle
= document
.createElement("var");
579 targetDirEle
.setAttribute("name", "TARGET_DIR");
580 targetDirEle
.setAttribute("value", ffsCommonDir
.replaceAll("(\\\\)", "/"));
581 ele
.appendChild(targetDirEle
);
583 NodeList childNodes
= node
.getChildNodes();
584 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
585 Node childItem
= childNodes
.item(k
);
586 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
587 ele
.appendChild(recursiveNode(childItem
, document
));
595 root
.appendChild(ele
);
598 private Element
recursiveNode(Node node
, Document document
) {
599 Element root
= document
.createElement(node
.getNodeName());
600 NamedNodeMap attr
= node
.getAttributes();
601 for (int i
= 0; i
< attr
.getLength(); i
++) {
602 Node attrItem
= attr
.item(i
);
603 root
.setAttribute(attrItem
.getNodeName(), attrItem
.getNodeValue());
605 NodeList childNodes
= node
.getChildNodes();
606 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
607 Node childItem
= childNodes
.item(i
);
608 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
609 root
.appendChild(recursiveNode(childItem
, document
));
611 else if (childItem
.getNodeType() == Node
.TEXT_NODE
){
612 if (!childItem
.getNodeValue().trim().equalsIgnoreCase("")) {
613 root
.setTextContent(childItem
.getNodeValue());