]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java
ef6dc7223e535a03b5596cd4b672c19926569c90
[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.HashMap;
16 import java.util.Iterator;
17 import java.util.Map;
18 import java.util.Set;
19
20 import javax.xml.parsers.DocumentBuilder;
21 import javax.xml.parsers.DocumentBuilderFactory;
22 import javax.xml.transform.OutputKeys;
23 import javax.xml.transform.Result;
24 import javax.xml.transform.Source;
25 import javax.xml.transform.Transformer;
26 import javax.xml.transform.TransformerFactory;
27 import javax.xml.transform.dom.DOMSource;
28 import javax.xml.transform.stream.StreamResult;
29
30 import org.apache.tools.ant.BuildException;
31 import org.apache.tools.ant.Project;
32 import org.tianocore.build.global.GlobalData;
33 import org.tianocore.build.global.SurfaceAreaQuery;
34 import org.tianocore.build.id.FpdModuleIdentification;
35 import org.tianocore.build.id.ModuleIdentification;
36 import org.w3c.dom.Comment;
37 import org.w3c.dom.Document;
38 import org.w3c.dom.Element;
39 import org.w3c.dom.NamedNodeMap;
40 import org.w3c.dom.Node;
41 import org.w3c.dom.NodeList;
42
43 /**
44 class PlatformBuildFileGenerator is used to generate ${PLATFORM}_build.xml file.
45
46 @since GenBuild 1.0
47 **/
48 public class PlatformBuildFileGenerator {
49
50 private String platformName;
51
52 ///
53 /// Mapping from modules identification to out put file name
54 ///
55 private Map<FpdModuleIdentification, String> outfiles;
56
57 ///
58 /// Mapping from FV name to its modules
59 ///
60 private Map<String, Set<FpdModuleIdentification>> fvs = new HashMap<String, Set<FpdModuleIdentification>>();
61
62
63 private boolean isUnified = true;
64
65 private Project project;
66
67 private String info = "DO NOT EDIT \n"
68 + "This file is auto-generated by the build utility\n"
69 + "\n"
70 + "Abstract:\n"
71 + "Auto-generated ANT build file for building EFI Modules and Platforms\n";
72
73 public PlatformBuildFileGenerator(Project project, Map<FpdModuleIdentification, String> outfiles, Map<String, Set<FpdModuleIdentification>> fvs, boolean isUnified){
74 this.project = project;
75 this.outfiles = outfiles;
76 this.isUnified = isUnified;
77 this.fvs = fvs;
78 this.platformName = project.getProperty("PLATFORM");
79 }
80
81 /**
82 Generate build.out.xml file.
83
84 @throws BuildException
85 build.out.xml XML document create error
86 **/
87 public void genBuildFile() throws BuildException {
88 DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
89 try {
90 DocumentBuilder dombuilder = domfac.newDocumentBuilder();
91 Document document = dombuilder.newDocument();
92 Comment rootComment = document.createComment(info);
93 //
94 // create root element and its attributes
95 //
96 Element root = document.createElement("project");
97 root.setAttribute("name", project.getProperty("PLATFORM"));
98 root.setAttribute("default", "all");
99 root.setAttribute("basedir", ".");
100
101 //
102 // element for External ANT tasks
103 //
104 root.appendChild(document.createComment("Apply external ANT tasks"));
105 Element ele = document.createElement("taskdef");
106 ele.setAttribute("resource", "GenBuild.tasks");
107 root.appendChild(ele);
108
109 ele = document.createElement("taskdef");
110 ele.setAttribute("resource", "frameworktasks.tasks");
111 root.appendChild(ele);
112
113 ele = document.createElement("taskdef");
114 ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
115 root.appendChild(ele);
116
117 ele = document.createElement("property");
118 ele.setAttribute("environment", "env");
119 root.appendChild(ele);
120
121 //
122 // Default Target
123 //
124 root.appendChild(document.createComment("Default target"));
125 ele = document.createElement("target");
126 ele.setAttribute("name", "all");
127 ele.setAttribute("depends", "prebuild, modules, fvs, postbuild");
128 root.appendChild(ele);
129
130 //
131 // Modules and Fvs Target
132 //
133 applyModules(document, root);
134
135 applyFvs(document, root);
136
137 //
138 // Clean Target
139 //
140 applyClean(document, root);
141
142 //
143 // Deep Clean Target
144 //
145 applyCleanall(document, root);
146
147 //
148 // User Extension pre build
149 //
150 applyUserExtensionsPreBuild(document, root);
151
152 //
153 // User Extension Post build
154 //
155 applyUserExtensionsPostBuild(document, root);
156
157 document.appendChild(rootComment);
158 document.appendChild(root);
159 //
160 // Prepare the DOM document for writing
161 //
162 Source source = new DOMSource(document);
163 //
164 // Prepare the output file
165 //
166 File file = new File(project.getProperty("PLATFORM_DIR") + File.separatorChar + platformName + "_build.xml");
167 //
168 // generate all directory path
169 //
170 (new File(file.getParent())).mkdirs();
171 Result result = new StreamResult(file);
172 //
173 // Write the DOM document to the file
174 //
175 Transformer xformer = TransformerFactory.newInstance().newTransformer();
176 xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
177 xformer.setOutputProperty(OutputKeys.INDENT, "yes");
178 xformer.transform(source, result);
179 } catch (Exception ex) {
180 throw new BuildException("Generation of the " + platformName + "_build.xml failed!\n" + ex.getMessage());
181 }
182 }
183
184 /**
185 1. Get All valid Fv Image Names in sequence
186 2. For each FV, get modules by sequences
187 3. Get other modules
188
189 @param document XML document
190 @param root Node
191 **/
192 private void applyModules(Document document, Node root) {
193 root.appendChild(document.createComment("Modules target"));
194 Element ele = document.createElement("target");
195 ele.setAttribute("name", "modules");
196
197 //
198 // Get all valid FV name
199 //
200 String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
201
202 //
203 // For each valid FV, get all modules in sequence
204 //
205 for (int i = 0; i < validFv.length; i++) {
206 if (fvs.containsKey(validFv[i])) {
207 Set<FpdModuleIdentification> set = fvs.get(validFv[i]);
208 Iterator<FpdModuleIdentification> iter = set.iterator();
209 while (iter.hasNext()) {
210 FpdModuleIdentification fpdModuleId = iter.next();
211 applySingleModule(document, ele, fpdModuleId);
212 }
213 }
214 }
215
216 //
217 // Get all other modules
218 //
219 Iterator<String> fvsNameIter = fvs.keySet().iterator();
220
221 while (fvsNameIter.hasNext()) {
222 String fvName = fvsNameIter.next();
223 if (!isContain(validFv, fvName)) {
224 Set<FpdModuleIdentification> set = fvs.get(fvName);
225 Iterator iter = set.iterator();
226 while (iter.hasNext()) {
227 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
228 applySingleModule(document, ele, fpdModuleId);
229 }
230 }
231 }
232
233 root.appendChild(ele);
234 }
235
236 private void applySingleModule(Document document, Node root, FpdModuleIdentification fpdModuleId) {
237 ModuleIdentification moduleId = fpdModuleId.getModule();
238 Element moduleEle = document.createElement("GenBuild");
239 moduleEle.setAttribute("type", "build");
240 //
241 // Inherit Properties.
242 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
243 //
244
245 //
246 // ARCH
247 //
248 Element property = document.createElement("property");
249 property.setAttribute("name", "ARCH");
250 property.setAttribute("value", fpdModuleId.getArch());
251 moduleEle.appendChild(property);
252
253 //
254 // MODULE_GUID
255 //
256 property = document.createElement("property");
257 property.setAttribute("name", "MODULE_GUID");
258 property.setAttribute("value", moduleId.getGuid());
259 moduleEle.appendChild(property);
260
261 //
262 // MODULE_VERSION
263 //
264 property = document.createElement("property");
265 property.setAttribute("name", "MODULE_VERSION");
266 property.setAttribute("value", moduleId.getVersion());
267 moduleEle.appendChild(property);
268
269 //
270 // PACKAGE_GUID
271 //
272 property = document.createElement("property");
273 property.setAttribute("name", "PACKAGE_GUID");
274 property.setAttribute("value", moduleId.getPackage().getGuid());
275 moduleEle.appendChild(property);
276
277 //
278 // PACKAGE_VERSION
279 //
280 property = document.createElement("property");
281 property.setAttribute("name", "PACKAGE_VERSION");
282 property.setAttribute("value", moduleId.getPackage().getVersion());
283 moduleEle.appendChild(property);
284
285 root.appendChild(moduleEle);
286 }
287
288 private boolean isContain(String[] list, String item) {
289 for (int i = 0; i < list.length; i++) {
290 if (list[i].equalsIgnoreCase(item)) {
291 return true;
292 }
293 }
294 return false;
295 }
296
297 private void applyFvs(Document document, Node root) {
298 //
299 // FVS Target
300 //
301 root.appendChild(document.createComment("FVs target"));
302 Element ele = document.createElement("target");
303 ele.setAttribute("name", "fvs");
304
305 //
306 // For every Target and ToolChain
307 //
308 String[] targetList = GlobalData.getToolChainInfo().getTargets();
309 for (int i = 0; i < targetList.length; i++){
310 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
311 for(int j = 0; j < toolchainList.length; j++){
312 String fvOutputDir = project.getProperty("BUILD_DIR") + File.separatorChar
313 + targetList[i] + File.separatorChar
314 + toolchainList[j] + File.separatorChar + "FV";
315 String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
316 for (int k = 0; k < validFv.length; k++) {
317 String inputFile = fvOutputDir + "" + File.separatorChar + validFv[k].toUpperCase() + ".inf";
318 Element fvEle = document.createElement("genfvimage");
319 fvEle.setAttribute("infFile", inputFile);
320 fvEle.setAttribute("outputDir", fvOutputDir);
321 ele.appendChild(fvEle);
322 }
323 }
324 }
325 root.appendChild(ele);
326 }
327
328 private void applyClean(Document document, Node root) {
329 //
330 // Clean Target
331 //
332 root.appendChild(document.createComment("Clean target"));
333 Element ele = document.createElement("target");
334 ele.setAttribute("name", "clean");
335
336 if (isUnified) {
337 Element cleanEle = document.createElement("delete");
338 cleanEle.setAttribute("includeemptydirs", "true");
339 Element filesetEle = document.createElement("fileset");
340 filesetEle.setAttribute("dir", project.getProperty("BUILD_DIR"));
341 filesetEle.setAttribute("includes", "**\\OUTPUT\\**");
342 cleanEle.appendChild(filesetEle);
343 ele.appendChild(cleanEle);
344 } else {
345 Set set = outfiles.keySet();
346 Iterator iter = set.iterator();
347 while (iter.hasNext()) {
348 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
349 ModuleIdentification moduleId = fpdModuleId.getModule();
350
351 Element ifEle = document.createElement("if");
352 Element availableEle = document.createElement("available");
353 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
354 + "build.xml");
355 ifEle.appendChild(availableEle);
356 Element elseEle = document.createElement("then");
357
358 Element moduleEle = document.createElement("ant");
359 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
360 + "build.xml");
361 moduleEle.setAttribute("target", "clean");
362 //
363 // Inherit Properties.
364 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
365 //
366
367 //
368 // ARCH
369 //
370 Element property = document.createElement("property");
371 property.setAttribute("name", "ARCH");
372 property.setAttribute("value", fpdModuleId.getArch());
373 moduleEle.appendChild(property);
374
375 //
376 // PACKAGE
377 //
378 property = document.createElement("property");
379 property.setAttribute("name", "PACKAGE");
380 property.setAttribute("value", moduleId.getPackage().getName());
381 moduleEle.appendChild(property);
382
383 //
384 // PACKAGE_GUID
385 //
386 property = document.createElement("property");
387 property.setAttribute("name", "PACKAGE_GUID");
388 property.setAttribute("value", moduleId.getPackage().getGuid());
389 moduleEle.appendChild(property);
390
391 //
392 // PACKAGE_VERSION
393 //
394 property = document.createElement("property");
395 property.setAttribute("name", "PACKAGE_VERSION");
396 property.setAttribute("value", moduleId.getPackage().getVersion());
397 moduleEle.appendChild(property);
398
399 //
400 // MODULE_DIR
401 //
402 property = document.createElement("property");
403 property.setAttribute("name", "MODULE_DIR");
404 property.setAttribute("value", moduleId.getMsaFile().getParent());
405 moduleEle.appendChild(property);
406 elseEle.appendChild(moduleEle);
407 ifEle.appendChild(elseEle);
408 ele.appendChild(ifEle);
409 }
410 }
411 root.appendChild(ele);
412 }
413
414 private void applyCleanall(Document document, Node root) {
415 //
416 // Deep Clean Target
417 //
418 root.appendChild(document.createComment("Target: cleanall"));
419 Element ele = document.createElement("target");
420 ele.setAttribute("name", "cleanall");
421
422 if (isUnified) {
423 String[] targetList = GlobalData.getToolChainInfo().getTargets();
424 for (int i = 0; i < targetList.length; ++i) {
425 Element cleanAllEle = document.createElement("delete");
426 cleanAllEle.setAttribute("dir", project.getProperty("BUILD_DIR") + File.separatorChar + targetList[i]);
427 ele.appendChild(cleanAllEle);
428 }
429 } else {
430 Set set = outfiles.keySet();
431 Iterator iter = set.iterator();
432 while (iter.hasNext()) {
433 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
434 ModuleIdentification moduleId = fpdModuleId.getModule();
435
436 Element ifEle = document.createElement("if");
437 Element availableEle = document.createElement("available");
438 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
439 + "build.xml");
440 ifEle.appendChild(availableEle);
441 Element elseEle = document.createElement("then");
442
443 Element moduleEle = document.createElement("ant");
444 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
445 + "build.xml");
446 moduleEle.setAttribute("target", "cleanall");
447 //
448 // Inherit Properties.
449 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
450 //
451
452 //
453 // ARCH
454 //
455 Element property = document.createElement("property");
456 property.setAttribute("name", "ARCH");
457 property.setAttribute("value", fpdModuleId.getArch());
458 moduleEle.appendChild(property);
459
460 //
461 // PACKAGE
462 //
463 property = document.createElement("property");
464 property.setAttribute("name", "PACKAGE");
465 property.setAttribute("value", moduleId.getPackage().getName());
466 moduleEle.appendChild(property);
467
468 //
469 // PACKAGE_GUID
470 //
471 property = document.createElement("property");
472 property.setAttribute("name", "PACKAGE_GUID");
473 property.setAttribute("value", moduleId.getPackage().getGuid());
474 moduleEle.appendChild(property);
475
476 //
477 // PACKAGE_VERSION
478 //
479 property = document.createElement("property");
480 property.setAttribute("name", "PACKAGE_VERSION");
481 property.setAttribute("value", moduleId.getPackage().getVersion());
482 moduleEle.appendChild(property);
483
484 //
485 // MODULE_DIR
486 //
487 property = document.createElement("property");
488 property.setAttribute("name", "MODULE_DIR");
489 property.setAttribute("value", moduleId.getMsaFile().getParent());
490 moduleEle.appendChild(property);
491 elseEle.appendChild(moduleEle);
492 ifEle.appendChild(elseEle);
493 ele.appendChild(ifEle);
494 }
495 }
496 root.appendChild(ele);
497 }
498
499 private void applyUserExtensionsPreBuild(Document document, Node root) {
500 //
501 // User Extensions
502 //
503 root.appendChild(document.createComment("Pre-Build Processing"));
504 Element ele = document.createElement("target");
505 ele.setAttribute("name", "prebuild");
506
507 Node node = SurfaceAreaQuery.getFpdUserExtensionPreBuild();
508 if (node != null) {
509 //
510 // For every Target and ToolChain
511 //
512 String[] targetList = GlobalData.getToolChainInfo().getTargets();
513 for (int i = 0; i < targetList.length; i++){
514 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
515 for(int j = 0; j < toolchainList.length; j++){
516 //
517 // Prepare FV_DIR
518 //
519 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
520 + targetList[i] + File.separatorChar
521 + toolchainList[j];
522 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
523 Element fvEle = document.createElement("var");
524 fvEle.setAttribute("name", "FV_DIR");
525 fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));
526 ele.appendChild(fvEle);
527
528 NodeList childNodes = node.getChildNodes();
529 for (int k = 0; k < childNodes.getLength(); k++) {
530 Node childItem = childNodes.item(k);
531 if (childItem.getNodeType() == Node.ELEMENT_NODE) {
532 ele.appendChild(recursiveNode(childItem, document));
533 }
534 }
535
536 }
537 }
538 }
539
540 root.appendChild(ele);
541 }
542
543 private void applyUserExtensionsPostBuild(Document document, Node root) {
544 //
545 // User Extensions
546 //
547 root.appendChild(document.createComment("Post-Build Processing"));
548 Element ele = document.createElement("target");
549 ele.setAttribute("name", "postbuild");
550
551 Node node = SurfaceAreaQuery.getFpdUserExtensionPostBuild();
552 if (node != null) {
553 //
554 // For every Target and ToolChain
555 //
556 String[] targetList = GlobalData.getToolChainInfo().getTargets();
557 for (int i = 0; i < targetList.length; i++){
558 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
559 for(int j = 0; j < toolchainList.length; j++){
560 //
561 // Prepare FV_DIR
562 //
563 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
564 + targetList[i] + File.separatorChar
565 + toolchainList[j];
566 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
567 Element fvEle = document.createElement("var");
568 fvEle.setAttribute("name", "FV_DIR");
569 fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));
570 ele.appendChild(fvEle);
571
572 NodeList childNodes = node.getChildNodes();
573 for (int k = 0; k < childNodes.getLength(); k++) {
574 Node childItem = childNodes.item(k);
575 if (childItem.getNodeType() == Node.ELEMENT_NODE) {
576 ele.appendChild(recursiveNode(childItem, document));
577 }
578 }
579
580 }
581 }
582 }
583
584 root.appendChild(ele);
585 }
586
587 private Element recursiveNode(Node node, Document document) {
588 Element root = document.createElement(node.getNodeName());
589 NamedNodeMap attr = node.getAttributes();
590 for (int i = 0; i < attr.getLength(); i++) {
591 Node attrItem = attr.item(i);
592 root.setAttribute(attrItem.getNodeName(), attrItem.getNodeValue());
593 }
594 NodeList childNodes = node.getChildNodes();
595 for (int i = 0; i < childNodes.getLength(); i++) {
596 Node childItem = childNodes.item(i);
597 if (childItem.getNodeType() == Node.ELEMENT_NODE) {
598 root.appendChild(recursiveNode(childItem, document));
599 }
600 else if (childItem.getNodeType() == Node.TEXT_NODE){
601 if ( ! childItem.getNodeValue().trim().equalsIgnoreCase("")) {
602 root.setTextContent(childItem.getNodeValue());
603 }
604 }
605 }
606 return root;
607 }
608 }