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 throw new BuildException("Generate " + platformName
+ "_build.xml failed. \n" + ex
.getMessage());
197 private void applyModules(Document document
, Node root
, String num
) {
198 root
.appendChild(document
.createComment("Modules target"));
199 Element ele
= document
.createElement("target");
200 ele
.setAttribute("name", "modules" + num
);
202 Set
<String
> fvNameSet
= sequences
.get(num
);
204 Iterator fvNameIter
= fvNameSet
.iterator();
205 while (fvNameIter
.hasNext()) {
206 String fvName
= (String
)fvNameIter
.next();
207 Set
<FpdModuleIdentification
> set
= fvs
.get(fvName
);
208 Iterator iter
= set
.iterator();
209 while (iter
.hasNext()) {
210 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
211 ModuleIdentification moduleId
= fpdModuleId
.getModule();
212 Element moduleEle
= document
.createElement("GenBuild");
213 moduleEle
.setAttribute("type", "build");
215 // Inherit Properties.
216 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
222 Element property
= document
.createElement("property");
223 property
.setAttribute("name", "ARCH");
224 property
.setAttribute("value", fpdModuleId
.getArch());
225 moduleEle
.appendChild(property
);
230 property
= document
.createElement("property");
231 property
.setAttribute("name", "MODULE_GUID");
232 property
.setAttribute("value", moduleId
.getGuid());
233 moduleEle
.appendChild(property
);
238 property
= document
.createElement("property");
239 property
.setAttribute("name", "MODULE_VERSION");
240 property
.setAttribute("value", moduleId
.getVersion());
241 moduleEle
.appendChild(property
);
246 property
= document
.createElement("property");
247 property
.setAttribute("name", "PACKAGE_GUID");
248 property
.setAttribute("value", moduleId
.getPackage().getGuid());
249 moduleEle
.appendChild(property
);
254 property
= document
.createElement("property");
255 property
.setAttribute("name", "PACKAGE_VERSION");
256 property
.setAttribute("value", moduleId
.getPackage().getVersion());
257 moduleEle
.appendChild(property
);
259 ele
.appendChild(moduleEle
);
262 root
.appendChild(ele
);
265 private void applyFvs(Document document
, Node root
, String num
) {
266 Set
<String
> fvNameSet
= sequences
.get(num
);
270 root
.appendChild(document
.createComment("FVs target"));
271 Element ele
= document
.createElement("target");
272 ele
.setAttribute("name", "fvs" + num
);
275 // For every Target and ToolChain
277 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
278 for (int i
= 0; i
< targetList
.length
; i
++){
279 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
280 for(int j
= 0; j
< toolchainList
.length
; j
++){
281 String fvOutputDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
282 + targetList
[i
] + File
.separatorChar
283 + toolchainList
[j
] + File
.separatorChar
+ "FV";
284 String
[] validFv
= SurfaceAreaQuery
.getFpdValidImageNames();
285 for (int k
= 0; k
< validFv
.length
; k
++) {
286 if (fvNameSet
.contains(validFv
[k
]) || ! isListInSequence(validFv
[k
])) {
287 String inputFile
= fvOutputDir
+ "" + File
.separatorChar
+ validFv
[k
].toUpperCase() + ".inf";
288 Element fvEle
= document
.createElement("genfvimage");
289 fvEle
.setAttribute("infFile", inputFile
);
290 fvEle
.setAttribute("outputDir", fvOutputDir
);
291 ele
.appendChild(fvEle
);
296 root
.appendChild(ele
);
299 private void applyClean(Document document
, Node root
) {
303 root
.appendChild(document
.createComment("Clean target"));
304 Element ele
= document
.createElement("target");
305 ele
.setAttribute("name", "clean");
308 Element cleanEle
= document
.createElement("delete");
309 cleanEle
.setAttribute("includeemptydirs", "true");
310 Element filesetEle
= document
.createElement("fileset");
311 filesetEle
.setAttribute("dir", project
.getProperty("BUILD_DIR"));
312 filesetEle
.setAttribute("includes", "**\\OUTPUT\\**");
313 cleanEle
.appendChild(filesetEle
);
314 ele
.appendChild(cleanEle
);
316 Set set
= outfiles
.keySet();
317 Iterator iter
= set
.iterator();
318 while (iter
.hasNext()) {
319 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
320 ModuleIdentification moduleId
= fpdModuleId
.getModule();
322 Element ifEle
= document
.createElement("if");
323 Element availableEle
= document
.createElement("available");
324 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
326 ifEle
.appendChild(availableEle
);
327 Element elseEle
= document
.createElement("then");
329 Element moduleEle
= document
.createElement("ant");
330 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
332 moduleEle
.setAttribute("target", "clean");
334 // Inherit Properties.
335 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
341 Element property
= document
.createElement("property");
342 property
.setAttribute("name", "ARCH");
343 property
.setAttribute("value", fpdModuleId
.getArch());
344 moduleEle
.appendChild(property
);
349 property
= document
.createElement("property");
350 property
.setAttribute("name", "PACKAGE");
351 property
.setAttribute("value", moduleId
.getPackage().getName());
352 moduleEle
.appendChild(property
);
357 property
= document
.createElement("property");
358 property
.setAttribute("name", "PACKAGE_GUID");
359 property
.setAttribute("value", moduleId
.getPackage().getGuid());
360 moduleEle
.appendChild(property
);
365 property
= document
.createElement("property");
366 property
.setAttribute("name", "PACKAGE_VERSION");
367 property
.setAttribute("value", moduleId
.getPackage().getVersion());
368 moduleEle
.appendChild(property
);
373 property
= document
.createElement("property");
374 property
.setAttribute("name", "MODULE_DIR");
375 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
376 moduleEle
.appendChild(property
);
377 elseEle
.appendChild(moduleEle
);
378 ifEle
.appendChild(elseEle
);
379 ele
.appendChild(ifEle
);
382 root
.appendChild(ele
);
385 private void applyCleanall(Document document
, Node root
) {
389 root
.appendChild(document
.createComment("Clean All target"));
390 Element ele
= document
.createElement("target");
391 ele
.setAttribute("name", "cleanall");
394 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
395 for (int i
= 0; i
< targetList
.length
; ++i
) {
396 Element cleanAllEle
= document
.createElement("delete");
397 cleanAllEle
.setAttribute("dir", project
.getProperty("BUILD_DIR") + File
.separatorChar
+ targetList
[i
]);
398 ele
.appendChild(cleanAllEle
);
401 Set set
= outfiles
.keySet();
402 Iterator iter
= set
.iterator();
403 while (iter
.hasNext()) {
404 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
405 ModuleIdentification moduleId
= fpdModuleId
.getModule();
407 Element ifEle
= document
.createElement("if");
408 Element availableEle
= document
.createElement("available");
409 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
411 ifEle
.appendChild(availableEle
);
412 Element elseEle
= document
.createElement("then");
414 Element moduleEle
= document
.createElement("ant");
415 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
417 moduleEle
.setAttribute("target", "cleanall");
419 // Inherit Properties.
420 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
426 Element property
= document
.createElement("property");
427 property
.setAttribute("name", "ARCH");
428 property
.setAttribute("value", fpdModuleId
.getArch());
429 moduleEle
.appendChild(property
);
434 property
= document
.createElement("property");
435 property
.setAttribute("name", "PACKAGE");
436 property
.setAttribute("value", moduleId
.getPackage().getName());
437 moduleEle
.appendChild(property
);
442 property
= document
.createElement("property");
443 property
.setAttribute("name", "PACKAGE_GUID");
444 property
.setAttribute("value", moduleId
.getPackage().getGuid());
445 moduleEle
.appendChild(property
);
450 property
= document
.createElement("property");
451 property
.setAttribute("name", "PACKAGE_VERSION");
452 property
.setAttribute("value", moduleId
.getPackage().getVersion());
453 moduleEle
.appendChild(property
);
458 property
= document
.createElement("property");
459 property
.setAttribute("name", "MODULE_DIR");
460 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
461 moduleEle
.appendChild(property
);
462 elseEle
.appendChild(moduleEle
);
463 ifEle
.appendChild(elseEle
);
464 ele
.appendChild(ifEle
);
467 root
.appendChild(ele
);
470 private void applyUserExtensionsPreBuild(Document document
, Node root
) {
474 root
.appendChild(document
.createComment("Pre Build Processing"));
475 Element ele
= document
.createElement("target");
476 ele
.setAttribute("name", "prebuild");
478 Node node
= SurfaceAreaQuery
.getFpdUserExtensionPreBuild();
481 // For every Target and ToolChain
483 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
484 for (int i
= 0; i
< targetList
.length
; i
++){
485 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
486 for(int j
= 0; j
< toolchainList
.length
; j
++){
490 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
491 + targetList
[i
] + File
.separatorChar
493 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
494 Element fvEle
= document
.createElement("var");
495 fvEle
.setAttribute("name", "FV_DIR");
496 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
497 ele
.appendChild(fvEle
);
499 NodeList childNodes
= node
.getChildNodes();
500 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
501 Node childItem
= childNodes
.item(k
);
502 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
503 ele
.appendChild(recursiveNode(childItem
, document
));
511 root
.appendChild(ele
);
514 private void applyUserExtensionsPostBuild(Document document
, Node root
) {
518 root
.appendChild(document
.createComment("Post Build Processing"));
519 Element ele
= document
.createElement("target");
520 ele
.setAttribute("name", "postbuild");
522 Node node
= SurfaceAreaQuery
.getFpdUserExtensionPostBuild();
525 // For every Target and ToolChain
527 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
528 for (int i
= 0; i
< targetList
.length
; i
++){
529 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
530 for(int j
= 0; j
< toolchainList
.length
; j
++){
534 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
535 + targetList
[i
] + File
.separatorChar
537 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
538 Element fvEle
= document
.createElement("var");
539 fvEle
.setAttribute("name", "FV_DIR");
540 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
541 ele
.appendChild(fvEle
);
543 NodeList childNodes
= node
.getChildNodes();
544 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
545 Node childItem
= childNodes
.item(k
);
546 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
547 ele
.appendChild(recursiveNode(childItem
, document
));
555 root
.appendChild(ele
);
558 private Element
recursiveNode(Node node
, Document document
) {
559 Element root
= document
.createElement(node
.getNodeName());
560 NamedNodeMap attr
= node
.getAttributes();
561 for (int i
= 0; i
< attr
.getLength(); i
++) {
562 Node attrItem
= attr
.item(i
);
563 root
.setAttribute(attrItem
.getNodeName(), attrItem
.getNodeValue());
565 NodeList childNodes
= node
.getChildNodes();
566 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
567 Node childItem
= childNodes
.item(i
);
568 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
569 root
.appendChild(recursiveNode(childItem
, document
));
571 else if (childItem
.getNodeType() == Node
.TEXT_NODE
){
572 if ( ! childItem
.getNodeValue().trim().equalsIgnoreCase("")) {
573 root
.setTextContent(childItem
.getNodeValue());
580 private boolean isListInSequence(String fvName
) {
581 Set
<String
> numbers
= sequences
.keySet();
582 Iterator
<String
> iter
= numbers
.iterator();
583 while (iter
.hasNext()) {
584 Set
<String
> fvNameSet
= sequences
.get(iter
.next());
585 if (fvNameSet
.contains(fvName
)) {