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