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
{
50 private String platformName
;
53 /// Mapping from modules identification to out put file name
55 private Map
<FpdModuleIdentification
, String
> outfiles
;
58 /// Mapping from FV name to its modules
60 private Map
<String
, Set
<FpdModuleIdentification
>> fvs
= new HashMap
<String
, Set
<FpdModuleIdentification
>>();
63 private boolean isUnified
= true;
65 private Project project
;
67 private String info
= "DO NOT EDIT \n"
68 + "This file is auto-generated by the build utility\n"
71 + "Auto-generated ANT build file for building EFI Modules and Platforms\n";
73 public PlatformBuildFileGenerator(Project project
, Map
<FpdModuleIdentification
, String
> outfiles
, Map
<String
, Set
<FpdModuleIdentification
>> fvs
, boolean isUnified
){
74 this.project
= project
;
75 this.outfiles
= outfiles
;
76 this.isUnified
= isUnified
;
78 this.platformName
= project
.getProperty("PLATFORM");
82 Generate build.out.xml file.
84 @throws BuildException
85 build.out.xml XML document create error
87 public void genBuildFile() throws BuildException
{
88 DocumentBuilderFactory domfac
= DocumentBuilderFactory
.newInstance();
90 DocumentBuilder dombuilder
= domfac
.newDocumentBuilder();
91 Document document
= dombuilder
.newDocument();
92 Comment rootComment
= document
.createComment(info
);
94 // create root element and its attributes
96 Element root
= document
.createElement("project");
97 root
.setAttribute("name", project
.getProperty("PLATFORM"));
98 root
.setAttribute("default", "all");
99 root
.setAttribute("basedir", ".");
102 // element for External ANT tasks
104 root
.appendChild(document
.createComment("Apply external ANT tasks"));
105 Element ele
= document
.createElement("taskdef");
106 ele
.setAttribute("resource", "GenBuild.tasks");
107 root
.appendChild(ele
);
109 ele
= document
.createElement("taskdef");
110 ele
.setAttribute("resource", "frameworktasks.tasks");
111 root
.appendChild(ele
);
113 ele
= document
.createElement("taskdef");
114 ele
.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
115 root
.appendChild(ele
);
117 ele
= document
.createElement("property");
118 ele
.setAttribute("environment", "env");
119 root
.appendChild(ele
);
124 root
.appendChild(document
.createComment("Default target"));
125 ele
= document
.createElement("target");
126 ele
.setAttribute("name", "all");
127 ele
.setAttribute("depends", "prebuild, modules, fvs, postbuild");
128 root
.appendChild(ele
);
131 // Modules and Fvs Target
133 applyModules(document
, root
);
135 applyFvs(document
, root
);
140 applyClean(document
, root
);
145 applyCleanall(document
, root
);
148 // User Extension pre build
150 applyUserExtensionsPreBuild(document
, root
);
153 // User Extension Post build
155 applyUserExtensionsPostBuild(document
, root
);
157 document
.appendChild(rootComment
);
158 document
.appendChild(root
);
160 // Prepare the DOM document for writing
162 Source source
= new DOMSource(document
);
164 // Prepare the output file
166 File file
= new File(project
.getProperty("PLATFORM_DIR") + File
.separatorChar
+ platformName
+ "_build.xml");
168 // generate all directory path
170 (new File(file
.getParent())).mkdirs();
171 Result result
= new StreamResult(file
);
173 // Write the DOM document to the file
175 Transformer xformer
= TransformerFactory
.newInstance().newTransformer();
176 xformer
.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
177 xformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
178 xformer
.transform(source
, result
);
179 } catch (Exception ex
) {
180 throw new BuildException("Generation of the " + platformName
+ "_build.xml failed!\n" + ex
.getMessage());
185 1. Get All valid Fv Image Names in sequence
186 2. For each FV, get modules by sequences
189 @param document XML document
192 private void applyModules(Document document
, Node root
) {
193 root
.appendChild(document
.createComment("Modules target"));
194 Element ele
= document
.createElement("target");
195 ele
.setAttribute("name", "modules");
198 // Get all valid FV name
200 String
[] validFv
= SurfaceAreaQuery
.getFpdValidImageNames();
203 // For each valid FV, get all modules in sequence
205 for (int i
= 0; i
< validFv
.length
; i
++) {
206 if (fvs
.containsKey(validFv
[i
])) {
207 Set
<FpdModuleIdentification
> set
= fvs
.get(validFv
[i
]);
208 Iterator
<FpdModuleIdentification
> iter
= set
.iterator();
209 while (iter
.hasNext()) {
210 FpdModuleIdentification fpdModuleId
= iter
.next();
211 applySingleModule(document
, ele
, fpdModuleId
);
217 // Get all other modules
219 Iterator
<String
> fvsNameIter
= fvs
.keySet().iterator();
221 while (fvsNameIter
.hasNext()) {
222 String fvName
= fvsNameIter
.next();
223 if (!isContain(validFv
, fvName
)) {
224 Set
<FpdModuleIdentification
> set
= fvs
.get(fvName
);
225 Iterator iter
= set
.iterator();
226 while (iter
.hasNext()) {
227 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
228 applySingleModule(document
, ele
, fpdModuleId
);
233 root
.appendChild(ele
);
236 private void applySingleModule(Document document
, Node root
, FpdModuleIdentification fpdModuleId
) {
237 ModuleIdentification moduleId
= fpdModuleId
.getModule();
238 Element moduleEle
= document
.createElement("GenBuild");
239 moduleEle
.setAttribute("type", "build");
241 // Inherit Properties.
242 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
248 Element property
= document
.createElement("property");
249 property
.setAttribute("name", "ARCH");
250 property
.setAttribute("value", fpdModuleId
.getArch());
251 moduleEle
.appendChild(property
);
256 property
= document
.createElement("property");
257 property
.setAttribute("name", "MODULE_GUID");
258 property
.setAttribute("value", moduleId
.getGuid());
259 moduleEle
.appendChild(property
);
264 property
= document
.createElement("property");
265 property
.setAttribute("name", "MODULE_VERSION");
266 property
.setAttribute("value", moduleId
.getVersion());
267 moduleEle
.appendChild(property
);
272 property
= document
.createElement("property");
273 property
.setAttribute("name", "PACKAGE_GUID");
274 property
.setAttribute("value", moduleId
.getPackage().getGuid());
275 moduleEle
.appendChild(property
);
280 property
= document
.createElement("property");
281 property
.setAttribute("name", "PACKAGE_VERSION");
282 property
.setAttribute("value", moduleId
.getPackage().getVersion());
283 moduleEle
.appendChild(property
);
285 root
.appendChild(moduleEle
);
288 private boolean isContain(String
[] list
, String item
) {
289 for (int i
= 0; i
< list
.length
; i
++) {
290 if (list
[i
].equalsIgnoreCase(item
)) {
297 private void applyFvs(Document document
, Node root
) {
301 root
.appendChild(document
.createComment("FVs target"));
302 Element ele
= document
.createElement("target");
303 ele
.setAttribute("name", "fvs");
306 // For every Target and ToolChain
308 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
309 for (int i
= 0; i
< targetList
.length
; i
++){
310 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
311 for(int j
= 0; j
< toolchainList
.length
; j
++){
312 String fvOutputDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
313 + targetList
[i
] + File
.separatorChar
314 + toolchainList
[j
] + File
.separatorChar
+ "FV";
315 String
[] validFv
= SurfaceAreaQuery
.getFpdValidImageNames();
316 for (int k
= 0; k
< validFv
.length
; k
++) {
317 String inputFile
= fvOutputDir
+ "" + File
.separatorChar
+ validFv
[k
].toUpperCase() + ".inf";
318 Element fvEle
= document
.createElement("genfvimage");
319 fvEle
.setAttribute("infFile", inputFile
);
320 fvEle
.setAttribute("outputDir", fvOutputDir
);
321 ele
.appendChild(fvEle
);
325 root
.appendChild(ele
);
328 private void applyClean(Document document
, Node root
) {
332 root
.appendChild(document
.createComment("Clean target"));
333 Element ele
= document
.createElement("target");
334 ele
.setAttribute("name", "clean");
337 Element cleanEle
= document
.createElement("delete");
338 cleanEle
.setAttribute("includeemptydirs", "true");
339 Element filesetEle
= document
.createElement("fileset");
340 filesetEle
.setAttribute("dir", project
.getProperty("BUILD_DIR"));
341 filesetEle
.setAttribute("includes", "**\\OUTPUT\\**");
342 cleanEle
.appendChild(filesetEle
);
343 ele
.appendChild(cleanEle
);
345 Set set
= outfiles
.keySet();
346 Iterator iter
= set
.iterator();
347 while (iter
.hasNext()) {
348 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
349 ModuleIdentification moduleId
= fpdModuleId
.getModule();
351 Element ifEle
= document
.createElement("if");
352 Element availableEle
= document
.createElement("available");
353 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
355 ifEle
.appendChild(availableEle
);
356 Element elseEle
= document
.createElement("then");
358 Element moduleEle
= document
.createElement("ant");
359 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
361 moduleEle
.setAttribute("target", "clean");
363 // Inherit Properties.
364 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
370 Element property
= document
.createElement("property");
371 property
.setAttribute("name", "ARCH");
372 property
.setAttribute("value", fpdModuleId
.getArch());
373 moduleEle
.appendChild(property
);
378 property
= document
.createElement("property");
379 property
.setAttribute("name", "PACKAGE");
380 property
.setAttribute("value", moduleId
.getPackage().getName());
381 moduleEle
.appendChild(property
);
386 property
= document
.createElement("property");
387 property
.setAttribute("name", "PACKAGE_GUID");
388 property
.setAttribute("value", moduleId
.getPackage().getGuid());
389 moduleEle
.appendChild(property
);
394 property
= document
.createElement("property");
395 property
.setAttribute("name", "PACKAGE_VERSION");
396 property
.setAttribute("value", moduleId
.getPackage().getVersion());
397 moduleEle
.appendChild(property
);
402 property
= document
.createElement("property");
403 property
.setAttribute("name", "MODULE_DIR");
404 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
405 moduleEle
.appendChild(property
);
406 elseEle
.appendChild(moduleEle
);
407 ifEle
.appendChild(elseEle
);
408 ele
.appendChild(ifEle
);
411 root
.appendChild(ele
);
414 private void applyCleanall(Document document
, Node root
) {
418 root
.appendChild(document
.createComment("Target: cleanall"));
419 Element ele
= document
.createElement("target");
420 ele
.setAttribute("name", "cleanall");
423 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
424 for (int i
= 0; i
< targetList
.length
; ++i
) {
425 Element cleanAllEle
= document
.createElement("delete");
426 cleanAllEle
.setAttribute("dir", project
.getProperty("BUILD_DIR") + File
.separatorChar
+ targetList
[i
]);
427 ele
.appendChild(cleanAllEle
);
430 Set set
= outfiles
.keySet();
431 Iterator iter
= set
.iterator();
432 while (iter
.hasNext()) {
433 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
434 ModuleIdentification moduleId
= fpdModuleId
.getModule();
436 Element ifEle
= document
.createElement("if");
437 Element availableEle
= document
.createElement("available");
438 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
440 ifEle
.appendChild(availableEle
);
441 Element elseEle
= document
.createElement("then");
443 Element moduleEle
= document
.createElement("ant");
444 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
446 moduleEle
.setAttribute("target", "cleanall");
448 // Inherit Properties.
449 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
455 Element property
= document
.createElement("property");
456 property
.setAttribute("name", "ARCH");
457 property
.setAttribute("value", fpdModuleId
.getArch());
458 moduleEle
.appendChild(property
);
463 property
= document
.createElement("property");
464 property
.setAttribute("name", "PACKAGE");
465 property
.setAttribute("value", moduleId
.getPackage().getName());
466 moduleEle
.appendChild(property
);
471 property
= document
.createElement("property");
472 property
.setAttribute("name", "PACKAGE_GUID");
473 property
.setAttribute("value", moduleId
.getPackage().getGuid());
474 moduleEle
.appendChild(property
);
479 property
= document
.createElement("property");
480 property
.setAttribute("name", "PACKAGE_VERSION");
481 property
.setAttribute("value", moduleId
.getPackage().getVersion());
482 moduleEle
.appendChild(property
);
487 property
= document
.createElement("property");
488 property
.setAttribute("name", "MODULE_DIR");
489 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
490 moduleEle
.appendChild(property
);
491 elseEle
.appendChild(moduleEle
);
492 ifEle
.appendChild(elseEle
);
493 ele
.appendChild(ifEle
);
496 root
.appendChild(ele
);
499 private void applyUserExtensionsPreBuild(Document document
, Node root
) {
503 root
.appendChild(document
.createComment("Pre-Build Processing"));
504 Element ele
= document
.createElement("target");
505 ele
.setAttribute("name", "prebuild");
507 Node node
= SurfaceAreaQuery
.getFpdUserExtensionPreBuild();
510 // For every Target and ToolChain
512 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
513 for (int i
= 0; i
< targetList
.length
; i
++){
514 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
515 for(int j
= 0; j
< toolchainList
.length
; j
++){
519 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
520 + targetList
[i
] + File
.separatorChar
522 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
523 Element fvEle
= document
.createElement("var");
524 fvEle
.setAttribute("name", "FV_DIR");
525 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
526 ele
.appendChild(fvEle
);
528 NodeList childNodes
= node
.getChildNodes();
529 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
530 Node childItem
= childNodes
.item(k
);
531 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
532 ele
.appendChild(recursiveNode(childItem
, document
));
540 root
.appendChild(ele
);
543 private void applyUserExtensionsPostBuild(Document document
, Node root
) {
547 root
.appendChild(document
.createComment("Post-Build Processing"));
548 Element ele
= document
.createElement("target");
549 ele
.setAttribute("name", "postbuild");
551 Node node
= SurfaceAreaQuery
.getFpdUserExtensionPostBuild();
554 // For every Target and ToolChain
556 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
557 for (int i
= 0; i
< targetList
.length
; i
++){
558 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
559 for(int j
= 0; j
< toolchainList
.length
; j
++){
563 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
564 + targetList
[i
] + File
.separatorChar
566 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
567 Element fvEle
= document
.createElement("var");
568 fvEle
.setAttribute("name", "FV_DIR");
569 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
570 ele
.appendChild(fvEle
);
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
));
584 root
.appendChild(ele
);
587 private Element
recursiveNode(Node node
, Document document
) {
588 Element root
= document
.createElement(node
.getNodeName());
589 NamedNodeMap attr
= node
.getAttributes();
590 for (int i
= 0; i
< attr
.getLength(); i
++) {
591 Node attrItem
= attr
.item(i
);
592 root
.setAttribute(attrItem
.getNodeName(), attrItem
.getNodeValue());
594 NodeList childNodes
= node
.getChildNodes();
595 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
596 Node childItem
= childNodes
.item(i
);
597 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
598 root
.appendChild(recursiveNode(childItem
, document
));
600 else if (childItem
.getNodeType() == Node
.TEXT_NODE
){
601 if ( ! childItem
.getNodeValue().trim().equalsIgnoreCase("")) {
602 root
.setTextContent(childItem
.getNodeValue());