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 SurfaceAreaQuery saq
= 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
){
76 this.project
= project
;
77 this.outfiles
= outfiles
;
78 this.isUnified
= isUnified
;
81 this.platformName
= project
.getProperty("PLATFORM");
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 // Prepare the output file
169 File file
= new File(project
.getProperty("PLATFORM_DIR") + File
.separatorChar
+ platformName
+ "_build.xml");
171 // generate all directory path
173 (new File(file
.getParent())).mkdirs();
174 Result result
= new StreamResult(file
);
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("Generation of the " + platformName
+ "_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 // Get all valid FV name
203 String
[] validFv
= saq
.getFpdValidImageNames();
206 // For each valid FV, get all modules in sequence
208 for (int i
= 0; i
< validFv
.length
; i
++) {
209 if (fvs
.containsKey(validFv
[i
])) {
210 Set
<FpdModuleIdentification
> set
= fvs
.get(validFv
[i
]);
211 Iterator
<FpdModuleIdentification
> iter
= set
.iterator();
212 while (iter
.hasNext()) {
213 FpdModuleIdentification fpdModuleId
= iter
.next();
214 applySingleModule(document
, ele
, fpdModuleId
);
220 // Get all other modules
222 Iterator
<String
> fvsNameIter
= fvs
.keySet().iterator();
224 while (fvsNameIter
.hasNext()) {
225 String fvName
= fvsNameIter
.next();
226 if (!isContain(validFv
, fvName
)) {
227 Set
<FpdModuleIdentification
> set
= fvs
.get(fvName
);
228 Iterator iter
= set
.iterator();
229 while (iter
.hasNext()) {
230 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
231 applySingleModule(document
, ele
, fpdModuleId
);
236 root
.appendChild(ele
);
239 private void applySingleModule(Document document
, Node root
, FpdModuleIdentification fpdModuleId
) {
240 ModuleIdentification moduleId
= fpdModuleId
.getModule();
241 Element moduleEle
= document
.createElement("GenBuild");
242 moduleEle
.setAttribute("type", "build");
244 // Inherit Properties.
245 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
251 Element property
= document
.createElement("property");
252 property
.setAttribute("name", "ARCH");
253 property
.setAttribute("value", fpdModuleId
.getArch());
254 moduleEle
.appendChild(property
);
259 property
= document
.createElement("property");
260 property
.setAttribute("name", "MODULE_GUID");
261 property
.setAttribute("value", moduleId
.getGuid());
262 moduleEle
.appendChild(property
);
267 property
= document
.createElement("property");
268 property
.setAttribute("name", "MODULE_VERSION");
269 property
.setAttribute("value", moduleId
.getVersion());
270 moduleEle
.appendChild(property
);
275 property
= document
.createElement("property");
276 property
.setAttribute("name", "PACKAGE_GUID");
277 property
.setAttribute("value", moduleId
.getPackage().getGuid());
278 moduleEle
.appendChild(property
);
283 property
= document
.createElement("property");
284 property
.setAttribute("name", "PACKAGE_VERSION");
285 property
.setAttribute("value", moduleId
.getPackage().getVersion());
286 moduleEle
.appendChild(property
);
288 root
.appendChild(moduleEle
);
291 private boolean isContain(String
[] list
, String item
) {
292 for (int i
= 0; i
< list
.length
; i
++) {
293 if (list
[i
].equalsIgnoreCase(item
)) {
300 private void applyFvs(Document document
, Node root
) {
304 root
.appendChild(document
.createComment("FVs target"));
305 Element ele
= document
.createElement("target");
306 ele
.setAttribute("name", "fvs");
309 // For every Target and ToolChain
311 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
312 for (int i
= 0; i
< targetList
.length
; i
++){
313 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
314 for(int j
= 0; j
< toolchainList
.length
; j
++){
315 String fvOutputDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
316 + targetList
[i
] + "_"
317 + toolchainList
[j
] + File
.separatorChar
+ "FV";
318 String
[] validFv
= saq
.getFpdValidImageNames();
319 for (int k
= 0; k
< validFv
.length
; k
++) {
320 String inputFile
= fvOutputDir
+ "" + File
.separatorChar
+ validFv
[k
].toUpperCase() + ".inf";
321 Element fvEle
= document
.createElement("genfvimage");
322 fvEle
.setAttribute("infFile", inputFile
);
323 fvEle
.setAttribute("outputDir", fvOutputDir
);
324 ele
.appendChild(fvEle
);
328 root
.appendChild(ele
);
331 private void applyClean(Document document
, Node root
) {
335 root
.appendChild(document
.createComment("Clean target"));
336 Element ele
= document
.createElement("target");
337 ele
.setAttribute("name", "clean");
340 Element cleanEle
= document
.createElement("delete");
341 cleanEle
.setAttribute("includeemptydirs", "true");
342 Element filesetEle
= document
.createElement("fileset");
343 filesetEle
.setAttribute("dir", project
.getProperty("BUILD_DIR"));
344 filesetEle
.setAttribute("includes", "**\\OUTPUT\\**");
345 cleanEle
.appendChild(filesetEle
);
346 ele
.appendChild(cleanEle
);
348 Set set
= outfiles
.keySet();
349 Iterator iter
= set
.iterator();
350 while (iter
.hasNext()) {
351 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
352 ModuleIdentification moduleId
= fpdModuleId
.getModule();
354 Element ifEle
= document
.createElement("if");
355 Element availableEle
= document
.createElement("available");
356 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
358 ifEle
.appendChild(availableEle
);
359 Element elseEle
= document
.createElement("then");
361 Element moduleEle
= document
.createElement("ant");
362 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
364 moduleEle
.setAttribute("target", "clean");
366 // Inherit Properties.
367 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
373 Element property
= document
.createElement("property");
374 property
.setAttribute("name", "ARCH");
375 property
.setAttribute("value", fpdModuleId
.getArch());
376 moduleEle
.appendChild(property
);
381 property
= document
.createElement("property");
382 property
.setAttribute("name", "PACKAGE");
383 property
.setAttribute("value", moduleId
.getPackage().getName());
384 moduleEle
.appendChild(property
);
389 property
= document
.createElement("property");
390 property
.setAttribute("name", "PACKAGE_GUID");
391 property
.setAttribute("value", moduleId
.getPackage().getGuid());
392 moduleEle
.appendChild(property
);
397 property
= document
.createElement("property");
398 property
.setAttribute("name", "PACKAGE_VERSION");
399 property
.setAttribute("value", moduleId
.getPackage().getVersion());
400 moduleEle
.appendChild(property
);
405 property
= document
.createElement("property");
406 property
.setAttribute("name", "MODULE_DIR");
407 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
408 moduleEle
.appendChild(property
);
409 elseEle
.appendChild(moduleEle
);
410 ifEle
.appendChild(elseEle
);
411 ele
.appendChild(ifEle
);
414 root
.appendChild(ele
);
417 private void applyCleanall(Document document
, Node root
) {
421 root
.appendChild(document
.createComment("Target: cleanall"));
422 Element ele
= document
.createElement("target");
423 ele
.setAttribute("name", "cleanall");
426 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
427 for (int i
= 0; i
< targetList
.length
; ++i
) {
428 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
429 for(int j
= 0; j
< toolchainList
.length
; j
++) {
430 Element cleanAllEle
= document
.createElement("delete");
431 cleanAllEle
.setAttribute("dir", project
.getProperty("BUILD_DIR") + File
.separatorChar
+ targetList
[i
] + "_" + toolchainList
[j
]);
432 ele
.appendChild(cleanAllEle
);
436 Set set
= outfiles
.keySet();
437 Iterator iter
= set
.iterator();
438 while (iter
.hasNext()) {
439 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
440 ModuleIdentification moduleId
= fpdModuleId
.getModule();
442 Element ifEle
= document
.createElement("if");
443 Element availableEle
= document
.createElement("available");
444 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
446 ifEle
.appendChild(availableEle
);
447 Element elseEle
= document
.createElement("then");
449 Element moduleEle
= document
.createElement("ant");
450 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
452 moduleEle
.setAttribute("target", "cleanall");
454 // Inherit Properties.
455 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
461 Element property
= document
.createElement("property");
462 property
.setAttribute("name", "ARCH");
463 property
.setAttribute("value", fpdModuleId
.getArch());
464 moduleEle
.appendChild(property
);
469 property
= document
.createElement("property");
470 property
.setAttribute("name", "PACKAGE");
471 property
.setAttribute("value", moduleId
.getPackage().getName());
472 moduleEle
.appendChild(property
);
477 property
= document
.createElement("property");
478 property
.setAttribute("name", "PACKAGE_GUID");
479 property
.setAttribute("value", moduleId
.getPackage().getGuid());
480 moduleEle
.appendChild(property
);
485 property
= document
.createElement("property");
486 property
.setAttribute("name", "PACKAGE_VERSION");
487 property
.setAttribute("value", moduleId
.getPackage().getVersion());
488 moduleEle
.appendChild(property
);
493 property
= document
.createElement("property");
494 property
.setAttribute("name", "MODULE_DIR");
495 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
496 moduleEle
.appendChild(property
);
497 elseEle
.appendChild(moduleEle
);
498 ifEle
.appendChild(elseEle
);
499 ele
.appendChild(ifEle
);
502 root
.appendChild(ele
);
505 private void applyUserExtensionsPreBuild(Document document
, Node root
) {
509 root
.appendChild(document
.createComment("Pre-Build Processing"));
510 Element ele
= document
.createElement("target");
511 ele
.setAttribute("name", "prebuild");
513 Node node
= saq
.getFpdUserExtensionPreBuild();
516 // For every Target and ToolChain
518 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
519 for (int i
= 0; i
< targetList
.length
; i
++){
520 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
521 for(int j
= 0; j
< toolchainList
.length
; j
++){
525 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
526 + targetList
[i
] + "_"
528 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
529 Element fvEle
= document
.createElement("var");
530 fvEle
.setAttribute("name", "FV_DIR");
531 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
532 ele
.appendChild(fvEle
);
534 NodeList childNodes
= node
.getChildNodes();
535 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
536 Node childItem
= childNodes
.item(k
);
537 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
538 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 NodeList childNodes
= node
.getChildNodes();
579 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
580 Node childItem
= childNodes
.item(k
);
581 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
582 ele
.appendChild(recursiveNode(childItem
, document
));
590 root
.appendChild(ele
);
593 private Element
recursiveNode(Node node
, Document document
) {
594 Element root
= document
.createElement(node
.getNodeName());
595 NamedNodeMap attr
= node
.getAttributes();
596 for (int i
= 0; i
< attr
.getLength(); i
++) {
597 Node attrItem
= attr
.item(i
);
598 root
.setAttribute(attrItem
.getNodeName(), attrItem
.getNodeValue());
600 NodeList childNodes
= node
.getChildNodes();
601 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
602 Node childItem
= childNodes
.item(i
);
603 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
604 root
.appendChild(recursiveNode(childItem
, document
));
606 else if (childItem
.getNodeType() == Node
.TEXT_NODE
){
607 if ( ! childItem
.getNodeValue().trim().equalsIgnoreCase("")) {
608 root
.setTextContent(childItem
.getNodeValue());