]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java
Removed the printStackTrace() which is used only for debug purpose.
[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 ///
52 /// Mapping from FV name to its modules
53 ///
54 private Map<String, Set<FpdModuleIdentification>> fvs;
55
56 ///
57 /// Mapping from sequence number to FV names
58 ///
59 private Map<String, Set<String>> sequences;
60
61 private boolean isUnified = true;
62
63 private Project project;
64
65 private String info = "DO NOT EDIT \n"
66 + "File auto-generated by build utility\n"
67 + "\n"
68 + "Abstract:\n"
69 + "Auto-generated ANT build file for building of EFI Modules/Platforms\n";
70
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;
74 this.fvs = fvs;
75 this.sequences = sequences;
76 this.isUnified = isUnified;
77 this.platformName = project.getProperty("PLATFORM");
78 }
79
80 /**
81 Generate build.out.xml file.
82
83 @throws BuildException
84 build.out.xml XML document create error
85 **/
86 public void genBuildFile() throws BuildException {
87 DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
88 try {
89 DocumentBuilder dombuilder = domfac.newDocumentBuilder();
90 Document document = dombuilder.newDocument();
91 Comment rootComment = document.createComment(info);
92 //
93 // create root element and its attributes
94 //
95 Element root = document.createElement("project");
96 root.setAttribute("name", project.getProperty("PLATFORM"));
97 root.setAttribute("default", "all");
98 root.setAttribute("basedir", ".");
99
100 //
101 // element for External ANT tasks
102 //
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);
107
108 ele = document.createElement("taskdef");
109 ele.setAttribute("resource", "frameworktasks.tasks");
110 root.appendChild(ele);
111
112 ele = document.createElement("taskdef");
113 ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
114 root.appendChild(ele);
115
116 ele = document.createElement("property");
117 ele.setAttribute("environment", "env");
118 root.appendChild(ele);
119
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) {
126 dependsStr += " , ";
127 }
128 dependsStr += "modules" + num + ", fvs" + num;
129 }
130
131 //
132 // Default Target
133 //
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);
139
140 //
141 // Modules and Fvs Target
142 //
143 sequenceIter = sequenceKeys.iterator();
144 while (sequenceIter.hasNext()) {
145 String num = (String)sequenceIter.next();
146 applyModules(document, root, num);
147 applyFvs(document, root, num);
148 }
149
150 //
151 // Clean Target
152 //
153 applyClean(document, root);
154
155 //
156 // Deep Clean Target
157 //
158 applyCleanall(document, root);
159
160 //
161 // User Extension pre build
162 //
163 applyUserExtensionsPreBuild(document, root);
164
165 //
166 // User Extension Post build
167 //
168 applyUserExtensionsPostBuild(document, root);
169
170 document.appendChild(rootComment);
171 document.appendChild(root);
172 //
173 // Prepare the DOM document for writing
174 //
175 Source source = new DOMSource(document);
176 //
177 // Prepare the output file
178 //
179 File file = new File(project.getProperty("PLATFORM_DIR") + File.separatorChar + platformName + "_build.xml");
180 //
181 // generate all directory path
182 //
183 (new File(file.getParent())).mkdirs();
184 Result result = new StreamResult(file);
185 //
186 // Write the DOM document to the file
187 //
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());
194 }
195 }
196
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);
201
202 Set<String> fvNameSet = sequences.get(num);
203
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");
214 //
215 // Inherit Properties.
216 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
217 //
218
219 //
220 // ARCH
221 //
222 Element property = document.createElement("property");
223 property.setAttribute("name", "ARCH");
224 property.setAttribute("value", fpdModuleId.getArch());
225 moduleEle.appendChild(property);
226
227 //
228 // MODULE_GUID
229 //
230 property = document.createElement("property");
231 property.setAttribute("name", "MODULE_GUID");
232 property.setAttribute("value", moduleId.getGuid());
233 moduleEle.appendChild(property);
234
235 //
236 // MODULE_VERSION
237 //
238 property = document.createElement("property");
239 property.setAttribute("name", "MODULE_VERSION");
240 property.setAttribute("value", moduleId.getVersion());
241 moduleEle.appendChild(property);
242
243 //
244 // PACKAGE_GUID
245 //
246 property = document.createElement("property");
247 property.setAttribute("name", "PACKAGE_GUID");
248 property.setAttribute("value", moduleId.getPackage().getGuid());
249 moduleEle.appendChild(property);
250
251 //
252 // PACKAGE_VERSION
253 //
254 property = document.createElement("property");
255 property.setAttribute("name", "PACKAGE_VERSION");
256 property.setAttribute("value", moduleId.getPackage().getVersion());
257 moduleEle.appendChild(property);
258
259 ele.appendChild(moduleEle);
260 }
261 }
262 root.appendChild(ele);
263 }
264
265 private void applyFvs(Document document, Node root, String num) {
266 Set<String> fvNameSet = sequences.get(num);
267 //
268 // FVS Target
269 //
270 root.appendChild(document.createComment("FVs target"));
271 Element ele = document.createElement("target");
272 ele.setAttribute("name", "fvs" + num);
273
274 //
275 // For every Target and ToolChain
276 //
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[i] + 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);
292 }
293 }
294 }
295 }
296 root.appendChild(ele);
297 }
298
299 private void applyClean(Document document, Node root) {
300 //
301 // Clean Target
302 //
303 root.appendChild(document.createComment("Clean target"));
304 Element ele = document.createElement("target");
305 ele.setAttribute("name", "clean");
306
307 if (isUnified) {
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);
315 } else {
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();
321
322 Element ifEle = document.createElement("if");
323 Element availableEle = document.createElement("available");
324 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
325 + "build.xml");
326 ifEle.appendChild(availableEle);
327 Element elseEle = document.createElement("then");
328
329 Element moduleEle = document.createElement("ant");
330 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
331 + "build.xml");
332 moduleEle.setAttribute("target", "clean");
333 //
334 // Inherit Properties.
335 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
336 //
337
338 //
339 // ARCH
340 //
341 Element property = document.createElement("property");
342 property.setAttribute("name", "ARCH");
343 property.setAttribute("value", fpdModuleId.getArch());
344 moduleEle.appendChild(property);
345
346 //
347 // PACKAGE
348 //
349 property = document.createElement("property");
350 property.setAttribute("name", "PACKAGE");
351 property.setAttribute("value", moduleId.getPackage().getName());
352 moduleEle.appendChild(property);
353
354 //
355 // PACKAGE_GUID
356 //
357 property = document.createElement("property");
358 property.setAttribute("name", "PACKAGE_GUID");
359 property.setAttribute("value", moduleId.getPackage().getGuid());
360 moduleEle.appendChild(property);
361
362 //
363 // PACKAGE_VERSION
364 //
365 property = document.createElement("property");
366 property.setAttribute("name", "PACKAGE_VERSION");
367 property.setAttribute("value", moduleId.getPackage().getVersion());
368 moduleEle.appendChild(property);
369
370 //
371 // MODULE_DIR
372 //
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);
380 }
381 }
382 root.appendChild(ele);
383 }
384
385 private void applyCleanall(Document document, Node root) {
386 //
387 // Deep Clean Target
388 //
389 root.appendChild(document.createComment("Clean All target"));
390 Element ele = document.createElement("target");
391 ele.setAttribute("name", "cleanall");
392
393 if (isUnified) {
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);
399 }
400 } else {
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();
406
407 Element ifEle = document.createElement("if");
408 Element availableEle = document.createElement("available");
409 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
410 + "build.xml");
411 ifEle.appendChild(availableEle);
412 Element elseEle = document.createElement("then");
413
414 Element moduleEle = document.createElement("ant");
415 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
416 + "build.xml");
417 moduleEle.setAttribute("target", "cleanall");
418 //
419 // Inherit Properties.
420 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
421 //
422
423 //
424 // ARCH
425 //
426 Element property = document.createElement("property");
427 property.setAttribute("name", "ARCH");
428 property.setAttribute("value", fpdModuleId.getArch());
429 moduleEle.appendChild(property);
430
431 //
432 // PACKAGE
433 //
434 property = document.createElement("property");
435 property.setAttribute("name", "PACKAGE");
436 property.setAttribute("value", moduleId.getPackage().getName());
437 moduleEle.appendChild(property);
438
439 //
440 // PACKAGE_GUID
441 //
442 property = document.createElement("property");
443 property.setAttribute("name", "PACKAGE_GUID");
444 property.setAttribute("value", moduleId.getPackage().getGuid());
445 moduleEle.appendChild(property);
446
447 //
448 // PACKAGE_VERSION
449 //
450 property = document.createElement("property");
451 property.setAttribute("name", "PACKAGE_VERSION");
452 property.setAttribute("value", moduleId.getPackage().getVersion());
453 moduleEle.appendChild(property);
454
455 //
456 // MODULE_DIR
457 //
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);
465 }
466 }
467 root.appendChild(ele);
468 }
469
470 private void applyUserExtensionsPreBuild(Document document, Node root) {
471 //
472 // User Extensions
473 //
474 root.appendChild(document.createComment("Pre Build Processing"));
475 Element ele = document.createElement("target");
476 ele.setAttribute("name", "prebuild");
477
478 Node node = SurfaceAreaQuery.getFpdUserExtensionPreBuild();
479 if (node != null) {
480 //
481 // For every Target and ToolChain
482 //
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++){
487 //
488 // Prepare FV_DIR
489 //
490 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
491 + targetList[i] + File.separatorChar
492 + toolchainList[j];
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);
498
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));
504 }
505 }
506
507 }
508 }
509 }
510
511 root.appendChild(ele);
512 }
513
514 private void applyUserExtensionsPostBuild(Document document, Node root) {
515 //
516 // User Extensions
517 //
518 root.appendChild(document.createComment("Post Build Processing"));
519 Element ele = document.createElement("target");
520 ele.setAttribute("name", "postbuild");
521
522 Node node = SurfaceAreaQuery.getFpdUserExtensionPostBuild();
523 if (node != null) {
524 //
525 // For every Target and ToolChain
526 //
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++){
531 //
532 // Prepare FV_DIR
533 //
534 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
535 + targetList[i] + File.separatorChar
536 + toolchainList[j];
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);
542
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));
548 }
549 }
550
551 }
552 }
553 }
554
555 root.appendChild(ele);
556 }
557
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());
564 }
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));
570 }
571 else if (childItem.getNodeType() == Node.TEXT_NODE){
572 if ( ! childItem.getNodeValue().trim().equalsIgnoreCase("")) {
573 root.setTextContent(childItem.getNodeValue());
574 }
575 }
576 }
577 return root;
578 }
579
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)) {
586 return true;
587 }
588 }
589 return false;
590 }
591 }