]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java
e6a1002da3b711bbd0384b719b07a8e9e07bc680
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / fpd / PlatformBuildFileGenerator.java
1 /** @file
2
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
8
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.
11 **/
12 package org.tianocore.build.fpd;
13
14 import java.io.File;
15 import java.util.Iterator;
16 import java.util.Map;
17 import java.util.Set;
18
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;
28
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;
41
42 public class PlatformBuildFileGenerator {
43
44 private String platformName;
45
46 ///
47 /// Mapping from modules identification to out put file name
48 ///
49 private Map<FpdModuleIdentification, String> outfiles;
50
51 private boolean isUnified = true;
52
53 private Project project;
54
55 private String info = "DO NOT EDIT \n"
56 + "This file is auto-generated by the build utility\n"
57 + "\n"
58 + "Abstract:\n"
59 + "Auto-generated ANT build file for building EFI Modules and Platforms\n";
60
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");
66 }
67
68 /**
69 Generate build.out.xml file.
70
71 @throws BuildException
72 build.out.xml XML document create error
73 **/
74 public void genBuildFile() throws BuildException {
75 DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
76 try {
77 DocumentBuilder dombuilder = domfac.newDocumentBuilder();
78 Document document = dombuilder.newDocument();
79 Comment rootComment = document.createComment(info);
80 //
81 // create root element and its attributes
82 //
83 Element root = document.createElement("project");
84 root.setAttribute("name", project.getProperty("PLATFORM"));
85 root.setAttribute("default", "all");
86 root.setAttribute("basedir", ".");
87
88 //
89 // element for External ANT tasks
90 //
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);
95
96 ele = document.createElement("taskdef");
97 ele.setAttribute("resource", "frameworktasks.tasks");
98 root.appendChild(ele);
99
100 ele = document.createElement("taskdef");
101 ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
102 root.appendChild(ele);
103
104 ele = document.createElement("property");
105 ele.setAttribute("environment", "env");
106 root.appendChild(ele);
107
108 //
109 // Default Target
110 //
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);
116
117 //
118 // Modules and Fvs Target
119 //
120 applyModules(document, root);
121
122 applyFvs(document, root);
123
124 //
125 // Clean Target
126 //
127 applyClean(document, root);
128
129 //
130 // Deep Clean Target
131 //
132 applyCleanall(document, root);
133
134 //
135 // User Extension pre build
136 //
137 applyUserExtensionsPreBuild(document, root);
138
139 //
140 // User Extension Post build
141 //
142 applyUserExtensionsPostBuild(document, root);
143
144 document.appendChild(rootComment);
145 document.appendChild(root);
146 //
147 // Prepare the DOM document for writing
148 //
149 Source source = new DOMSource(document);
150 //
151 // Prepare the output file
152 //
153 File file = new File(project.getProperty("PLATFORM_DIR") + File.separatorChar + platformName + "_build.xml");
154 //
155 // generate all directory path
156 //
157 (new File(file.getParent())).mkdirs();
158 Result result = new StreamResult(file);
159 //
160 // Write the DOM document to the file
161 //
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());
168 }
169 }
170
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");
175
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");
183 //
184 // Inherit Properties.
185 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
186 //
187
188 //
189 // ARCH
190 //
191 Element property = document.createElement("property");
192 property.setAttribute("name", "ARCH");
193 property.setAttribute("value", fpdModuleId.getArch());
194 moduleEle.appendChild(property);
195
196 //
197 // MODULE_GUID
198 //
199 property = document.createElement("property");
200 property.setAttribute("name", "MODULE_GUID");
201 property.setAttribute("value", moduleId.getGuid());
202 moduleEle.appendChild(property);
203
204 //
205 // MODULE_VERSION
206 //
207 property = document.createElement("property");
208 property.setAttribute("name", "MODULE_VERSION");
209 property.setAttribute("value", moduleId.getVersion());
210 moduleEle.appendChild(property);
211
212 //
213 // PACKAGE_GUID
214 //
215 property = document.createElement("property");
216 property.setAttribute("name", "PACKAGE_GUID");
217 property.setAttribute("value", moduleId.getPackage().getGuid());
218 moduleEle.appendChild(property);
219
220 //
221 // PACKAGE_VERSION
222 //
223 property = document.createElement("property");
224 property.setAttribute("name", "PACKAGE_VERSION");
225 property.setAttribute("value", moduleId.getPackage().getVersion());
226 moduleEle.appendChild(property);
227
228 ele.appendChild(moduleEle);
229 }
230 root.appendChild(ele);
231 }
232
233 private void applyFvs(Document document, Node root) {
234 //
235 // FVS Target
236 //
237 root.appendChild(document.createComment("FVs target"));
238 Element ele = document.createElement("target");
239 ele.setAttribute("name", "fvs");
240
241 //
242 // For every Target and ToolChain
243 //
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);
258 }
259 }
260 }
261 root.appendChild(ele);
262 }
263
264 private void applyClean(Document document, Node root) {
265 //
266 // Clean Target
267 //
268 root.appendChild(document.createComment("Clean target"));
269 Element ele = document.createElement("target");
270 ele.setAttribute("name", "clean");
271
272 if (isUnified) {
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);
280 } else {
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();
286
287 Element ifEle = document.createElement("if");
288 Element availableEle = document.createElement("available");
289 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
290 + "build.xml");
291 ifEle.appendChild(availableEle);
292 Element elseEle = document.createElement("then");
293
294 Element moduleEle = document.createElement("ant");
295 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
296 + "build.xml");
297 moduleEle.setAttribute("target", "clean");
298 //
299 // Inherit Properties.
300 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
301 //
302
303 //
304 // ARCH
305 //
306 Element property = document.createElement("property");
307 property.setAttribute("name", "ARCH");
308 property.setAttribute("value", fpdModuleId.getArch());
309 moduleEle.appendChild(property);
310
311 //
312 // PACKAGE
313 //
314 property = document.createElement("property");
315 property.setAttribute("name", "PACKAGE");
316 property.setAttribute("value", moduleId.getPackage().getName());
317 moduleEle.appendChild(property);
318
319 //
320 // PACKAGE_GUID
321 //
322 property = document.createElement("property");
323 property.setAttribute("name", "PACKAGE_GUID");
324 property.setAttribute("value", moduleId.getPackage().getGuid());
325 moduleEle.appendChild(property);
326
327 //
328 // PACKAGE_VERSION
329 //
330 property = document.createElement("property");
331 property.setAttribute("name", "PACKAGE_VERSION");
332 property.setAttribute("value", moduleId.getPackage().getVersion());
333 moduleEle.appendChild(property);
334
335 //
336 // MODULE_DIR
337 //
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);
345 }
346 }
347 root.appendChild(ele);
348 }
349
350 private void applyCleanall(Document document, Node root) {
351 //
352 // Deep Clean Target
353 //
354 root.appendChild(document.createComment("Target: cleanall"));
355 Element ele = document.createElement("target");
356 ele.setAttribute("name", "cleanall");
357
358 if (isUnified) {
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);
364 }
365 } else {
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();
371
372 Element ifEle = document.createElement("if");
373 Element availableEle = document.createElement("available");
374 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
375 + "build.xml");
376 ifEle.appendChild(availableEle);
377 Element elseEle = document.createElement("then");
378
379 Element moduleEle = document.createElement("ant");
380 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
381 + "build.xml");
382 moduleEle.setAttribute("target", "cleanall");
383 //
384 // Inherit Properties.
385 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
386 //
387
388 //
389 // ARCH
390 //
391 Element property = document.createElement("property");
392 property.setAttribute("name", "ARCH");
393 property.setAttribute("value", fpdModuleId.getArch());
394 moduleEle.appendChild(property);
395
396 //
397 // PACKAGE
398 //
399 property = document.createElement("property");
400 property.setAttribute("name", "PACKAGE");
401 property.setAttribute("value", moduleId.getPackage().getName());
402 moduleEle.appendChild(property);
403
404 //
405 // PACKAGE_GUID
406 //
407 property = document.createElement("property");
408 property.setAttribute("name", "PACKAGE_GUID");
409 property.setAttribute("value", moduleId.getPackage().getGuid());
410 moduleEle.appendChild(property);
411
412 //
413 // PACKAGE_VERSION
414 //
415 property = document.createElement("property");
416 property.setAttribute("name", "PACKAGE_VERSION");
417 property.setAttribute("value", moduleId.getPackage().getVersion());
418 moduleEle.appendChild(property);
419
420 //
421 // MODULE_DIR
422 //
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);
430 }
431 }
432 root.appendChild(ele);
433 }
434
435 private void applyUserExtensionsPreBuild(Document document, Node root) {
436 //
437 // User Extensions
438 //
439 root.appendChild(document.createComment("Pre-Build Processing"));
440 Element ele = document.createElement("target");
441 ele.setAttribute("name", "prebuild");
442
443 Node node = SurfaceAreaQuery.getFpdUserExtensionPreBuild();
444 if (node != null) {
445 //
446 // For every Target and ToolChain
447 //
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++){
452 //
453 // Prepare FV_DIR
454 //
455 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
456 + targetList[i] + File.separatorChar
457 + toolchainList[j];
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);
463
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));
469 }
470 }
471
472 }
473 }
474 }
475
476 root.appendChild(ele);
477 }
478
479 private void applyUserExtensionsPostBuild(Document document, Node root) {
480 //
481 // User Extensions
482 //
483 root.appendChild(document.createComment("Post-Build Processing"));
484 Element ele = document.createElement("target");
485 ele.setAttribute("name", "postbuild");
486
487 Node node = SurfaceAreaQuery.getFpdUserExtensionPostBuild();
488 if (node != null) {
489 //
490 // For every Target and ToolChain
491 //
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++){
496 //
497 // Prepare FV_DIR
498 //
499 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
500 + targetList[i] + File.separatorChar
501 + toolchainList[j];
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);
507
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));
513 }
514 }
515
516 }
517 }
518 }
519
520 root.appendChild(ele);
521 }
522
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());
529 }
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));
535 }
536 else if (childItem.getNodeType() == Node.TEXT_NODE){
537 if ( ! childItem.getNodeValue().trim().equalsIgnoreCase("")) {
538 root.setTextContent(childItem.getNodeValue());
539 }
540 }
541 }
542 return root;
543 }
544 }