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
;
51 private boolean isUnified
= true;
53 private Project project
;
55 private String info
= "DO NOT EDIT \n"
56 + "This file is auto-generated by the build utility\n"
59 + "Auto-generated ANT build file for building EFI Modules and Platforms\n";
61 public PlatformBuildFileGenerator(Project project
, Map
<FpdModuleIdentification
, String
> outfiles
, boolean isUnified
){
62 this.project
= project
;
63 this.outfiles
= outfiles
;
64 this.isUnified
= isUnified
;
65 this.platformName
= project
.getProperty("PLATFORM");
69 Generate build.out.xml file.
71 @throws BuildException
72 build.out.xml XML document create error
74 public void genBuildFile() throws BuildException
{
75 DocumentBuilderFactory domfac
= DocumentBuilderFactory
.newInstance();
77 DocumentBuilder dombuilder
= domfac
.newDocumentBuilder();
78 Document document
= dombuilder
.newDocument();
79 Comment rootComment
= document
.createComment(info
);
81 // create root element and its attributes
83 Element root
= document
.createElement("project");
84 root
.setAttribute("name", project
.getProperty("PLATFORM"));
85 root
.setAttribute("default", "all");
86 root
.setAttribute("basedir", ".");
89 // element for External ANT tasks
91 root
.appendChild(document
.createComment("Apply external ANT tasks"));
92 Element ele
= document
.createElement("taskdef");
93 ele
.setAttribute("resource", "GenBuild.tasks");
94 root
.appendChild(ele
);
96 ele
= document
.createElement("taskdef");
97 ele
.setAttribute("resource", "frameworktasks.tasks");
98 root
.appendChild(ele
);
100 ele
= document
.createElement("taskdef");
101 ele
.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
102 root
.appendChild(ele
);
104 ele
= document
.createElement("property");
105 ele
.setAttribute("environment", "env");
106 root
.appendChild(ele
);
111 root
.appendChild(document
.createComment("Default target"));
112 ele
= document
.createElement("target");
113 ele
.setAttribute("name", "all");
114 ele
.setAttribute("depends", "prebuild, modules, fvs, postbuild");
115 root
.appendChild(ele
);
118 // Modules and Fvs Target
120 applyModules(document
, root
);
122 applyFvs(document
, root
);
127 applyClean(document
, root
);
132 applyCleanall(document
, root
);
135 // User Extension pre build
137 applyUserExtensionsPreBuild(document
, root
);
140 // User Extension Post build
142 applyUserExtensionsPostBuild(document
, root
);
144 document
.appendChild(rootComment
);
145 document
.appendChild(root
);
147 // Prepare the DOM document for writing
149 Source source
= new DOMSource(document
);
151 // Prepare the output file
153 File file
= new File(project
.getProperty("PLATFORM_DIR") + File
.separatorChar
+ platformName
+ "_build.xml");
155 // generate all directory path
157 (new File(file
.getParent())).mkdirs();
158 Result result
= new StreamResult(file
);
160 // Write the DOM document to the file
162 Transformer xformer
= TransformerFactory
.newInstance().newTransformer();
163 xformer
.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
164 xformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
165 xformer
.transform(source
, result
);
166 } catch (Exception ex
) {
167 throw new BuildException("Generation of the " + platformName
+ "_build.xml failed!\n" + ex
.getMessage());
171 private void applyModules(Document document
, Node root
) {
172 root
.appendChild(document
.createComment("Modules target"));
173 Element ele
= document
.createElement("target");
174 ele
.setAttribute("name", "modules");
176 Set
<FpdModuleIdentification
> set
= outfiles
.keySet();
177 Iterator iter
= set
.iterator();
178 while (iter
.hasNext()) {
179 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
180 ModuleIdentification moduleId
= fpdModuleId
.getModule();
181 Element moduleEle
= document
.createElement("GenBuild");
182 moduleEle
.setAttribute("type", "build");
184 // Inherit Properties.
185 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
191 Element property
= document
.createElement("property");
192 property
.setAttribute("name", "ARCH");
193 property
.setAttribute("value", fpdModuleId
.getArch());
194 moduleEle
.appendChild(property
);
199 property
= document
.createElement("property");
200 property
.setAttribute("name", "MODULE_GUID");
201 property
.setAttribute("value", moduleId
.getGuid());
202 moduleEle
.appendChild(property
);
207 property
= document
.createElement("property");
208 property
.setAttribute("name", "MODULE_VERSION");
209 property
.setAttribute("value", moduleId
.getVersion());
210 moduleEle
.appendChild(property
);
215 property
= document
.createElement("property");
216 property
.setAttribute("name", "PACKAGE_GUID");
217 property
.setAttribute("value", moduleId
.getPackage().getGuid());
218 moduleEle
.appendChild(property
);
223 property
= document
.createElement("property");
224 property
.setAttribute("name", "PACKAGE_VERSION");
225 property
.setAttribute("value", moduleId
.getPackage().getVersion());
226 moduleEle
.appendChild(property
);
228 ele
.appendChild(moduleEle
);
230 root
.appendChild(ele
);
233 private void applyFvs(Document document
, Node root
) {
237 root
.appendChild(document
.createComment("FVs target"));
238 Element ele
= document
.createElement("target");
239 ele
.setAttribute("name", "fvs");
242 // For every Target and ToolChain
244 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
245 for (int i
= 0; i
< targetList
.length
; i
++){
246 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
247 for(int j
= 0; j
< toolchainList
.length
; j
++){
248 String fvOutputDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
249 + targetList
[i
] + File
.separatorChar
250 + toolchainList
[j
] + File
.separatorChar
+ "FV";
251 String
[] validFv
= SurfaceAreaQuery
.getFpdValidImageNames();
252 for (int k
= 0; k
< validFv
.length
; k
++) {
253 String inputFile
= fvOutputDir
+ "" + File
.separatorChar
+ validFv
[k
].toUpperCase() + ".inf";
254 Element fvEle
= document
.createElement("genfvimage");
255 fvEle
.setAttribute("infFile", inputFile
);
256 fvEle
.setAttribute("outputDir", fvOutputDir
);
257 ele
.appendChild(fvEle
);
261 root
.appendChild(ele
);
264 private void applyClean(Document document
, Node root
) {
268 root
.appendChild(document
.createComment("Clean target"));
269 Element ele
= document
.createElement("target");
270 ele
.setAttribute("name", "clean");
273 Element cleanEle
= document
.createElement("delete");
274 cleanEle
.setAttribute("includeemptydirs", "true");
275 Element filesetEle
= document
.createElement("fileset");
276 filesetEle
.setAttribute("dir", project
.getProperty("BUILD_DIR"));
277 filesetEle
.setAttribute("includes", "**\\OUTPUT\\**");
278 cleanEle
.appendChild(filesetEle
);
279 ele
.appendChild(cleanEle
);
281 Set set
= outfiles
.keySet();
282 Iterator iter
= set
.iterator();
283 while (iter
.hasNext()) {
284 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
285 ModuleIdentification moduleId
= fpdModuleId
.getModule();
287 Element ifEle
= document
.createElement("if");
288 Element availableEle
= document
.createElement("available");
289 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
291 ifEle
.appendChild(availableEle
);
292 Element elseEle
= document
.createElement("then");
294 Element moduleEle
= document
.createElement("ant");
295 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
297 moduleEle
.setAttribute("target", "clean");
299 // Inherit Properties.
300 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
306 Element property
= document
.createElement("property");
307 property
.setAttribute("name", "ARCH");
308 property
.setAttribute("value", fpdModuleId
.getArch());
309 moduleEle
.appendChild(property
);
314 property
= document
.createElement("property");
315 property
.setAttribute("name", "PACKAGE");
316 property
.setAttribute("value", moduleId
.getPackage().getName());
317 moduleEle
.appendChild(property
);
322 property
= document
.createElement("property");
323 property
.setAttribute("name", "PACKAGE_GUID");
324 property
.setAttribute("value", moduleId
.getPackage().getGuid());
325 moduleEle
.appendChild(property
);
330 property
= document
.createElement("property");
331 property
.setAttribute("name", "PACKAGE_VERSION");
332 property
.setAttribute("value", moduleId
.getPackage().getVersion());
333 moduleEle
.appendChild(property
);
338 property
= document
.createElement("property");
339 property
.setAttribute("name", "MODULE_DIR");
340 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
341 moduleEle
.appendChild(property
);
342 elseEle
.appendChild(moduleEle
);
343 ifEle
.appendChild(elseEle
);
344 ele
.appendChild(ifEle
);
347 root
.appendChild(ele
);
350 private void applyCleanall(Document document
, Node root
) {
354 root
.appendChild(document
.createComment("Target: cleanall"));
355 Element ele
= document
.createElement("target");
356 ele
.setAttribute("name", "cleanall");
359 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
360 for (int i
= 0; i
< targetList
.length
; ++i
) {
361 Element cleanAllEle
= document
.createElement("delete");
362 cleanAllEle
.setAttribute("dir", project
.getProperty("BUILD_DIR") + File
.separatorChar
+ targetList
[i
]);
363 ele
.appendChild(cleanAllEle
);
366 Set set
= outfiles
.keySet();
367 Iterator iter
= set
.iterator();
368 while (iter
.hasNext()) {
369 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
370 ModuleIdentification moduleId
= fpdModuleId
.getModule();
372 Element ifEle
= document
.createElement("if");
373 Element availableEle
= document
.createElement("available");
374 availableEle
.setAttribute("file", moduleId
.getMsaFile().getParent() + File
.separatorChar
376 ifEle
.appendChild(availableEle
);
377 Element elseEle
= document
.createElement("then");
379 Element moduleEle
= document
.createElement("ant");
380 moduleEle
.setAttribute("antfile", moduleId
.getMsaFile().getParent() + File
.separatorChar
382 moduleEle
.setAttribute("target", "cleanall");
384 // Inherit Properties.
385 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
391 Element property
= document
.createElement("property");
392 property
.setAttribute("name", "ARCH");
393 property
.setAttribute("value", fpdModuleId
.getArch());
394 moduleEle
.appendChild(property
);
399 property
= document
.createElement("property");
400 property
.setAttribute("name", "PACKAGE");
401 property
.setAttribute("value", moduleId
.getPackage().getName());
402 moduleEle
.appendChild(property
);
407 property
= document
.createElement("property");
408 property
.setAttribute("name", "PACKAGE_GUID");
409 property
.setAttribute("value", moduleId
.getPackage().getGuid());
410 moduleEle
.appendChild(property
);
415 property
= document
.createElement("property");
416 property
.setAttribute("name", "PACKAGE_VERSION");
417 property
.setAttribute("value", moduleId
.getPackage().getVersion());
418 moduleEle
.appendChild(property
);
423 property
= document
.createElement("property");
424 property
.setAttribute("name", "MODULE_DIR");
425 property
.setAttribute("value", moduleId
.getMsaFile().getParent());
426 moduleEle
.appendChild(property
);
427 elseEle
.appendChild(moduleEle
);
428 ifEle
.appendChild(elseEle
);
429 ele
.appendChild(ifEle
);
432 root
.appendChild(ele
);
435 private void applyUserExtensionsPreBuild(Document document
, Node root
) {
439 root
.appendChild(document
.createComment("Pre-Build Processing"));
440 Element ele
= document
.createElement("target");
441 ele
.setAttribute("name", "prebuild");
443 Node node
= SurfaceAreaQuery
.getFpdUserExtensionPreBuild();
446 // For every Target and ToolChain
448 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
449 for (int i
= 0; i
< targetList
.length
; i
++){
450 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
451 for(int j
= 0; j
< toolchainList
.length
; j
++){
455 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
456 + targetList
[i
] + File
.separatorChar
458 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
459 Element fvEle
= document
.createElement("var");
460 fvEle
.setAttribute("name", "FV_DIR");
461 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
462 ele
.appendChild(fvEle
);
464 NodeList childNodes
= node
.getChildNodes();
465 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
466 Node childItem
= childNodes
.item(k
);
467 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
468 ele
.appendChild(recursiveNode(childItem
, document
));
476 root
.appendChild(ele
);
479 private void applyUserExtensionsPostBuild(Document document
, Node root
) {
483 root
.appendChild(document
.createComment("Post-Build Processing"));
484 Element ele
= document
.createElement("target");
485 ele
.setAttribute("name", "postbuild");
487 Node node
= SurfaceAreaQuery
.getFpdUserExtensionPostBuild();
490 // For every Target and ToolChain
492 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
493 for (int i
= 0; i
< targetList
.length
; i
++){
494 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
495 for(int j
= 0; j
< toolchainList
.length
; j
++){
499 String ffsCommonDir
= project
.getProperty("BUILD_DIR") + File
.separatorChar
500 + targetList
[i
] + File
.separatorChar
502 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
503 Element fvEle
= document
.createElement("var");
504 fvEle
.setAttribute("name", "FV_DIR");
505 fvEle
.setAttribute("value", fvDir
.getPath().replaceAll("(\\\\)", "/"));
506 ele
.appendChild(fvEle
);
508 NodeList childNodes
= node
.getChildNodes();
509 for (int k
= 0; k
< childNodes
.getLength(); k
++) {
510 Node childItem
= childNodes
.item(k
);
511 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
512 ele
.appendChild(recursiveNode(childItem
, document
));
520 root
.appendChild(ele
);
523 private Element
recursiveNode(Node node
, Document document
) {
524 Element root
= document
.createElement(node
.getNodeName());
525 NamedNodeMap attr
= node
.getAttributes();
526 for (int i
= 0; i
< attr
.getLength(); i
++) {
527 Node attrItem
= attr
.item(i
);
528 root
.setAttribute(attrItem
.getNodeName(), attrItem
.getNodeValue());
530 NodeList childNodes
= node
.getChildNodes();
531 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
532 Node childItem
= childNodes
.item(i
);
533 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
534 root
.appendChild(recursiveNode(childItem
, document
));
536 else if (childItem
.getNodeType() == Node
.TEXT_NODE
){
537 if ( ! childItem
.getNodeValue().trim().equalsIgnoreCase("")) {
538 root
.setTextContent(childItem
.getNodeValue());