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
.Iterator
;
19 import javax
.xml
.parsers
.DocumentBuilder
;
20 import javax
.xml
.parsers
.DocumentBuilderFactory
;
21 import javax
.xml
.transform
.OutputKeys
;
22 import javax
.xml
.transform
.Result
;
23 import javax
.xml
.transform
.Source
;
24 import javax
.xml
.transform
.Transformer
;
25 import javax
.xml
.transform
.TransformerFactory
;
26 import javax
.xml
.transform
.dom
.DOMSource
;
27 import javax
.xml
.transform
.stream
.StreamResult
;
29 import org
.apache
.tools
.ant
.BuildException
;
30 import org
.apache
.tools
.ant
.Project
;
31 import org
.tianocore
.build
.global
.GlobalData
;
32 import org
.tianocore
.build
.global
.SurfaceAreaQuery
;
33 import org
.tianocore
.build
.id
.FpdModuleIdentification
;
34 import org
.tianocore
.build
.id
.ModuleIdentification
;
35 import org
.w3c
.dom
.Comment
;
36 import org
.w3c
.dom
.Document
;
37 import org
.w3c
.dom
.Element
;
38 import org
.w3c
.dom
.NamedNodeMap
;
39 import org
.w3c
.dom
.Node
;
40 import org
.w3c
.dom
.NodeList
;
42 public class PlatformBuildFileGenerator
{
44 private String platformName
;
47 /// Mapping from modules identification to out put file name
49 private Map
<FpdModuleIdentification
, String
> outfiles
;
52 /// Mapping from FV name to its modules
54 private Map
<String
, Set
<FpdModuleIdentification
>> fvs
;
57 /// Mapping from sequence number to FV names
59 private Map
<String
, Set
<String
>> sequences
;
61 private boolean isUnified
= true;
63 private Project project
;
65 private String info
= "DO NOT EDIT \n"
66 + "File auto-generated by build utility\n"
69 + "Auto-generated ANT build file for building of EFI Modules/Platforms\n";
71 public PlatformBuildFileGenerator(Project project
, Map
<FpdModuleIdentification
, String
> outfiles
, Map
<String
, Set
<FpdModuleIdentification
>> fvs
, Map
<String
, Set
<String
>> sequences
, boolean isUnified
){
72 this.project
= project
;
73 this.outfiles
= outfiles
;
75 this.sequences
= sequences
;
76 this.isUnified
= isUnified
;
77 this.platformName
= project
.getProperty("PLATFORM");
81 Generate build.out.xml file.
83 @throws BuildException
84 build.out.xml XML document create error
86 public void genBuildFile() throws BuildException
{
87 DocumentBuilderFactory domfac
= DocumentBuilderFactory
.newInstance();
89 DocumentBuilder dombuilder
= domfac
.newDocumentBuilder();
90 Document document
= dombuilder
.newDocument();
91 Comment rootComment
= document
.createComment(info
);
93 // create root element and its attributes
95 Element root
= document
.createElement("project");
96 root
.setAttribute("name", project
.getProperty("PLATFORM"));
97 root
.setAttribute("default", "all");
98 root
.setAttribute("basedir", ".");
101 // element for External ANT tasks
103 root
.appendChild(document
.createComment("Apply external ANT tasks"));
104 Element ele
= document
.createElement("taskdef");
105 ele
.setAttribute("resource", "GenBuild.tasks");
106 root
.appendChild(ele
);
108 ele
= document
.createElement("taskdef");
109 ele
.setAttribute("resource", "frameworktasks.tasks");
110 root
.appendChild(ele
);
112 ele
= document
.createElement("taskdef");
113 ele
.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
114 root
.appendChild(ele
);
116 ele
= document
.createElement("property");
117 ele
.setAttribute("environment", "env");
118 root
.appendChild(ele
);
120 Set
<String
> sequenceKeys
= sequences
.keySet();
121 Iterator sequenceIter
= sequenceKeys
.iterator();
122 String dependsStr
= "";
123 while (sequenceIter
.hasNext()) {
124 String num
= (String
)sequenceIter
.next();
125 if (dependsStr
.length() > 0) {
128 dependsStr
+= "modules" + num
+ ", fvs" + num
;
134 root
.appendChild(document
.createComment("Default target"));
135 ele
= document
.createElement("target");
136 ele
.setAttribute("name", "all");
137 ele
.setAttribute("depends", dependsStr
+ ", userextensions");
138 root
.appendChild(ele
);
141 // Modules and Fvs Target
143 sequenceIter
= sequenceKeys
.iterator();
144 while (sequenceIter
.hasNext()) {
145 String num
= (String
)sequenceIter
.next();
146 applyModules(document
, root
, num
);
147 applyFvs(document
, root
, num
);
153 applyClean(document
, root
);
158 applyCleanall(document
, root
);
163 applyUserExtensions(document
, root
);
165 document
.appendChild(rootComment
);
166 document
.appendChild(root
);
168 // Prepare the DOM document for writing
170 Source source
= new DOMSource(document
);
172 // Prepare the output file
174 File file
= new File(project
.getProperty("PLATFORM_DIR") + File
.separatorChar
+ platformName
+ "_build.xml");
176 // generate all directory path
178 (new File(file
.getParent())).mkdirs();
179 Result result
= new StreamResult(file
);
181 // Write the DOM document to the file
183 Transformer xformer
= TransformerFactory
.newInstance().newTransformer();
184 xformer
.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
185 xformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
186 xformer
.transform(source
, result
);
187 } catch (Exception ex
) {
188 ex
.printStackTrace();
189 throw new BuildException("Generate " + platformName
+ "_build.xml failed. \n" + ex
.getMessage());
193 private void applyModules(Document document
, Node root
, String num
) {
194 root
.appendChild(document
.createComment("Modules target"));
195 Element ele
= document
.createElement("target");
196 ele
.setAttribute("name", "modules" + num
);
198 Set
<String
> fvNameSet
= sequences
.get(num
);
200 Iterator fvNameIter
= fvNameSet
.iterator();
201 while (fvNameIter
.hasNext()) {
202 String fvName
= (String
)fvNameIter
.next();
203 Set
<FpdModuleIdentification
> set
= fvs
.get(fvName
);
204 Iterator iter
= set
.iterator();
205 while (iter
.hasNext()) {
206 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
207 ModuleIdentification moduleId
= fpdModuleId
.getModule();
208 Element moduleEle
= document
.createElement("GenBuild");
209 moduleEle
.setAttribute("type", "build");
211 // Inherit Properties.
212 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
218 Element property
= document
.createElement("property");
219 property
.setAttribute("name", "ARCH");
220 property
.setAttribute("value", fpdModuleId
.getArch());
221 moduleEle
.appendChild(property
);
226 property
= document
.createElement("property");
227 property
.setAttribute("name", "MODULE_GUID");
228 property
.setAttribute("value", moduleId
.getGuid());
229 moduleEle
.appendChild(property
);
234 property
= document
.createElement("property");
235 property
.setAttribute("name", "MODULE_VERSION");
236 property
.setAttribute("value", moduleId
.getVersion());
237 moduleEle
.appendChild(property
);
242 property
= document
.createElement("property");
243 property
.setAttribute("name", "PACKAGE_GUID");
244 property
.setAttribute("value", moduleId
.getPackage().getGuid());
245 moduleEle
.appendChild(property
);
250 property
= document
.createElement("property");
251 property
.setAttribute("name", "PACKAGE_VERSION");
252 property
.setAttribute("value", moduleId
.getPackage().getVersion());
253 moduleEle
.appendChild(property
);
255 ele
.appendChild(moduleEle
);
258 root
.appendChild(ele
);
261 private void applyFvs(Document document
, Node root
, String num
) {
262 Set
<String
> fvNameSet
= sequences
.get(num
);
266 root
.appendChild(document
.createComment("FVs target"));
267 Element ele
= document
.createElement("target");
268 ele
.setAttribute("name", "fvs" + num
);
271 // For every Target and ToolChain
273 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
274 for (int i
= 0; i
< targetList
.length
; i
++){
275 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
276 for(int j
= 0; j
< toolchainList
.length
; j
++){
277 String fvOutputDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
278 + targetList
[i
] + File
.separatorChar
279 + toolchainList
[i
] + File
.separatorChar
+ "FV";
280 String
[] validFv
= SurfaceAreaQuery
.getFpdValidImageNames();
281 for (int k
= 0; k
< validFv
.length
; k
++) {
282 if (fvNameSet
.contains(validFv
[k
]) || ! isListInSequence(validFv
[k
])) {
283 String inputFile
= fvOutputDir
+ "" + File
.separatorChar
+ validFv
[k
].toUpperCase() + ".inf";
284 Element fvEle
= document
.createElement("genfvimage");
285 fvEle
.setAttribute("infFile", inputFile
);
286 fvEle
.setAttribute("outputDir", fvOutputDir
);
287 ele
.appendChild(fvEle
);
292 root
.appendChild(ele
);
295 private void applyClean(Document document
, Node root
) {
299 root
.appendChild(document
.createComment("Clean target"));
300 Element ele
= document
.createElement("target");
301 ele
.setAttribute("name", "clean");
304 Element cleanEle
= document
.createElement("delete");
305 cleanEle
.setAttribute("includeemptydirs", "true");
306 Element filesetEle
= document
.createElement("fileset");
307 filesetEle
.setAttribute("dir", project
.getProperty("BUILD_DIR"));
308 filesetEle
.setAttribute("includes", "**\\OUTPUT\\**");
309 cleanEle
.appendChild(filesetEle
);
310 ele
.appendChild(cleanEle
);
312 Set set
= outfiles
.keySet();
313 Iterator iter
= set
.iterator();
314 while (iter
.hasNext()) {
315 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
316 ModuleIdentification moduleId
= fpdModuleId
.getModule();
318 Element ifEle
= document
.createElement("if");
319 Element availableEle
= document
.createElement("available");
320 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
322 ifEle
.appendChild(availableEle
);
323 Element elseEle
= document
.createElement("then");
325 Element moduleEle
= document
.createElement("ant");
326 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
328 moduleEle
.setAttribute("target", "clean");
330 // Inherit Properties.
331 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
337 Element property
= document
.createElement("property");
338 property
.setAttribute("name", "ARCH");
339 property
.setAttribute("value", fpdModuleId
.getArch());
340 moduleEle
.appendChild(property
);
345 property
= document
.createElement("property");
346 property
.setAttribute("name", "PACKAGE");
347 property
.setAttribute("value", moduleId
.getPackage().getName());
348 moduleEle
.appendChild(property
);
353 property
= document
.createElement("property");
354 property
.setAttribute("name", "PACKAGE_GUID");
355 property
.setAttribute("value", moduleId
.getPackage().getGuid());
356 moduleEle
.appendChild(property
);
361 property
= document
.createElement("property");
362 property
.setAttribute("name", "PACKAGE_VERSION");
363 property
.setAttribute("value", moduleId
.getPackage().getVersion());
364 moduleEle
.appendChild(property
);
369 property
= document
.createElement("property");
370 property
.setAttribute("name", "MODULE_DIR");
371 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
372 moduleEle
.appendChild(property
);
373 elseEle
.appendChild(moduleEle
);
374 ifEle
.appendChild(elseEle
);
375 ele
.appendChild(ifEle
);
378 root
.appendChild(ele
);
381 private void applyCleanall(Document document
, Node root
) {
385 root
.appendChild(document
.createComment("Clean All target"));
386 Element ele
= document
.createElement("target");
387 ele
.setAttribute("name", "cleanall");
390 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
391 for (int i
= 0; i
< targetList
.length
; ++i
) {
392 Element cleanAllEle
= document
.createElement("delete");
393 cleanAllEle
.setAttribute("dir", project
.getProperty("BUILD_DIR") + File
.separatorChar
+ targetList
[i
]);
394 ele
.appendChild(cleanAllEle
);
397 Set set
= outfiles
.keySet();
398 Iterator iter
= set
.iterator();
399 while (iter
.hasNext()) {
400 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
401 ModuleIdentification moduleId
= fpdModuleId
.getModule();
403 Element ifEle
= document
.createElement("if");
404 Element availableEle
= document
.createElement("available");
405 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
407 ifEle
.appendChild(availableEle
);
408 Element elseEle
= document
.createElement("then");
410 Element moduleEle
= document
.createElement("ant");
411 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
413 moduleEle
.setAttribute("target", "cleanall");
415 // Inherit Properties.
416 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
422 Element property
= document
.createElement("property");
423 property
.setAttribute("name", "ARCH");
424 property
.setAttribute("value", fpdModuleId
.getArch());
425 moduleEle
.appendChild(property
);
430 property
= document
.createElement("property");
431 property
.setAttribute("name", "PACKAGE");
432 property
.setAttribute("value", moduleId
.getPackage().getName());
433 moduleEle
.appendChild(property
);
438 property
= document
.createElement("property");
439 property
.setAttribute("name", "PACKAGE_GUID");
440 property
.setAttribute("value", moduleId
.getPackage().getGuid());
441 moduleEle
.appendChild(property
);
446 property
= document
.createElement("property");
447 property
.setAttribute("name", "PACKAGE_VERSION");
448 property
.setAttribute("value", moduleId
.getPackage().getVersion());
449 moduleEle
.appendChild(property
);
454 property
= document
.createElement("property");
455 property
.setAttribute("name", "MODULE_DIR");
456 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
457 moduleEle
.appendChild(property
);
458 elseEle
.appendChild(moduleEle
);
459 ifEle
.appendChild(elseEle
);
460 ele
.appendChild(ifEle
);
463 root
.appendChild(ele
);
466 private void applyUserExtensions(Document document
, Node root
) {
470 root
.appendChild(document
.createComment("User Extensions"));
471 Element ele
= document
.createElement("target");
472 ele
.setAttribute("name", "userextensions");
474 Node node
= SurfaceAreaQuery
.getFpdUserExtension();
477 // For every Target and ToolChain
479 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
480 for (int i
= 0; i
< targetList
.length
; i
++){
481 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
482 for(int j
= 0; j
< toolchainList
.length
; j
++){
486 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
487 + targetList
[i
] + File
.separatorChar
489 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
490 Element fvEle
= document
.createElement("var");
491 fvEle
.setAttribute("name", "FV_DIR");
492 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
493 ele
.appendChild(fvEle
);
495 NodeList childNodes
= node
.getChildNodes();
496 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
497 Node childItem
= childNodes
.item(k
);
498 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
499 ele
.appendChild(recursiveNode(childItem
, document
));
507 root
.appendChild(ele
);
510 private Element
recursiveNode(Node node
, Document document
) {
511 Element root
= document
.createElement(node
.getNodeName());
512 NamedNodeMap attr
= node
.getAttributes();
513 for (int i
= 0; i
< attr
.getLength(); i
++) {
514 Node attrItem
= attr
.item(i
);
515 root
.setAttribute(attrItem
.getNodeName(), attrItem
.getNodeValue());
517 NodeList childNodes
= node
.getChildNodes();
518 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
519 Node childItem
= childNodes
.item(i
);
520 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
521 root
.appendChild(recursiveNode(childItem
, document
));
523 else if (childItem
.getNodeType() == Node
.TEXT_NODE
){
524 if ( ! childItem
.getNodeValue().trim().equalsIgnoreCase("")) {
525 root
.setTextContent(childItem
.getNodeValue());
532 private boolean isListInSequence(String fvName
) {
533 Set
<String
> numbers
= sequences
.keySet();
534 Iterator
<String
> iter
= numbers
.iterator();
535 while (iter
.hasNext()) {
536 Set
<String
> fvNameSet
= sequences
.get(iter
.next());
537 if (fvNameSet
.contains(fvName
)) {