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