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("property");
113 ele
.setAttribute("environment", "env");
114 root
.appendChild(ele
);
116 Set
<String
> sequenceKeys
= sequences
.keySet();
117 Iterator sequenceIter
= sequenceKeys
.iterator();
118 String dependsStr
= "";
119 while (sequenceIter
.hasNext()) {
120 String num
= (String
)sequenceIter
.next();
121 if (dependsStr
.length() > 0) {
124 dependsStr
+= "modules" + num
+ ", fvs" + num
;
130 root
.appendChild(document
.createComment("Default target"));
131 ele
= document
.createElement("target");
132 ele
.setAttribute("name", "all");
133 ele
.setAttribute("depends", dependsStr
+ ", userextensions");
134 root
.appendChild(ele
);
137 // Modules and Fvs Target
139 sequenceIter
= sequenceKeys
.iterator();
140 while (sequenceIter
.hasNext()) {
141 String num
= (String
)sequenceIter
.next();
142 applyModules(document
, root
, num
);
143 applyFvs(document
, root
, num
);
149 applyClean(document
, root
);
154 applyCleanall(document
, root
);
159 applyUserExtensions(document
, root
);
161 document
.appendChild(rootComment
);
162 document
.appendChild(root
);
164 // Prepare the DOM document for writing
166 Source source
= new DOMSource(document
);
168 // Prepare the output file
170 File file
= new File(project
.getProperty("PLATFORM_DIR") + File
.separatorChar
+ platformName
+ "_build.xml");
172 // generate all directory path
174 (new File(file
.getParent())).mkdirs();
175 Result result
= new StreamResult(file
);
177 // Write the DOM document to the file
179 Transformer xformer
= TransformerFactory
.newInstance().newTransformer();
180 xformer
.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
181 xformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
182 xformer
.transform(source
, result
);
183 } catch (Exception ex
) {
184 ex
.printStackTrace();
185 throw new BuildException("Generate " + platformName
+ "_build.xml failed. \n" + ex
.getMessage());
189 private void applyModules(Document document
, Node root
, String num
) {
190 root
.appendChild(document
.createComment("Modules target"));
191 Element ele
= document
.createElement("target");
192 ele
.setAttribute("name", "modules" + num
);
194 Set
<String
> fvNameSet
= sequences
.get(num
);
196 Iterator fvNameIter
= fvNameSet
.iterator();
197 while (fvNameIter
.hasNext()) {
198 String fvName
= (String
)fvNameIter
.next();
199 Set
<FpdModuleIdentification
> set
= fvs
.get(fvName
);
200 Iterator iter
= set
.iterator();
201 while (iter
.hasNext()) {
202 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
203 ModuleIdentification moduleId
= fpdModuleId
.getModule();
204 Element moduleEle
= document
.createElement("GenBuild");
205 moduleEle
.setAttribute("type", "build");
207 // Inherit Properties.
208 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
214 Element property
= document
.createElement("property");
215 property
.setAttribute("name", "ARCH");
216 property
.setAttribute("value", fpdModuleId
.getArch());
217 moduleEle
.appendChild(property
);
222 property
= document
.createElement("property");
223 property
.setAttribute("name", "MODULE_GUID");
224 property
.setAttribute("value", moduleId
.getGuid());
225 moduleEle
.appendChild(property
);
230 property
= document
.createElement("property");
231 property
.setAttribute("name", "MODULE_VERSION");
232 property
.setAttribute("value", moduleId
.getVersion());
233 moduleEle
.appendChild(property
);
238 property
= document
.createElement("property");
239 property
.setAttribute("name", "PACKAGE_GUID");
240 property
.setAttribute("value", moduleId
.getPackage().getGuid());
241 moduleEle
.appendChild(property
);
246 property
= document
.createElement("property");
247 property
.setAttribute("name", "PACKAGE_VERSION");
248 property
.setAttribute("value", moduleId
.getPackage().getVersion());
249 moduleEle
.appendChild(property
);
251 ele
.appendChild(moduleEle
);
254 root
.appendChild(ele
);
257 private void applyFvs(Document document
, Node root
, String num
) {
258 Set
<String
> fvNameSet
= sequences
.get(num
);
262 root
.appendChild(document
.createComment("FVs target"));
263 Element ele
= document
.createElement("target");
264 ele
.setAttribute("name", "fvs" + num
);
267 // For every Target and ToolChain
269 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
270 for (int i
= 0; i
< targetList
.length
; i
++){
271 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
272 for(int j
= 0; j
< toolchainList
.length
; j
++){
273 String fvOutputDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
274 + targetList
[i
] + File
.separatorChar
275 + toolchainList
[i
] + File
.separatorChar
+ "FV";
276 String
[] validFv
= SurfaceAreaQuery
.getFpdValidImageNames();
277 for (int k
= 0; k
< validFv
.length
; k
++) {
278 if (fvNameSet
.contains(validFv
[k
]) || ! isListInSequence(validFv
[k
])) {
279 String inputFile
= fvOutputDir
+ "" + File
.separatorChar
+ validFv
[k
].toUpperCase() + ".inf";
280 Element fvEle
= document
.createElement("genfvimage");
281 fvEle
.setAttribute("infFile", inputFile
);
282 fvEle
.setAttribute("outputDir", fvOutputDir
);
283 ele
.appendChild(fvEle
);
288 root
.appendChild(ele
);
291 private void applyClean(Document document
, Node root
) {
295 root
.appendChild(document
.createComment("Clean target"));
296 Element ele
= document
.createElement("target");
297 ele
.setAttribute("name", "clean");
300 Element cleanEle
= document
.createElement("delete");
301 cleanEle
.setAttribute("includeemptydirs", "true");
302 Element filesetEle
= document
.createElement("fileset");
303 filesetEle
.setAttribute("dir", project
.getProperty("BUILD_DIR"));
304 filesetEle
.setAttribute("includes", "**\\OUTPUT\\**");
305 cleanEle
.appendChild(filesetEle
);
306 ele
.appendChild(cleanEle
);
308 Set set
= outfiles
.keySet();
309 Iterator iter
= set
.iterator();
310 while (iter
.hasNext()) {
311 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
312 ModuleIdentification moduleId
= fpdModuleId
.getModule();
314 Element ifEle
= document
.createElement("if");
315 Element availableEle
= document
.createElement("available");
316 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
318 ifEle
.appendChild(availableEle
);
319 Element elseEle
= document
.createElement("then");
321 Element moduleEle
= document
.createElement("ant");
322 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
324 moduleEle
.setAttribute("target", "clean");
326 // Inherit Properties.
327 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
333 Element property
= document
.createElement("property");
334 property
.setAttribute("name", "ARCH");
335 property
.setAttribute("value", fpdModuleId
.getArch());
336 moduleEle
.appendChild(property
);
341 property
= document
.createElement("property");
342 property
.setAttribute("name", "PACKAGE");
343 property
.setAttribute("value", moduleId
.getPackage().getName());
344 moduleEle
.appendChild(property
);
349 property
= document
.createElement("property");
350 property
.setAttribute("name", "PACKAGE_GUID");
351 property
.setAttribute("value", moduleId
.getPackage().getGuid());
352 moduleEle
.appendChild(property
);
357 property
= document
.createElement("property");
358 property
.setAttribute("name", "PACKAGE_VERSION");
359 property
.setAttribute("value", moduleId
.getPackage().getVersion());
360 moduleEle
.appendChild(property
);
365 property
= document
.createElement("property");
366 property
.setAttribute("name", "MODULE_DIR");
367 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
368 moduleEle
.appendChild(property
);
369 elseEle
.appendChild(moduleEle
);
370 ifEle
.appendChild(elseEle
);
371 ele
.appendChild(ifEle
);
374 root
.appendChild(ele
);
377 private void applyCleanall(Document document
, Node root
) {
381 root
.appendChild(document
.createComment("Clean All target"));
382 Element ele
= document
.createElement("target");
383 ele
.setAttribute("name", "cleanall");
386 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
387 for (int i
= 0; i
< targetList
.length
; ++i
) {
388 Element cleanAllEle
= document
.createElement("delete");
389 cleanAllEle
.setAttribute("dir", project
.getProperty("BUILD_DIR") + File
.separatorChar
+ targetList
[i
]);
390 ele
.appendChild(cleanAllEle
);
393 Set set
= outfiles
.keySet();
394 Iterator iter
= set
.iterator();
395 while (iter
.hasNext()) {
396 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
397 ModuleIdentification moduleId
= fpdModuleId
.getModule();
399 Element ifEle
= document
.createElement("if");
400 Element availableEle
= document
.createElement("available");
401 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
403 ifEle
.appendChild(availableEle
);
404 Element elseEle
= document
.createElement("then");
406 Element moduleEle
= document
.createElement("ant");
407 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
409 moduleEle
.setAttribute("target", "cleanall");
411 // Inherit Properties.
412 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
418 Element property
= document
.createElement("property");
419 property
.setAttribute("name", "ARCH");
420 property
.setAttribute("value", fpdModuleId
.getArch());
421 moduleEle
.appendChild(property
);
426 property
= document
.createElement("property");
427 property
.setAttribute("name", "PACKAGE");
428 property
.setAttribute("value", moduleId
.getPackage().getName());
429 moduleEle
.appendChild(property
);
434 property
= document
.createElement("property");
435 property
.setAttribute("name", "PACKAGE_GUID");
436 property
.setAttribute("value", moduleId
.getPackage().getGuid());
437 moduleEle
.appendChild(property
);
442 property
= document
.createElement("property");
443 property
.setAttribute("name", "PACKAGE_VERSION");
444 property
.setAttribute("value", moduleId
.getPackage().getVersion());
445 moduleEle
.appendChild(property
);
450 property
= document
.createElement("property");
451 property
.setAttribute("name", "MODULE_DIR");
452 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
453 moduleEle
.appendChild(property
);
454 elseEle
.appendChild(moduleEle
);
455 ifEle
.appendChild(elseEle
);
456 ele
.appendChild(ifEle
);
459 root
.appendChild(ele
);
462 private void applyUserExtensions(Document document
, Node root
) {
466 root
.appendChild(document
.createComment("User Extensions"));
467 Element ele
= document
.createElement("target");
468 ele
.setAttribute("name", "userextensions");
470 Node node
= SurfaceAreaQuery
.getFpdUserExtension();
473 // For every Target and ToolChain
475 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
476 for (int i
= 0; i
< targetList
.length
; i
++){
477 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
478 for(int j
= 0; j
< toolchainList
.length
; j
++){
482 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
483 + targetList
[i
] + File
.separatorChar
485 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
486 Element fvEle
= document
.createElement("var");
487 fvEle
.setAttribute("name", "FV_DIR");
488 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
489 ele
.appendChild(fvEle
);
491 NodeList childNodes
= node
.getChildNodes();
492 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
493 Node childItem
= childNodes
.item(k
);
494 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
495 ele
.appendChild(recursiveNode(childItem
, document
));
503 root
.appendChild(ele
);
506 private Element
recursiveNode(Node node
, Document document
) {
507 Element root
= document
.createElement(node
.getNodeName());
508 NamedNodeMap attr
= node
.getAttributes();
509 for (int i
= 0; i
< attr
.getLength(); i
++) {
510 Node attrItem
= attr
.item(i
);
511 root
.setAttribute(attrItem
.getNodeName(), attrItem
.getNodeValue());
513 NodeList childNodes
= node
.getChildNodes();
514 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
515 Node childItem
= childNodes
.item(i
);
516 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
517 root
.appendChild(recursiveNode(childItem
, document
));
519 else if (childItem
.getNodeType() == Node
.TEXT_NODE
){
520 if ( ! childItem
.getNodeValue().trim().equalsIgnoreCase("")) {
521 root
.setTextContent(childItem
.getNodeValue());
528 private boolean isListInSequence(String fvName
) {
529 Set
<String
> numbers
= sequences
.keySet();
530 Iterator
<String
> iter
= numbers
.iterator();
531 while (iter
.hasNext()) {
532 Set
<String
> fvNameSet
= sequences
.get(iter
.next());
533 if (fvNameSet
.contains(fvName
)) {