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