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
);
163 document
.appendChild(rootComment
);
164 document
.appendChild(root
);
166 // Prepare the DOM document for writing
168 Source source
= new DOMSource(document
);
170 // generate all directory path
172 (new File(platformBuildFile
.getParent())).mkdirs();
173 Result result
= new StreamResult(platformBuildFile
);
175 // Write the DOM document to the file
177 Transformer xformer
= TransformerFactory
.newInstance().newTransformer();
178 xformer
.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
179 xformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
180 xformer
.transform(source
, result
);
181 } catch (Exception ex
) {
182 throw new BuildException("Generating platform build file [" + platformBuildFile
.getPath() + "_build.xml] failed. \n" + ex
.getMessage());
187 1. Get All valid Fv Image Names in sequence
188 2. For each FV, get modules by sequences
191 @param document XML document
194 private void applyModules(Document document
, Node root
) {
195 root
.appendChild(document
.createComment("Modules target"));
196 Element ele
= document
.createElement("target");
197 ele
.setAttribute("name", "modules");
200 // Try to build apriori if necessary
203 // For every Target and ToolChain
205 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
206 for (int i
= 0; i
< targetList
.length
; i
++){
207 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
208 for(int j
= 0; j
< toolchainList
.length
; j
++){
212 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
213 + targetList
[i
] + "_"
215 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
216 Element fvEle
= document
.createElement("var");
217 fvEle
.setAttribute("name", "FV_DIR");
218 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
219 ele
.appendChild(fvEle
);
221 Iterator
<String
> aprIter
= aprioriType
.keySet().iterator();
222 while (aprIter
.hasNext()) {
223 String fvName
= aprIter
.next();
224 Element moduleEle
= document
.createElement("Build_Apriori");
225 moduleEle
.setAttribute("FILENAME", fvName
);
226 moduleEle
.setAttribute("GUID", aprioriType
.get(fvName
));
227 ele
.appendChild(moduleEle
);
233 // Get all valid FV name
235 String
[] validFv
= saq
.getFpdValidImageNames();
238 // For each valid FV, get all modules in sequence
240 for (int i
= 0; i
< validFv
.length
; i
++) {
241 if (fvs
.containsKey(validFv
[i
])) {
242 Set
<FpdModuleIdentification
> set
= fvs
.get(validFv
[i
]);
243 Iterator
<FpdModuleIdentification
> iter
= set
.iterator();
244 while (iter
.hasNext()) {
245 FpdModuleIdentification fpdModuleId
= iter
.next();
246 applySingleModule(document
, ele
, fpdModuleId
);
252 // Get all other modules
254 Iterator
<String
> fvsNameIter
= fvs
.keySet().iterator();
256 while (fvsNameIter
.hasNext()) {
257 String fvName
= fvsNameIter
.next();
258 if (!isContain(validFv
, fvName
)) {
259 Set
<FpdModuleIdentification
> set
= fvs
.get(fvName
);
260 Iterator iter
= set
.iterator();
261 while (iter
.hasNext()) {
262 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
263 applySingleModule(document
, ele
, fpdModuleId
);
268 root
.appendChild(ele
);
271 private void applySingleModule(Document document
, Node root
, FpdModuleIdentification fpdModuleId
) {
272 ModuleIdentification moduleId
= fpdModuleId
.getModule();
273 Element moduleEle
= document
.createElement("GenBuild");
274 moduleEle
.setAttribute("type", "build");
276 // Inherit Properties.
277 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
283 Element property
= document
.createElement("property");
284 property
.setAttribute("name", "ARCH");
285 property
.setAttribute("value", fpdModuleId
.getArch());
286 moduleEle
.appendChild(property
);
291 property
= document
.createElement("property");
292 property
.setAttribute("name", "MODULE_GUID");
293 property
.setAttribute("value", moduleId
.getGuid());
294 moduleEle
.appendChild(property
);
299 property
= document
.createElement("property");
300 property
.setAttribute("name", "MODULE_VERSION");
301 property
.setAttribute("value", moduleId
.getVersion());
302 moduleEle
.appendChild(property
);
307 property
= document
.createElement("property");
308 property
.setAttribute("name", "PACKAGE_GUID");
309 property
.setAttribute("value", moduleId
.getPackage().getGuid());
310 moduleEle
.appendChild(property
);
315 property
= document
.createElement("property");
316 property
.setAttribute("name", "PACKAGE_VERSION");
317 property
.setAttribute("value", moduleId
.getPackage().getVersion());
318 moduleEle
.appendChild(property
);
320 root
.appendChild(moduleEle
);
323 private boolean isContain(String
[] list
, String item
) {
324 for (int i
= 0; i
< list
.length
; i
++) {
325 if (list
[i
].equalsIgnoreCase(item
)) {
332 private void applyFvs(Document document
, Node root
) {
336 root
.appendChild(document
.createComment("FVs target"));
337 Element ele
= document
.createElement("target");
338 ele
.setAttribute("name", "fvs");
341 // For every Target and ToolChain
343 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
344 for (int i
= 0; i
< targetList
.length
; i
++){
345 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
346 for(int j
= 0; j
< toolchainList
.length
; j
++){
347 String fvOutputDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
348 + targetList
[i
] + "_"
349 + toolchainList
[j
] + File
.separatorChar
+ "FV";
350 String
[] validFv
= saq
.getFpdValidImageNames();
351 for (int k
= 0; k
< validFv
.length
; k
++) {
352 String inputFile
= fvOutputDir
+ "" + File
.separatorChar
+ validFv
[k
].toUpperCase() + ".inf";
353 Element fvEle
= document
.createElement("genfvimage");
354 fvEle
.setAttribute("infFile", inputFile
);
355 fvEle
.setAttribute("outputDir", fvOutputDir
);
356 ele
.appendChild(fvEle
);
360 root
.appendChild(ele
);
363 private void applyClean(Document document
, Node root
) {
367 root
.appendChild(document
.createComment("Clean target"));
368 Element ele
= document
.createElement("target");
369 ele
.setAttribute("name", "clean");
372 Element cleanEle
= document
.createElement("delete");
373 cleanEle
.setAttribute("includeemptydirs", "true");
374 Element filesetEle
= document
.createElement("fileset");
375 filesetEle
.setAttribute("dir", project
.getProperty("BUILD_DIR"));
376 filesetEle
.setAttribute("includes", "**\\OUTPUT\\**");
377 cleanEle
.appendChild(filesetEle
);
378 ele
.appendChild(cleanEle
);
380 Set set
= outfiles
.keySet();
381 Iterator iter
= set
.iterator();
382 while (iter
.hasNext()) {
383 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
384 ModuleIdentification moduleId
= fpdModuleId
.getModule();
386 Element ifEle
= document
.createElement("if");
387 Element availableEle
= document
.createElement("available");
388 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
390 ifEle
.appendChild(availableEle
);
391 Element elseEle
= document
.createElement("then");
393 Element moduleEle
= document
.createElement("ant");
394 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
396 moduleEle
.setAttribute("target", "clean");
398 // Inherit Properties.
399 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
405 Element property
= document
.createElement("property");
406 property
.setAttribute("name", "ARCH");
407 property
.setAttribute("value", fpdModuleId
.getArch());
408 moduleEle
.appendChild(property
);
413 property
= document
.createElement("property");
414 property
.setAttribute("name", "PACKAGE");
415 property
.setAttribute("value", moduleId
.getPackage().getName());
416 moduleEle
.appendChild(property
);
421 property
= document
.createElement("property");
422 property
.setAttribute("name", "PACKAGE_GUID");
423 property
.setAttribute("value", moduleId
.getPackage().getGuid());
424 moduleEle
.appendChild(property
);
429 property
= document
.createElement("property");
430 property
.setAttribute("name", "PACKAGE_VERSION");
431 property
.setAttribute("value", moduleId
.getPackage().getVersion());
432 moduleEle
.appendChild(property
);
437 property
= document
.createElement("property");
438 property
.setAttribute("name", "MODULE_DIR");
439 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
440 moduleEle
.appendChild(property
);
441 elseEle
.appendChild(moduleEle
);
442 ifEle
.appendChild(elseEle
);
443 ele
.appendChild(ifEle
);
446 root
.appendChild(ele
);
449 private void applyCleanall(Document document
, Node root
) {
453 root
.appendChild(document
.createComment("Target: cleanall"));
454 Element ele
= document
.createElement("target");
455 ele
.setAttribute("name", "cleanall");
458 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
459 for (int i
= 0; i
< targetList
.length
; ++i
) {
460 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
461 for(int j
= 0; j
< toolchainList
.length
; j
++) {
462 Element cleanAllEle
= document
.createElement("delete");
463 cleanAllEle
.setAttribute("dir", project
.getProperty("BUILD_DIR") + File
.separatorChar
+ targetList
[i
] + "_" + toolchainList
[j
]);
464 ele
.appendChild(cleanAllEle
);
468 Set set
= outfiles
.keySet();
469 Iterator iter
= set
.iterator();
470 while (iter
.hasNext()) {
471 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
472 ModuleIdentification moduleId
= fpdModuleId
.getModule();
474 Element ifEle
= document
.createElement("if");
475 Element availableEle
= document
.createElement("available");
476 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
478 ifEle
.appendChild(availableEle
);
479 Element elseEle
= document
.createElement("then");
481 Element moduleEle
= document
.createElement("ant");
482 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
484 moduleEle
.setAttribute("target", "cleanall");
486 // Inherit Properties.
487 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
493 Element property
= document
.createElement("property");
494 property
.setAttribute("name", "ARCH");
495 property
.setAttribute("value", fpdModuleId
.getArch());
496 moduleEle
.appendChild(property
);
501 property
= document
.createElement("property");
502 property
.setAttribute("name", "PACKAGE");
503 property
.setAttribute("value", moduleId
.getPackage().getName());
504 moduleEle
.appendChild(property
);
509 property
= document
.createElement("property");
510 property
.setAttribute("name", "PACKAGE_GUID");
511 property
.setAttribute("value", moduleId
.getPackage().getGuid());
512 moduleEle
.appendChild(property
);
517 property
= document
.createElement("property");
518 property
.setAttribute("name", "PACKAGE_VERSION");
519 property
.setAttribute("value", moduleId
.getPackage().getVersion());
520 moduleEle
.appendChild(property
);
525 property
= document
.createElement("property");
526 property
.setAttribute("name", "MODULE_DIR");
527 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
528 moduleEle
.appendChild(property
);
529 elseEle
.appendChild(moduleEle
);
530 ifEle
.appendChild(elseEle
);
531 ele
.appendChild(ifEle
);
534 root
.appendChild(ele
);
537 private void applyUserExtensionsPreBuild(Document document
, Node root
) {
541 root
.appendChild(document
.createComment("Pre-Build Processing"));
542 Element ele
= document
.createElement("target");
543 ele
.setAttribute("name", "prebuild");
545 Node node
= saq
.getFpdUserExtensionPreBuild();
548 // For every Target and ToolChain
550 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
551 for (int i
= 0; i
< targetList
.length
; i
++){
552 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
553 for(int j
= 0; j
< toolchainList
.length
; j
++){
557 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
558 + targetList
[i
] + "_"
560 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
561 Element fvEle
= document
.createElement("var");
562 fvEle
.setAttribute("name", "FV_DIR");
563 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
564 ele
.appendChild(fvEle
);
566 Element targetDirEle
= document
.createElement("var");
567 targetDirEle
.setAttribute("name", "TARGET_DIR");
568 targetDirEle
.setAttribute("value", ffsCommonDir
.replaceAll("(\\\\)", "/"));
569 ele
.appendChild(targetDirEle
);
571 NodeList childNodes
= node
.getChildNodes();
572 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
573 Node childItem
= childNodes
.item(k
);
574 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
575 ele
.appendChild(recursiveNode(childItem
, document
));
582 root
.appendChild(ele
);
585 private void applyUserExtensionsPostBuild(Document document
, Node root
) {
589 root
.appendChild(document
.createComment("Post-Build Processing"));
590 Element ele
= document
.createElement("target");
591 ele
.setAttribute("name", "postbuild");
593 Node node
= saq
.getFpdUserExtensionPostBuild();
596 // For every Target and ToolChain
598 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
599 for (int i
= 0; i
< targetList
.length
; i
++){
600 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
601 for(int j
= 0; j
< toolchainList
.length
; j
++){
605 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
606 + targetList
[i
] + "_"
608 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
609 Element fvEle
= document
.createElement("var");
610 fvEle
.setAttribute("name", "FV_DIR");
611 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
612 ele
.appendChild(fvEle
);
614 Element targetDirEle
= document
.createElement("var");
615 targetDirEle
.setAttribute("name", "TARGET_DIR");
616 targetDirEle
.setAttribute("value", ffsCommonDir
.replaceAll("(\\\\)", "/"));
617 ele
.appendChild(targetDirEle
);
619 NodeList childNodes
= node
.getChildNodes();
620 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
621 Node childItem
= childNodes
.item(k
);
622 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
623 ele
.appendChild(recursiveNode(childItem
, document
));
631 root
.appendChild(ele
);
634 private Element
recursiveNode(Node node
, Document document
) {
635 Element root
= document
.createElement(node
.getNodeName());
636 NamedNodeMap attr
= node
.getAttributes();
637 for (int i
= 0; i
< attr
.getLength(); i
++) {
638 Node attrItem
= attr
.item(i
);
639 root
.setAttribute(attrItem
.getNodeName(), attrItem
.getNodeValue());
641 NodeList childNodes
= node
.getChildNodes();
642 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
643 Node childItem
= childNodes
.item(i
);
644 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
645 root
.appendChild(recursiveNode(childItem
, document
));
647 else if (childItem
.getNodeType() == Node
.TEXT_NODE
){
648 if (!childItem
.getNodeValue().trim().equalsIgnoreCase("")) {
649 root
.setTextContent(childItem
.getNodeValue());