]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java
65872eb629b00f8d6178a478d423986d2da79e87
[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("property");
113 ele.setAttribute("environment", "env");
114 root.appendChild(ele);
115
116 Set<String> sequenceKeys = sequences.keySet();
117 Iterator sequenceIter = sequenceKeys.iterator();
118 String dependsStr = "";
119 while (sequenceIter.hasNext()) {
120 String num = (String)sequenceIter.next();
121 if (dependsStr.length() > 0) {
122 dependsStr += " , ";
123 }
124 dependsStr += "modules" + num + ", fvs" + num;
125 }
126
127 //
128 // Default Target
129 //
130 root.appendChild(document.createComment("Default target"));
131 ele = document.createElement("target");
132 ele.setAttribute("name", "all");
133 ele.setAttribute("depends", dependsStr + ", userextensions");
134 root.appendChild(ele);
135
136 //
137 // Modules and Fvs Target
138 //
139 sequenceIter = sequenceKeys.iterator();
140 while (sequenceIter.hasNext()) {
141 String num = (String)sequenceIter.next();
142 applyModules(document, root, num);
143 applyFvs(document, root, num);
144 }
145
146 //
147 // Clean Target
148 //
149 applyClean(document, root);
150
151 //
152 // Deep Clean Target
153 //
154 applyCleanall(document, root);
155
156 //
157 // User Extension
158 //
159 applyUserExtensions(document, root);
160
161 document.appendChild(rootComment);
162 document.appendChild(root);
163 //
164 // Prepare the DOM document for writing
165 //
166 Source source = new DOMSource(document);
167 //
168 // Prepare the output file
169 //
170 File file = new File(project.getProperty("PLATFORM_DIR") + File.separatorChar + platformName + "_build.xml");
171 //
172 // generate all directory path
173 //
174 (new File(file.getParent())).mkdirs();
175 Result result = new StreamResult(file);
176 //
177 // Write the DOM document to the file
178 //
179 Transformer xformer = TransformerFactory.newInstance().newTransformer();
180 xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
181 xformer.setOutputProperty(OutputKeys.INDENT, "yes");
182 xformer.transform(source, result);
183 } catch (Exception ex) {
184 ex.printStackTrace();
185 throw new BuildException("Generate " + platformName + "_build.xml failed. \n" + ex.getMessage());
186 }
187 }
188
189 private void applyModules(Document document, Node root, String num) {
190 root.appendChild(document.createComment("Modules target"));
191 Element ele = document.createElement("target");
192 ele.setAttribute("name", "modules" + num);
193
194 Set<String> fvNameSet = sequences.get(num);
195
196 Iterator fvNameIter = fvNameSet.iterator();
197 while (fvNameIter.hasNext()) {
198 String fvName = (String)fvNameIter.next();
199 Set<FpdModuleIdentification> set = fvs.get(fvName);
200 Iterator iter = set.iterator();
201 while (iter.hasNext()) {
202 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
203 ModuleIdentification moduleId = fpdModuleId.getModule();
204 Element moduleEle = document.createElement("GenBuild");
205 moduleEle.setAttribute("type", "build");
206 //
207 // Inherit Properties.
208 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
209 //
210
211 //
212 // ARCH
213 //
214 Element property = document.createElement("property");
215 property.setAttribute("name", "ARCH");
216 property.setAttribute("value", fpdModuleId.getArch());
217 moduleEle.appendChild(property);
218
219 //
220 // MODULE_GUID
221 //
222 property = document.createElement("property");
223 property.setAttribute("name", "MODULE_GUID");
224 property.setAttribute("value", moduleId.getGuid());
225 moduleEle.appendChild(property);
226
227 //
228 // MODULE_VERSION
229 //
230 property = document.createElement("property");
231 property.setAttribute("name", "MODULE_VERSION");
232 property.setAttribute("value", moduleId.getVersion());
233 moduleEle.appendChild(property);
234
235 //
236 // PACKAGE_GUID
237 //
238 property = document.createElement("property");
239 property.setAttribute("name", "PACKAGE_GUID");
240 property.setAttribute("value", moduleId.getPackage().getGuid());
241 moduleEle.appendChild(property);
242
243 //
244 // PACKAGE_VERSION
245 //
246 property = document.createElement("property");
247 property.setAttribute("name", "PACKAGE_VERSION");
248 property.setAttribute("value", moduleId.getPackage().getVersion());
249 moduleEle.appendChild(property);
250
251 ele.appendChild(moduleEle);
252 }
253 }
254 root.appendChild(ele);
255 }
256
257 private void applyFvs(Document document, Node root, String num) {
258 Set<String> fvNameSet = sequences.get(num);
259 //
260 // FVS Target
261 //
262 root.appendChild(document.createComment("FVs target"));
263 Element ele = document.createElement("target");
264 ele.setAttribute("name", "fvs" + num);
265
266 //
267 // For every Target and ToolChain
268 //
269 String[] targetList = GlobalData.getToolChainInfo().getTargets();
270 for (int i = 0; i < targetList.length; i++){
271 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
272 for(int j = 0; j < toolchainList.length; j++){
273 String fvOutputDir = project.getProperty("BUILD_DIR") + File.separatorChar
274 + targetList[i] + File.separatorChar
275 + toolchainList[i] + File.separatorChar + "FV";
276 String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
277 for (int k = 0; k < validFv.length; k++) {
278 if (fvNameSet.contains(validFv[k]) || ! isListInSequence(validFv[k])) {
279 String inputFile = fvOutputDir + "" + File.separatorChar + validFv[k].toUpperCase() + ".inf";
280 Element fvEle = document.createElement("genfvimage");
281 fvEle.setAttribute("infFile", inputFile);
282 fvEle.setAttribute("outputDir", fvOutputDir);
283 ele.appendChild(fvEle);
284 }
285 }
286 }
287 }
288 root.appendChild(ele);
289 }
290
291 private void applyClean(Document document, Node root) {
292 //
293 // Clean Target
294 //
295 root.appendChild(document.createComment("Clean target"));
296 Element ele = document.createElement("target");
297 ele.setAttribute("name", "clean");
298
299 if (isUnified) {
300 Element cleanEle = document.createElement("delete");
301 cleanEle.setAttribute("includeemptydirs", "true");
302 Element filesetEle = document.createElement("fileset");
303 filesetEle.setAttribute("dir", project.getProperty("BUILD_DIR"));
304 filesetEle.setAttribute("includes", "**\\OUTPUT\\**");
305 cleanEle.appendChild(filesetEle);
306 ele.appendChild(cleanEle);
307 } else {
308 Set set = outfiles.keySet();
309 Iterator iter = set.iterator();
310 while (iter.hasNext()) {
311 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
312 ModuleIdentification moduleId = fpdModuleId.getModule();
313
314 Element ifEle = document.createElement("if");
315 Element availableEle = document.createElement("available");
316 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
317 + "build.xml");
318 ifEle.appendChild(availableEle);
319 Element elseEle = document.createElement("then");
320
321 Element moduleEle = document.createElement("ant");
322 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
323 + "build.xml");
324 moduleEle.setAttribute("target", "clean");
325 //
326 // Inherit Properties.
327 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
328 //
329
330 //
331 // ARCH
332 //
333 Element property = document.createElement("property");
334 property.setAttribute("name", "ARCH");
335 property.setAttribute("value", fpdModuleId.getArch());
336 moduleEle.appendChild(property);
337
338 //
339 // PACKAGE
340 //
341 property = document.createElement("property");
342 property.setAttribute("name", "PACKAGE");
343 property.setAttribute("value", moduleId.getPackage().getName());
344 moduleEle.appendChild(property);
345
346 //
347 // PACKAGE_GUID
348 //
349 property = document.createElement("property");
350 property.setAttribute("name", "PACKAGE_GUID");
351 property.setAttribute("value", moduleId.getPackage().getGuid());
352 moduleEle.appendChild(property);
353
354 //
355 // PACKAGE_VERSION
356 //
357 property = document.createElement("property");
358 property.setAttribute("name", "PACKAGE_VERSION");
359 property.setAttribute("value", moduleId.getPackage().getVersion());
360 moduleEle.appendChild(property);
361
362 //
363 // MODULE_DIR
364 //
365 property = document.createElement("property");
366 property.setAttribute("name", "MODULE_DIR");
367 property.setAttribute("value", moduleId.getMsaFile().getParent());
368 moduleEle.appendChild(property);
369 elseEle.appendChild(moduleEle);
370 ifEle.appendChild(elseEle);
371 ele.appendChild(ifEle);
372 }
373 }
374 root.appendChild(ele);
375 }
376
377 private void applyCleanall(Document document, Node root) {
378 //
379 // Deep Clean Target
380 //
381 root.appendChild(document.createComment("Clean All target"));
382 Element ele = document.createElement("target");
383 ele.setAttribute("name", "cleanall");
384
385 if (isUnified) {
386 String[] targetList = GlobalData.getToolChainInfo().getTargets();
387 for (int i = 0; i < targetList.length; ++i) {
388 Element cleanAllEle = document.createElement("delete");
389 cleanAllEle.setAttribute("dir", project.getProperty("BUILD_DIR") + File.separatorChar + targetList[i]);
390 ele.appendChild(cleanAllEle);
391 }
392 } else {
393 Set set = outfiles.keySet();
394 Iterator iter = set.iterator();
395 while (iter.hasNext()) {
396 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
397 ModuleIdentification moduleId = fpdModuleId.getModule();
398
399 Element ifEle = document.createElement("if");
400 Element availableEle = document.createElement("available");
401 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
402 + "build.xml");
403 ifEle.appendChild(availableEle);
404 Element elseEle = document.createElement("then");
405
406 Element moduleEle = document.createElement("ant");
407 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
408 + "build.xml");
409 moduleEle.setAttribute("target", "cleanall");
410 //
411 // Inherit Properties.
412 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
413 //
414
415 //
416 // ARCH
417 //
418 Element property = document.createElement("property");
419 property.setAttribute("name", "ARCH");
420 property.setAttribute("value", fpdModuleId.getArch());
421 moduleEle.appendChild(property);
422
423 //
424 // PACKAGE
425 //
426 property = document.createElement("property");
427 property.setAttribute("name", "PACKAGE");
428 property.setAttribute("value", moduleId.getPackage().getName());
429 moduleEle.appendChild(property);
430
431 //
432 // PACKAGE_GUID
433 //
434 property = document.createElement("property");
435 property.setAttribute("name", "PACKAGE_GUID");
436 property.setAttribute("value", moduleId.getPackage().getGuid());
437 moduleEle.appendChild(property);
438
439 //
440 // PACKAGE_VERSION
441 //
442 property = document.createElement("property");
443 property.setAttribute("name", "PACKAGE_VERSION");
444 property.setAttribute("value", moduleId.getPackage().getVersion());
445 moduleEle.appendChild(property);
446
447 //
448 // MODULE_DIR
449 //
450 property = document.createElement("property");
451 property.setAttribute("name", "MODULE_DIR");
452 property.setAttribute("value", moduleId.getMsaFile().getParent());
453 moduleEle.appendChild(property);
454 elseEle.appendChild(moduleEle);
455 ifEle.appendChild(elseEle);
456 ele.appendChild(ifEle);
457 }
458 }
459 root.appendChild(ele);
460 }
461
462 private void applyUserExtensions(Document document, Node root) {
463 //
464 // User Extensions
465 //
466 root.appendChild(document.createComment("User Extensions"));
467 Element ele = document.createElement("target");
468 ele.setAttribute("name", "userextensions");
469
470 Node node = SurfaceAreaQuery.getFpdUserExtension();
471 if (node != null) {
472 //
473 // For every Target and ToolChain
474 //
475 String[] targetList = GlobalData.getToolChainInfo().getTargets();
476 for (int i = 0; i < targetList.length; i++){
477 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
478 for(int j = 0; j < toolchainList.length; j++){
479 //
480 // Prepare FV_DIR
481 //
482 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
483 + targetList[i] + File.separatorChar
484 + toolchainList[j];
485 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
486 Element fvEle = document.createElement("var");
487 fvEle.setAttribute("name", "FV_DIR");
488 fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));
489 ele.appendChild(fvEle);
490
491 NodeList childNodes = node.getChildNodes();
492 for (int k = 0; k < childNodes.getLength(); k++) {
493 Node childItem = childNodes.item(k);
494 if (childItem.getNodeType() == Node.ELEMENT_NODE) {
495 ele.appendChild(recursiveNode(childItem, document));
496 }
497 }
498
499 }
500 }
501 }
502
503 root.appendChild(ele);
504 }
505
506 private Element recursiveNode(Node node, Document document) {
507 Element root = document.createElement(node.getNodeName());
508 NamedNodeMap attr = node.getAttributes();
509 for (int i = 0; i < attr.getLength(); i++) {
510 Node attrItem = attr.item(i);
511 root.setAttribute(attrItem.getNodeName(), attrItem.getNodeValue());
512 }
513 NodeList childNodes = node.getChildNodes();
514 for (int i = 0; i < childNodes.getLength(); i++) {
515 Node childItem = childNodes.item(i);
516 if (childItem.getNodeType() == Node.ELEMENT_NODE) {
517 root.appendChild(recursiveNode(childItem, document));
518 }
519 else if (childItem.getNodeType() == Node.TEXT_NODE){
520 if ( ! childItem.getNodeValue().trim().equalsIgnoreCase("")) {
521 root.setTextContent(childItem.getNodeValue());
522 }
523 }
524 }
525 return root;
526 }
527
528 private boolean isListInSequence(String fvName) {
529 Set<String> numbers = sequences.keySet();
530 Iterator<String> iter = numbers.iterator();
531 while (iter.hasNext()) {
532 Set<String> fvNameSet = sequences.get(iter.next());
533 if (fvNameSet.contains(fvName)) {
534 return true;
535 }
536 }
537 return false;
538 }
539 }