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