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
= "prebuild";
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
+ ", postbuild");
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
);
161 // User Extension pre build
163 applyUserExtensionsPreBuild(document
, root
);
166 // User Extension Post build
168 applyUserExtensionsPostBuild(document
, root
);
170 document
.appendChild(rootComment
);
171 document
.appendChild(root
);
173 // Prepare the DOM document for writing
175 Source source
= new DOMSource(document
);
177 // Prepare the output file
179 File file
= new File(project
.getProperty("PLATFORM_DIR") + File
.separatorChar
+ platformName
+ "_build.xml");
181 // generate all directory path
183 (new File(file
.getParent())).mkdirs();
184 Result result
= new StreamResult(file
);
186 // Write the DOM document to the file
188 Transformer xformer
= TransformerFactory
.newInstance().newTransformer();
189 xformer
.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
190 xformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
191 xformer
.transform(source
, result
);
192 } catch (Exception ex
) {
193 ex
.printStackTrace();
194 throw new BuildException("Generate " + platformName
+ "_build.xml failed. \n" + ex
.getMessage());
198 private void applyModules(Document document
, Node root
, String num
) {
199 root
.appendChild(document
.createComment("Modules target"));
200 Element ele
= document
.createElement("target");
201 ele
.setAttribute("name", "modules" + num
);
203 Set
<String
> fvNameSet
= sequences
.get(num
);
205 Iterator fvNameIter
= fvNameSet
.iterator();
206 while (fvNameIter
.hasNext()) {
207 String fvName
= (String
)fvNameIter
.next();
208 Set
<FpdModuleIdentification
> set
= fvs
.get(fvName
);
209 Iterator iter
= set
.iterator();
210 while (iter
.hasNext()) {
211 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
212 ModuleIdentification moduleId
= fpdModuleId
.getModule();
213 Element moduleEle
= document
.createElement("GenBuild");
214 moduleEle
.setAttribute("type", "build");
216 // Inherit Properties.
217 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
223 Element property
= document
.createElement("property");
224 property
.setAttribute("name", "ARCH");
225 property
.setAttribute("value", fpdModuleId
.getArch());
226 moduleEle
.appendChild(property
);
231 property
= document
.createElement("property");
232 property
.setAttribute("name", "MODULE_GUID");
233 property
.setAttribute("value", moduleId
.getGuid());
234 moduleEle
.appendChild(property
);
239 property
= document
.createElement("property");
240 property
.setAttribute("name", "MODULE_VERSION");
241 property
.setAttribute("value", moduleId
.getVersion());
242 moduleEle
.appendChild(property
);
247 property
= document
.createElement("property");
248 property
.setAttribute("name", "PACKAGE_GUID");
249 property
.setAttribute("value", moduleId
.getPackage().getGuid());
250 moduleEle
.appendChild(property
);
255 property
= document
.createElement("property");
256 property
.setAttribute("name", "PACKAGE_VERSION");
257 property
.setAttribute("value", moduleId
.getPackage().getVersion());
258 moduleEle
.appendChild(property
);
260 ele
.appendChild(moduleEle
);
263 root
.appendChild(ele
);
266 private void applyFvs(Document document
, Node root
, String num
) {
267 Set
<String
> fvNameSet
= sequences
.get(num
);
271 root
.appendChild(document
.createComment("FVs target"));
272 Element ele
= document
.createElement("target");
273 ele
.setAttribute("name", "fvs" + num
);
276 // For every Target and ToolChain
278 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
279 for (int i
= 0; i
< targetList
.length
; i
++){
280 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
281 for(int j
= 0; j
< toolchainList
.length
; j
++){
282 String fvOutputDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
283 + targetList
[i
] + File
.separatorChar
284 + toolchainList
[i
] + File
.separatorChar
+ "FV";
285 String
[] validFv
= SurfaceAreaQuery
.getFpdValidImageNames();
286 for (int k
= 0; k
< validFv
.length
; k
++) {
287 if (fvNameSet
.contains(validFv
[k
]) || ! isListInSequence(validFv
[k
])) {
288 String inputFile
= fvOutputDir
+ "" + File
.separatorChar
+ validFv
[k
].toUpperCase() + ".inf";
289 Element fvEle
= document
.createElement("genfvimage");
290 fvEle
.setAttribute("infFile", inputFile
);
291 fvEle
.setAttribute("outputDir", fvOutputDir
);
292 ele
.appendChild(fvEle
);
297 root
.appendChild(ele
);
300 private void applyClean(Document document
, Node root
) {
304 root
.appendChild(document
.createComment("Clean target"));
305 Element ele
= document
.createElement("target");
306 ele
.setAttribute("name", "clean");
309 Element cleanEle
= document
.createElement("delete");
310 cleanEle
.setAttribute("includeemptydirs", "true");
311 Element filesetEle
= document
.createElement("fileset");
312 filesetEle
.setAttribute("dir", project
.getProperty("BUILD_DIR"));
313 filesetEle
.setAttribute("includes", "**\\OUTPUT\\**");
314 cleanEle
.appendChild(filesetEle
);
315 ele
.appendChild(cleanEle
);
317 Set set
= outfiles
.keySet();
318 Iterator iter
= set
.iterator();
319 while (iter
.hasNext()) {
320 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
321 ModuleIdentification moduleId
= fpdModuleId
.getModule();
323 Element ifEle
= document
.createElement("if");
324 Element availableEle
= document
.createElement("available");
325 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
327 ifEle
.appendChild(availableEle
);
328 Element elseEle
= document
.createElement("then");
330 Element moduleEle
= document
.createElement("ant");
331 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
333 moduleEle
.setAttribute("target", "clean");
335 // Inherit Properties.
336 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
342 Element property
= document
.createElement("property");
343 property
.setAttribute("name", "ARCH");
344 property
.setAttribute("value", fpdModuleId
.getArch());
345 moduleEle
.appendChild(property
);
350 property
= document
.createElement("property");
351 property
.setAttribute("name", "PACKAGE");
352 property
.setAttribute("value", moduleId
.getPackage().getName());
353 moduleEle
.appendChild(property
);
358 property
= document
.createElement("property");
359 property
.setAttribute("name", "PACKAGE_GUID");
360 property
.setAttribute("value", moduleId
.getPackage().getGuid());
361 moduleEle
.appendChild(property
);
366 property
= document
.createElement("property");
367 property
.setAttribute("name", "PACKAGE_VERSION");
368 property
.setAttribute("value", moduleId
.getPackage().getVersion());
369 moduleEle
.appendChild(property
);
374 property
= document
.createElement("property");
375 property
.setAttribute("name", "MODULE_DIR");
376 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
377 moduleEle
.appendChild(property
);
378 elseEle
.appendChild(moduleEle
);
379 ifEle
.appendChild(elseEle
);
380 ele
.appendChild(ifEle
);
383 root
.appendChild(ele
);
386 private void applyCleanall(Document document
, Node root
) {
390 root
.appendChild(document
.createComment("Clean All target"));
391 Element ele
= document
.createElement("target");
392 ele
.setAttribute("name", "cleanall");
395 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
396 for (int i
= 0; i
< targetList
.length
; ++i
) {
397 Element cleanAllEle
= document
.createElement("delete");
398 cleanAllEle
.setAttribute("dir", project
.getProperty("BUILD_DIR") + File
.separatorChar
+ targetList
[i
]);
399 ele
.appendChild(cleanAllEle
);
402 Set set
= outfiles
.keySet();
403 Iterator iter
= set
.iterator();
404 while (iter
.hasNext()) {
405 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
406 ModuleIdentification moduleId
= fpdModuleId
.getModule();
408 Element ifEle
= document
.createElement("if");
409 Element availableEle
= document
.createElement("available");
410 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
412 ifEle
.appendChild(availableEle
);
413 Element elseEle
= document
.createElement("then");
415 Element moduleEle
= document
.createElement("ant");
416 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
418 moduleEle
.setAttribute("target", "cleanall");
420 // Inherit Properties.
421 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
427 Element property
= document
.createElement("property");
428 property
.setAttribute("name", "ARCH");
429 property
.setAttribute("value", fpdModuleId
.getArch());
430 moduleEle
.appendChild(property
);
435 property
= document
.createElement("property");
436 property
.setAttribute("name", "PACKAGE");
437 property
.setAttribute("value", moduleId
.getPackage().getName());
438 moduleEle
.appendChild(property
);
443 property
= document
.createElement("property");
444 property
.setAttribute("name", "PACKAGE_GUID");
445 property
.setAttribute("value", moduleId
.getPackage().getGuid());
446 moduleEle
.appendChild(property
);
451 property
= document
.createElement("property");
452 property
.setAttribute("name", "PACKAGE_VERSION");
453 property
.setAttribute("value", moduleId
.getPackage().getVersion());
454 moduleEle
.appendChild(property
);
459 property
= document
.createElement("property");
460 property
.setAttribute("name", "MODULE_DIR");
461 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
462 moduleEle
.appendChild(property
);
463 elseEle
.appendChild(moduleEle
);
464 ifEle
.appendChild(elseEle
);
465 ele
.appendChild(ifEle
);
468 root
.appendChild(ele
);
471 private void applyUserExtensionsPreBuild(Document document
, Node root
) {
475 root
.appendChild(document
.createComment("Pre Build Processing"));
476 Element ele
= document
.createElement("target");
477 ele
.setAttribute("name", "prebuild");
479 Node node
= SurfaceAreaQuery
.getFpdUserExtensionPreBuild();
482 // For every Target and ToolChain
484 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
485 for (int i
= 0; i
< targetList
.length
; i
++){
486 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
487 for(int j
= 0; j
< toolchainList
.length
; j
++){
491 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
492 + targetList
[i
] + File
.separatorChar
494 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
495 Element fvEle
= document
.createElement("var");
496 fvEle
.setAttribute("name", "FV_DIR");
497 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
498 ele
.appendChild(fvEle
);
500 NodeList childNodes
= node
.getChildNodes();
501 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
502 Node childItem
= childNodes
.item(k
);
503 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
504 ele
.appendChild(recursiveNode(childItem
, document
));
512 root
.appendChild(ele
);
515 private void applyUserExtensionsPostBuild(Document document
, Node root
) {
519 root
.appendChild(document
.createComment("Post Build Processing"));
520 Element ele
= document
.createElement("target");
521 ele
.setAttribute("name", "postbuild");
523 Node node
= SurfaceAreaQuery
.getFpdUserExtensionPostBuild();
526 // For every Target and ToolChain
528 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
529 for (int i
= 0; i
< targetList
.length
; i
++){
530 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
531 for(int j
= 0; j
< toolchainList
.length
; j
++){
535 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
536 + targetList
[i
] + File
.separatorChar
538 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
539 Element fvEle
= document
.createElement("var");
540 fvEle
.setAttribute("name", "FV_DIR");
541 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
542 ele
.appendChild(fvEle
);
544 NodeList childNodes
= node
.getChildNodes();
545 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
546 Node childItem
= childNodes
.item(k
);
547 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
548 ele
.appendChild(recursiveNode(childItem
, document
));
556 root
.appendChild(ele
);
559 private Element
recursiveNode(Node node
, Document document
) {
560 Element root
= document
.createElement(node
.getNodeName());
561 NamedNodeMap attr
= node
.getAttributes();
562 for (int i
= 0; i
< attr
.getLength(); i
++) {
563 Node attrItem
= attr
.item(i
);
564 root
.setAttribute(attrItem
.getNodeName(), attrItem
.getNodeValue());
566 NodeList childNodes
= node
.getChildNodes();
567 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
568 Node childItem
= childNodes
.item(i
);
569 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
570 root
.appendChild(recursiveNode(childItem
, document
));
572 else if (childItem
.getNodeType() == Node
.TEXT_NODE
){
573 if ( ! childItem
.getNodeValue().trim().equalsIgnoreCase("")) {
574 root
.setTextContent(childItem
.getNodeValue());
581 private boolean isListInSequence(String fvName
) {
582 Set
<String
> numbers
= sequences
.keySet();
583 Iterator
<String
> iter
= numbers
.iterator();
584 while (iter
.hasNext()) {
585 Set
<String
> fvNameSet
= sequences
.get(iter
.next());
586 if (fvNameSet
.contains(fvName
)) {