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 Map
<String
, String
> aprioriType
= null;
69 private Project project
;
71 private String info
= "DO NOT EDIT \n"
72 + "This file is auto-generated by the build utility\n"
75 + "Auto-generated ANT build file for building EFI Modules and Platforms\n";
77 public PlatformBuildFileGenerator(Project project
, Map
<FpdModuleIdentification
, String
> outfiles
, Map
<String
, Set
<FpdModuleIdentification
>> fvs
, boolean isUnified
, SurfaceAreaQuery saq
, String platformBuildFile
, Map
<String
, String
> aprioriType
){
78 this.project
= project
;
79 this.outfiles
= outfiles
;
80 this.isUnified
= isUnified
;
83 this.platformBuildFile
= new File(platformBuildFile
);
84 this.aprioriType
= aprioriType
;
88 Generate build.out.xml file.
90 @throws BuildException
91 build.out.xml XML document create error
93 public void genBuildFile() throws BuildException
{
94 DocumentBuilderFactory domfac
= DocumentBuilderFactory
.newInstance();
96 DocumentBuilder dombuilder
= domfac
.newDocumentBuilder();
97 Document document
= dombuilder
.newDocument();
98 Comment rootComment
= document
.createComment(info
);
100 // create root element and its attributes
102 Element root
= document
.createElement("project");
103 root
.setAttribute("name", project
.getProperty("PLATFORM"));
104 root
.setAttribute("default", "all");
105 root
.setAttribute("basedir", ".");
108 // element for External ANT tasks
110 root
.appendChild(document
.createComment("Apply external ANT tasks"));
111 Element ele
= document
.createElement("taskdef");
112 ele
.setAttribute("resource", "GenBuild.tasks");
113 root
.appendChild(ele
);
115 ele
= document
.createElement("taskdef");
116 ele
.setAttribute("resource", "frameworktasks.tasks");
117 root
.appendChild(ele
);
119 ele
= document
.createElement("taskdef");
120 ele
.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
121 root
.appendChild(ele
);
123 ele
= document
.createElement("property");
124 ele
.setAttribute("environment", "env");
125 root
.appendChild(ele
);
130 root
.appendChild(document
.createComment("Default target"));
131 ele
= document
.createElement("target");
132 ele
.setAttribute("name", "all");
133 ele
.setAttribute("depends", "prebuild, modules, fvs, postbuild");
134 root
.appendChild(ele
);
137 // Modules and Fvs Target
139 applyModules(document
, root
);
141 applyFvs(document
, root
);
146 applyClean(document
, root
);
151 applyCleanall(document
, root
);
154 // User Extension pre build
156 applyUserExtensionsPreBuild(document
, root
);
159 // User Extension Post build
161 applyUserExtensionsPostBuild(document
, root
);
162 applyUserExtensions(document
, root
);
164 document
.appendChild(rootComment
);
165 document
.appendChild(root
);
167 // Prepare the DOM document for writing
169 Source source
= new DOMSource(document
);
171 // generate all directory path
173 (new File(platformBuildFile
.getParent())).mkdirs();
174 Result result
= new StreamResult(platformBuildFile
);
176 // Write the DOM document to the file
178 Transformer xformer
= TransformerFactory
.newInstance().newTransformer();
179 xformer
.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
180 xformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
181 xformer
.transform(source
, result
);
182 } catch (Exception ex
) {
183 throw new BuildException("Generating platform build file [" + platformBuildFile
.getPath() + "_build.xml] failed. \n" + ex
.getMessage());
188 1. Get All valid Fv Image Names in sequence
189 2. For each FV, get modules by sequences
192 @param document XML document
195 private void applyModules(Document document
, Node root
) {
196 root
.appendChild(document
.createComment("Modules target"));
197 Element ele
= document
.createElement("target");
198 ele
.setAttribute("name", "modules");
201 // Try to build apriori if necessary
204 // For every Target and ToolChain
206 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
207 for (int i
= 0; i
< targetList
.length
; i
++){
208 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
209 for(int j
= 0; j
< toolchainList
.length
; j
++){
213 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
214 + targetList
[i
] + "_"
216 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
217 Element fvEle
= document
.createElement("var");
218 fvEle
.setAttribute("name", "FV_DIR");
219 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
220 ele
.appendChild(fvEle
);
222 Iterator
<String
> aprIter
= aprioriType
.keySet().iterator();
223 while (aprIter
.hasNext()) {
224 String fvName
= aprIter
.next();
225 Element moduleEle
= document
.createElement("Build_Apriori");
226 moduleEle
.setAttribute("FILENAME", fvName
);
227 moduleEle
.setAttribute("GUID", aprioriType
.get(fvName
));
228 ele
.appendChild(moduleEle
);
234 // Get all valid FV name
236 String
[] validFv
= saq
.getFpdValidImageNames();
239 // For each valid FV, get all modules in sequence
241 for (int i
= 0; i
< validFv
.length
; i
++) {
242 if (fvs
.containsKey(validFv
[i
])) {
243 Set
<FpdModuleIdentification
> set
= fvs
.get(validFv
[i
]);
244 Iterator
<FpdModuleIdentification
> iter
= set
.iterator();
245 while (iter
.hasNext()) {
246 FpdModuleIdentification fpdModuleId
= iter
.next();
247 applySingleModule(document
, ele
, fpdModuleId
);
253 // Get all other modules
255 Iterator
<String
> fvsNameIter
= fvs
.keySet().iterator();
257 while (fvsNameIter
.hasNext()) {
258 String fvName
= fvsNameIter
.next();
259 if (!isContain(validFv
, fvName
)) {
260 Set
<FpdModuleIdentification
> set
= fvs
.get(fvName
);
261 Iterator iter
= set
.iterator();
262 while (iter
.hasNext()) {
263 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
264 applySingleModule(document
, ele
, fpdModuleId
);
269 root
.appendChild(ele
);
272 private void applySingleModule(Document document
, Node root
, FpdModuleIdentification fpdModuleId
) {
273 ModuleIdentification moduleId
= fpdModuleId
.getModule();
274 Element moduleEle
= document
.createElement("GenBuild");
275 moduleEle
.setAttribute("type", "build");
277 // Inherit Properties.
278 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
284 Element property
= document
.createElement("property");
285 property
.setAttribute("name", "ARCH");
286 property
.setAttribute("value", fpdModuleId
.getArch());
287 moduleEle
.appendChild(property
);
292 property
= document
.createElement("property");
293 property
.setAttribute("name", "MODULE_GUID");
294 property
.setAttribute("value", moduleId
.getGuid());
295 moduleEle
.appendChild(property
);
300 property
= document
.createElement("property");
301 property
.setAttribute("name", "MODULE_VERSION");
302 property
.setAttribute("value", moduleId
.getVersion());
303 moduleEle
.appendChild(property
);
308 property
= document
.createElement("property");
309 property
.setAttribute("name", "PACKAGE_GUID");
310 property
.setAttribute("value", moduleId
.getPackage().getGuid());
311 moduleEle
.appendChild(property
);
316 property
= document
.createElement("property");
317 property
.setAttribute("name", "PACKAGE_VERSION");
318 property
.setAttribute("value", moduleId
.getPackage().getVersion());
319 moduleEle
.appendChild(property
);
321 root
.appendChild(moduleEle
);
324 private boolean isContain(String
[] list
, String item
) {
325 for (int i
= 0; i
< list
.length
; i
++) {
326 if (list
[i
].equalsIgnoreCase(item
)) {
333 private void applyFvs(Document document
, Node root
) {
337 root
.appendChild(document
.createComment("FVs target"));
338 Element ele
= document
.createElement("target");
339 ele
.setAttribute("name", "fvs");
342 // For every Target and ToolChain
344 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
345 for (int i
= 0; i
< targetList
.length
; i
++){
346 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
347 for(int j
= 0; j
< toolchainList
.length
; j
++){
348 String fvOutputDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
349 + targetList
[i
] + "_"
350 + toolchainList
[j
] + File
.separatorChar
+ "FV";
351 String
[] validFv
= saq
.getFpdValidImageNames();
352 for (int k
= 0; k
< validFv
.length
; k
++) {
353 String inputFile
= fvOutputDir
+ "" + File
.separatorChar
+ validFv
[k
].toUpperCase() + ".inf";
354 Element fvEle
= document
.createElement("genfvimage");
355 fvEle
.setAttribute("infFile", inputFile
);
356 fvEle
.setAttribute("outputDir", fvOutputDir
);
357 ele
.appendChild(fvEle
);
361 root
.appendChild(ele
);
364 private void applyClean(Document document
, Node root
) {
368 root
.appendChild(document
.createComment("Clean target"));
369 Element ele
= document
.createElement("target");
370 ele
.setAttribute("name", "clean");
373 Element cleanEle
= document
.createElement("delete");
374 cleanEle
.setAttribute("includeemptydirs", "true");
375 Element filesetEle
= document
.createElement("fileset");
376 filesetEle
.setAttribute("dir", project
.getProperty("BUILD_DIR"));
377 filesetEle
.setAttribute("includes", "**\\OUTPUT\\**");
378 cleanEle
.appendChild(filesetEle
);
379 ele
.appendChild(cleanEle
);
381 Set set
= outfiles
.keySet();
382 Iterator iter
= set
.iterator();
383 while (iter
.hasNext()) {
384 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
385 ModuleIdentification moduleId
= fpdModuleId
.getModule();
387 Element ifEle
= document
.createElement("if");
388 Element availableEle
= document
.createElement("available");
389 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
391 ifEle
.appendChild(availableEle
);
392 Element elseEle
= document
.createElement("then");
394 Element moduleEle
= document
.createElement("ant");
395 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
397 moduleEle
.setAttribute("target", "clean");
399 // Inherit Properties.
400 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
406 Element property
= document
.createElement("property");
407 property
.setAttribute("name", "ARCH");
408 property
.setAttribute("value", fpdModuleId
.getArch());
409 moduleEle
.appendChild(property
);
414 property
= document
.createElement("property");
415 property
.setAttribute("name", "PACKAGE");
416 property
.setAttribute("value", moduleId
.getPackage().getName());
417 moduleEle
.appendChild(property
);
422 property
= document
.createElement("property");
423 property
.setAttribute("name", "PACKAGE_GUID");
424 property
.setAttribute("value", moduleId
.getPackage().getGuid());
425 moduleEle
.appendChild(property
);
430 property
= document
.createElement("property");
431 property
.setAttribute("name", "PACKAGE_VERSION");
432 property
.setAttribute("value", moduleId
.getPackage().getVersion());
433 moduleEle
.appendChild(property
);
438 property
= document
.createElement("property");
439 property
.setAttribute("name", "MODULE_DIR");
440 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
441 moduleEle
.appendChild(property
);
442 elseEle
.appendChild(moduleEle
);
443 ifEle
.appendChild(elseEle
);
444 ele
.appendChild(ifEle
);
447 root
.appendChild(ele
);
450 private void applyCleanall(Document document
, Node root
) {
454 root
.appendChild(document
.createComment("Target: cleanall"));
455 Element ele
= document
.createElement("target");
456 ele
.setAttribute("name", "cleanall");
459 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
460 for (int i
= 0; i
< targetList
.length
; ++i
) {
461 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
462 for(int j
= 0; j
< toolchainList
.length
; j
++) {
463 Element cleanAllEle
= document
.createElement("delete");
464 cleanAllEle
.setAttribute("dir", project
.getProperty("BUILD_DIR") + File
.separatorChar
+ targetList
[i
] + "_" + toolchainList
[j
]);
465 ele
.appendChild(cleanAllEle
);
469 Set set
= outfiles
.keySet();
470 Iterator iter
= set
.iterator();
471 while (iter
.hasNext()) {
472 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
473 ModuleIdentification moduleId
= fpdModuleId
.getModule();
475 Element ifEle
= document
.createElement("if");
476 Element availableEle
= document
.createElement("available");
477 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
479 ifEle
.appendChild(availableEle
);
480 Element elseEle
= document
.createElement("then");
482 Element moduleEle
= document
.createElement("ant");
483 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
485 moduleEle
.setAttribute("target", "cleanall");
487 // Inherit Properties.
488 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
494 Element property
= document
.createElement("property");
495 property
.setAttribute("name", "ARCH");
496 property
.setAttribute("value", fpdModuleId
.getArch());
497 moduleEle
.appendChild(property
);
502 property
= document
.createElement("property");
503 property
.setAttribute("name", "PACKAGE");
504 property
.setAttribute("value", moduleId
.getPackage().getName());
505 moduleEle
.appendChild(property
);
510 property
= document
.createElement("property");
511 property
.setAttribute("name", "PACKAGE_GUID");
512 property
.setAttribute("value", moduleId
.getPackage().getGuid());
513 moduleEle
.appendChild(property
);
518 property
= document
.createElement("property");
519 property
.setAttribute("name", "PACKAGE_VERSION");
520 property
.setAttribute("value", moduleId
.getPackage().getVersion());
521 moduleEle
.appendChild(property
);
526 property
= document
.createElement("property");
527 property
.setAttribute("name", "MODULE_DIR");
528 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
529 moduleEle
.appendChild(property
);
530 elseEle
.appendChild(moduleEle
);
531 ifEle
.appendChild(elseEle
);
532 ele
.appendChild(ifEle
);
535 root
.appendChild(ele
);
538 private void applyUserExtensionsPreBuild(Document document
, Node root
) {
542 root
.appendChild(document
.createComment("Pre-Build Processing"));
543 Element ele
= document
.createElement("target");
544 ele
.setAttribute("name", "prebuild");
546 Node node
= saq
.getFpdUserExtensionPreBuild();
549 // For every Target and ToolChain
551 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
552 for (int i
= 0; i
< targetList
.length
; i
++){
553 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
554 for(int j
= 0; j
< toolchainList
.length
; j
++){
558 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
559 + targetList
[i
] + "_"
561 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
562 Element fvEle
= document
.createElement("var");
563 fvEle
.setAttribute("name", "FV_DIR");
564 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
565 ele
.appendChild(fvEle
);
567 Element targetDirEle
= document
.createElement("var");
568 targetDirEle
.setAttribute("name", "TARGET_DIR");
569 targetDirEle
.setAttribute("value", ffsCommonDir
.replaceAll("(\\\\)", "/"));
570 ele
.appendChild(targetDirEle
);
572 NodeList childNodes
= node
.getChildNodes();
573 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
574 Node childItem
= childNodes
.item(k
);
575 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
576 ele
.appendChild(recursiveNode(childItem
, document
));
583 root
.appendChild(ele
);
586 private void applyUserExtensionsPostBuild(Document document
, Node root
) {
590 root
.appendChild(document
.createComment("Post-Build Processing"));
591 Element ele
= document
.createElement("target");
592 ele
.setAttribute("name", "postbuild");
594 Node node
= saq
.getFpdUserExtensionPostBuild();
597 // For every Target and ToolChain
599 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
600 for (int i
= 0; i
< targetList
.length
; i
++){
601 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
602 for(int j
= 0; j
< toolchainList
.length
; j
++){
606 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
607 + targetList
[i
] + "_"
609 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
610 Element fvEle
= document
.createElement("var");
611 fvEle
.setAttribute("name", "FV_DIR");
612 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
613 ele
.appendChild(fvEle
);
615 Element targetDirEle
= document
.createElement("var");
616 targetDirEle
.setAttribute("name", "TARGET_DIR");
617 targetDirEle
.setAttribute("value", ffsCommonDir
.replaceAll("(\\\\)", "/"));
618 ele
.appendChild(targetDirEle
);
620 NodeList childNodes
= node
.getChildNodes();
621 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
622 Node childItem
= childNodes
.item(k
);
623 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
624 ele
.appendChild(recursiveNode(childItem
, document
));
632 root
.appendChild(ele
);
635 private void applyUserExtensions(Document document
, Node root
) {
636 Node
[] nodeList
= saq
.getFpdUserExtensions();
637 for (int nodeIndex
= 0; nodeIndex
< nodeList
.length
; ++nodeIndex
) {
638 Node node
= nodeList
[nodeIndex
];
642 root
.appendChild(document
.createComment("User Defined Target"));
643 Element ele
= document
.createElement("target");
644 ele
.setAttribute("name", node
.getAttributes().getNamedItem("Identifier").getNodeValue());
648 // For every Target and ToolChain
650 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
651 for (int i
= 0; i
< targetList
.length
; i
++){
652 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
653 for(int j
= 0; j
< toolchainList
.length
; j
++){
657 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
658 + targetList
[i
] + "_"
660 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
661 Element fvEle
= document
.createElement("var");
662 fvEle
.setAttribute("name", "FV_DIR");
663 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
664 ele
.appendChild(fvEle
);
666 Element targetDirEle
= document
.createElement("var");
667 targetDirEle
.setAttribute("name", "TARGET_DIR");
668 targetDirEle
.setAttribute("value", ffsCommonDir
.replaceAll("(\\\\)", "/"));
669 ele
.appendChild(targetDirEle
);
671 NodeList childNodes
= node
.getChildNodes();
672 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
673 Node childItem
= childNodes
.item(k
);
674 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
675 ele
.appendChild(recursiveNode(childItem
, document
));
683 root
.appendChild(ele
);
687 private Element
recursiveNode(Node node
, Document document
) {
688 Element root
= document
.createElement(node
.getNodeName());
689 NamedNodeMap attr
= node
.getAttributes();
690 for (int i
= 0; i
< attr
.getLength(); i
++) {
691 Node attrItem
= attr
.item(i
);
692 root
.setAttribute(attrItem
.getNodeName(), attrItem
.getNodeValue());
694 NodeList childNodes
= node
.getChildNodes();
695 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
696 Node childItem
= childNodes
.item(i
);
697 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
698 root
.appendChild(recursiveNode(childItem
, document
));
700 else if (childItem
.getNodeType() == Node
.TEXT_NODE
){
701 if (!childItem
.getNodeValue().trim().equalsIgnoreCase("")) {
702 root
.setTextContent(childItem
.getNodeValue());