]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java
added the support for new schema and old schema at the same time
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / fpd / FpdParserTask.java
1 /** @file
2 This file is ANT task FpdParserTask.
3
4 FpdParserTask is used to parse FPD (Framework Platform Description) and generate
5 build.out.xml. It is for Package or Platform build use.
6
7 Copyright (c) 2006, Intel Corporation
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
12
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 **/
16 package org.tianocore.build.fpd;
17
18 import java.io.BufferedWriter;
19 import java.io.File;
20 import java.io.FileWriter;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.LinkedHashMap;
24 import java.util.LinkedHashSet;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.Vector;
28
29 import javax.xml.parsers.DocumentBuilder;
30 import javax.xml.parsers.DocumentBuilderFactory;
31 import javax.xml.transform.OutputKeys;
32 import javax.xml.transform.Result;
33 import javax.xml.transform.Source;
34 import javax.xml.transform.Transformer;
35 import javax.xml.transform.TransformerFactory;
36 import javax.xml.transform.dom.DOMSource;
37 import javax.xml.transform.stream.StreamResult;
38
39 import org.apache.tools.ant.BuildException;
40 import org.apache.tools.ant.Task;
41 import org.apache.tools.ant.taskdefs.Property;
42 import org.apache.xmlbeans.XmlObject;
43 import org.w3c.dom.Comment;
44 import org.w3c.dom.Document;
45 import org.w3c.dom.Element;
46
47 import org.tianocore.build.global.GlobalData;
48 import org.tianocore.build.global.OutputManager;
49 import org.tianocore.build.global.OverrideProcess;
50 import org.tianocore.build.global.SurfaceAreaQuery;
51 import org.tianocore.build.pcd.action.CollectPCDAction;
52 import org.tianocore.build.pcd.action.ActionMessage;
53 import org.tianocore.BuildOptionsDocument;
54 import org.tianocore.FrameworkPlatformDescriptionDocument;
55 import org.tianocore.ModuleSADocument;
56
57
58 /**
59 <code>FpdParserTask</code> is an ANT task. The main function is parsing FPD
60 XML file and generating its ANT build script for Platform or Package.
61
62 <p>The usage is (take NT32 Platform for example):</p>
63
64 <pre>
65 &lt;FPDParser fpdfilename="Build\Nt32.fpd" /&gt;
66 </pre>
67
68 <p>The task will initialize all information through parsing Framework Database,
69 SPD, Tool chain configuration files. </p>
70
71 @since GenBuild 1.0
72 **/
73 public class FpdParserTask extends Task {
74
75 ///
76 /// FV dir: ${PLATFORM_DIR}/Build/FV
77 ///
78 public static final String FV_OUTPUT_DIR = "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "FV";
79
80 private File fpdFilename;
81
82 private File guiddatabase;
83
84 ///
85 /// Keep platform buildoption information
86 ///
87 public static XmlObject platformBuildOptions = null;
88
89 ///
90 /// Mapping from modules identification to out put file name
91 ///
92 private Map<FpdModuleIdentification, String> outfiles = new LinkedHashMap<FpdModuleIdentification, String>();
93
94 ///
95 /// Mapping from FV name to its modules
96 ///
97 private Map<String, Set<FpdModuleIdentification> > fvs = new HashMap<String, Set<FpdModuleIdentification> >();
98
99 ///
100 /// Mapping from sequence number to its modules
101 ///
102 private Map<String, Set<FpdModuleIdentification> > sequences = new HashMap<String, Set<FpdModuleIdentification> >();
103
104 ///
105 /// FpdParserTask can specify some ANT properties.
106 ///
107 private Vector<Property> properties = new Vector<Property>();
108
109 private String info = "====================================================================\n"
110 + "DO NOT EDIT \n"
111 + "File auto-generated by build utility\n"
112 + "\n"
113 + "Abstract:\n"
114 + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"
115 + "=====================================================================";
116
117 /**
118 Public construct method. It is necessary for ANT task.
119 **/
120 public FpdParserTask () {
121 }
122
123 /**
124 ANT task's entry method. The main steps is described as following:
125
126 <ul>
127 <li>Initialize global information (Framework DB, SPD files and all MSA files
128 listed in SPD). This step will execute only once in whole build process;</li>
129 <li>Parse specified FPD file; </li>
130 <li>Generate FV.inf files; </li>
131 <li>Generate build.out.xml file for Flatform or Package build; </li>
132 <li>Collect PCD information. </li>
133 </ul>
134
135 @throws BuildException
136 Surface area is not valid.
137 **/
138 public void execute() throws BuildException {
139 OutputManager.update(getProject());
140 //
141 // Parse DB and SPDs files. Initialize Global Data
142 //
143 GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db", getProject()
144 .getProperty("WORKSPACE_DIR"));
145 //
146 // Parse FPD file
147 //
148 parseFpdFile();
149 //
150 // Gen Fv.inf files
151 //
152 genFvInfFiles();
153 //
154 // Gen build.xml
155 //
156 genBuildFile();
157 //
158 // Collect PCD information
159 //
160 collectPCDInformation ();
161 }
162
163 /**
164 Generate Fv.inf files. The Fv.inf file is composed with four
165 parts: Options, Attributes, Components and Files. The Fv.inf files
166 will be under ${PLATFOMR_DIR}\Build\Fv.
167
168 @throws BuildException
169 File write FV.inf files error.
170 **/
171 private void genFvInfFiles() throws BuildException{
172 String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
173 for (int i = 0; i < validFv.length; i++) {
174 getProject().setProperty("FV_FILENAME", validFv[i].toUpperCase());
175 //
176 // Get all global variables from FPD and set them to properties
177 //
178 String[][] globalVariables = SurfaceAreaQuery
179 .getFpdGlobalVariable();
180 for (int j = 0; j < globalVariables.length; j++) {
181 getProject().setProperty(globalVariables[j][0],
182 globalVariables[j][1]);
183 }
184
185 File fvFile = new File(getProject().replaceProperties(
186 FV_OUTPUT_DIR + File.separatorChar + validFv[i].toUpperCase()
187 + ".inf"));
188 fvFile.getParentFile().mkdirs();
189
190 try {
191 FileWriter fw = new FileWriter(fvFile);
192 BufferedWriter bw = new BufferedWriter(fw);
193 //
194 // Options
195 //
196 String[][] options = SurfaceAreaQuery.getFpdOptions(validFv[i]);
197 if (options.length > 0) {
198 bw.write("[options]");
199 bw.newLine();
200 for (int j = 0; j < options.length; j++) {
201 StringBuffer str = new StringBuffer(100);
202 str.append(options[j][0]);
203 while (str.length() < 40) {
204 str.append(' ');
205 }
206 str.append("= ");
207 str.append(options[j][1]);
208 bw.write(getProject().replaceProperties(str.toString()));
209 bw.newLine();
210 }
211 bw.newLine();
212 }
213 //
214 // Attributes;
215 //
216 String[][] attributes = SurfaceAreaQuery
217 .getFpdAttributes(validFv[i]);
218 if (attributes.length > 0) {
219 bw.write("[attributes]");
220 bw.newLine();
221 for (int j = 0; j < attributes.length; j++) {
222 StringBuffer str = new StringBuffer(100);
223 str.append(attributes[j][0]);
224 while (str.length() < 40) {
225 str.append(' ');
226 }
227 str.append("= ");
228 str.append(attributes[j][1]);
229 bw
230 .write(getProject().replaceProperties(
231 str.toString()));
232 bw.newLine();
233 }
234 bw.newLine();
235 }
236 //
237 // Components
238 //
239 String[][] components = SurfaceAreaQuery
240 .getFpdComponents(validFv[i]);
241 if (components.length > 0) {
242 bw.write("[components]");
243 bw.newLine();
244 for (int j = 0; j < components.length; j++) {
245 StringBuffer str = new StringBuffer(100);
246 str.append(components[j][0]);
247 while (str.length() < 40) {
248 str.append(' ');
249 }
250 str.append("= ");
251 str.append(components[j][1]);
252 bw
253 .write(getProject().replaceProperties(
254 str.toString()));
255 bw.newLine();
256 }
257 bw.newLine();
258 }
259 //
260 // Files
261 //
262 Set<FpdModuleIdentification> filesSet = fvs.get(validFv[i].toUpperCase());
263 if (filesSet != null) {
264 FpdModuleIdentification[] files = filesSet.toArray(new FpdModuleIdentification[filesSet
265 .size()]);
266 bw.write("[files]");
267 bw.newLine();
268 for (int j = 0; j < files.length; j++) {
269 String str = outfiles.get(files[j]);
270 bw.write(getProject().replaceProperties(
271 "EFI_FILE_NAME = " + str));
272 bw.newLine();
273 }
274 }
275 bw.flush();
276 bw.close();
277 fw.close();
278 } catch (Exception e) {
279 throw new BuildException("Generate Fv.inf file failed. \n" + e.getMessage());
280 }
281 }
282 }
283
284 /**
285 Parse FPD file.
286
287 @throws BuildException
288 FPD file is not valid.
289 **/
290 private void parseFpdFile() throws BuildException {
291 try {
292 FrameworkPlatformDescriptionDocument doc = (FrameworkPlatformDescriptionDocument) XmlObject.Factory
293 .parse(fpdFilename);
294 if ( ! doc.validate() ){
295 throw new BuildException("FPD file is invalid.");
296 }
297 platformBuildOptions = doc.getFrameworkPlatformDescription()
298 .getBuildOptions();
299 HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();
300 map.put("FrameworkPlatformDescription", doc);
301 SurfaceAreaQuery.setDoc(map);
302 //
303 // Parse all list modules SA
304 //
305 parseModuleSAFiles();
306 SurfaceAreaQuery.setDoc(map);
307 } catch (Exception e) {
308 throw new BuildException("Load FPD file [" + fpdFilename.getPath()
309 + "] error. \n" + e.getMessage());
310 }
311 }
312
313 /**
314 Parse all modules listed in FPD file.
315 **/
316 private void parseModuleSAFiles() {
317 ModuleSADocument.ModuleSA[] moduleSAs = SurfaceAreaQuery
318 .getFpdModules();
319 //
320 // For every Module lists in FPD file.
321 //
322 for (int i = 0; i < moduleSAs.length; i++) {
323 String defaultFv = "NULL";
324 String defaultArch = "IA32";
325 String baseName = moduleSAs[i].getModuleName();
326 if (baseName == null) {
327 System.out.println("Warning: Module Name is not specified.");
328 continue;
329 }
330 String fvBinding = moduleSAs[i].getFvBinding();
331 //
332 // If the module do not specify any FvBinding, use the default value.
333 // Else update the default FvBinding value to this value.
334 //
335 if (fvBinding == null) {
336 fvBinding = defaultFv;
337 }
338 else {
339 defaultFv = fvBinding;
340 }
341 String arch;
342 //
343 // If the module do not specify any Arch, use the default value.
344 // Else update the default Arch value to this value.
345 //
346 if (moduleSAs[i].getArch() == null ){
347 arch = defaultArch;
348 }
349 else {
350 arch = moduleSAs[i].getArch().toString();
351 defaultArch = arch;
352 }
353 Map<String, XmlObject> msaMap = GlobalData.getNativeMsa(baseName);
354 Map<String, XmlObject> mbdMap = GlobalData.getNativeMbd(baseName);
355 Map<String, XmlObject> fpdMap = new HashMap<String, XmlObject>();
356 Map<String, XmlObject> map = new HashMap<String, XmlObject>();
357 //
358 // Whether the Module SA has parsed before or not
359 //
360 if (!GlobalData.isModuleParsed(baseName)) {
361 OverrideProcess op = new OverrideProcess();
362 //
363 // using overriding rules
364 // Here we can also put platform Build override
365 //
366 map = op.override(mbdMap, msaMap);
367 fpdMap = getPlatformOverrideInfo(moduleSAs[i]);
368 XmlObject buildOption = (XmlObject)fpdMap.get("BuildOptions");
369 buildOption = (XmlObject)fpdMap.get("PackageDependencies");
370 buildOption = (XmlObject)fpdMap.get("BuildOptions");
371 buildOption = op.override(buildOption, platformBuildOptions);
372 fpdMap.put("BuildOptions", ((BuildOptionsDocument)buildOption).getBuildOptions());
373 Map<String, XmlObject> overrideMap = op.override(fpdMap, OverrideProcess.deal(map));
374 GlobalData.registerModule(baseName, overrideMap);
375 } else {
376 map = GlobalData.getDoc(baseName);
377 }
378 SurfaceAreaQuery.setDoc(map);
379 String guid = SurfaceAreaQuery.getModuleGuid();
380 String componentType = SurfaceAreaQuery.getComponentType();
381 FpdModuleIdentification moduleId = new FpdModuleIdentification(baseName, guid, arch);
382 updateFvs(fvBinding, moduleId);
383 outfiles.put(moduleId, "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar
384 + "${TARGET}" + File.separatorChar + arch
385 + File.separatorChar + guid + "-" + baseName
386 + getSuffix(componentType));
387 }
388 }
389
390 /**
391 Add the current module to corresponding FV.
392
393 @param fvName current FV name
394 @param moduleName current module identification
395 **/
396 private void updateFvs(String fvName, FpdModuleIdentification moduleName) {
397 String upcaseFvName = fvName.toUpperCase();
398 if (fvs.containsKey(upcaseFvName)) {
399 Set<FpdModuleIdentification> set = fvs.get(upcaseFvName);
400 set.add(moduleName);
401 } else {
402 Set<FpdModuleIdentification> set = new LinkedHashSet<FpdModuleIdentification>();
403 set.add(moduleName);
404 fvs.put(upcaseFvName, set);
405 }
406 }
407
408 /**
409 Get the suffix based on component type. Current relationship are listed:
410
411 <pre>
412 <b>ComponentType</b> <b>Suffix</b>
413 APPLICATION .APP
414 SEC .SEC
415 PEI_CORE .PEI
416 PE32_PEIM .PEI
417 RELOCATABLE_PEIM .PEI
418 PIC_PEIM .PEI
419 COMBINED_PEIM_DRIVER .PEI
420 TE_PEIM .PEI
421 LOGO .FFS
422 others .DXE
423 </pre>
424
425 @param componentType component type
426 @return
427 @throws BuildException
428 If component type is null
429 **/
430 public static String getSuffix(String componentType) throws BuildException{
431 if (componentType == null) {
432 throw new BuildException("Component type is not specified.");
433 }
434 String str = ".DXE";
435 if (componentType.equalsIgnoreCase("APPLICATION")) {
436 str = ".APP";
437 } else if (componentType.equalsIgnoreCase("SEC")) {
438 str = ".SEC";
439 } else if (componentType.equalsIgnoreCase("PEI_CORE")) {
440 str = ".PEI";
441 } else if (componentType.equalsIgnoreCase("PE32_PEIM")) {
442 str = ".PEI";
443 } else if (componentType.equalsIgnoreCase("RELOCATABLE_PEIM")) {
444 str = ".PEI";
445 } else if (componentType.equalsIgnoreCase("PIC_PEIM")) {
446 str = ".PEI";
447 } else if (componentType.equalsIgnoreCase("COMBINED_PEIM_DRIVER")) {
448 str = ".PEI";
449 } else if (componentType.equalsIgnoreCase("TE_PEIM")) {
450 str = ".PEI";
451 } else if (componentType.equalsIgnoreCase("LOGO")) {
452 str = ".FFS";
453 }
454 return str;
455 }
456
457 /**
458 Parse module surface are info described in FPD file and put them into map.
459
460 @param sa module surface area info descibed in FPD file
461 @return map list with top level elements
462 **/
463 private Map<String, XmlObject> getPlatformOverrideInfo(
464 ModuleSADocument.ModuleSA sa) {
465 Map<String, XmlObject> map = new HashMap<String, XmlObject>();
466 map.put("SourceFiles", sa.getSourceFiles());
467 map.put("Includes", sa.getIncludes());
468 map.put("PackageDependencies", null);
469 map.put("Libraries", sa.getLibraries());
470 map.put("Protocols", sa.getProtocols());
471 map.put("Events", sa.getEvents());
472 map.put("Hobs", sa.getHobs());
473 map.put("PPIs", sa.getPPIs());
474 map.put("Variables", sa.getVariables());
475 map.put("BootModes", sa.getBootModes());
476 map.put("SystemTables", sa.getSystemTables());
477 map.put("DataHubs", sa.getDataHubs());
478 map.put("Formsets", sa.getFormsets());
479 map.put("Guids", sa.getGuids());
480 map.put("Externs", sa.getExterns());
481 map.put("BuildOptions", sa.getBuildOptions());//platformBuildOptions);
482 return map;
483 }
484
485 /**
486 Generate build.out.xml file.
487
488 @throws BuildException
489 build.out.xml XML document create error
490 **/
491 private void genBuildFile() throws BuildException {
492 DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
493 try {
494 DocumentBuilder dombuilder = domfac.newDocumentBuilder();
495 Document document = dombuilder.newDocument();
496 Comment rootComment = document.createComment(info);
497 //
498 // create root element and its attributes
499 //
500 Element root = document.createElement("project");
501 root.setAttribute("name", getProject().getProperty("PLATFORM"));
502 root.setAttribute("default", "main");
503 root.setAttribute("basedir", ".");
504 //
505 // element for External ANT tasks
506 //
507 root.appendChild(document.createComment("Apply external ANT tasks"));
508 Element ele = document.createElement("taskdef");
509 ele.setAttribute("resource", "GenBuild.tasks");
510 root.appendChild(ele);
511
512 ele = document.createElement("taskdef");
513 ele.setAttribute("resource", "frameworktasks.tasks");
514 root.appendChild(ele);
515
516 ele = document.createElement("property");
517 ele.setAttribute("environment", "env");
518 root.appendChild(ele);
519 //
520 // Default Target
521 //
522 root.appendChild(document.createComment("Default target"));
523 ele = document.createElement("target");
524 ele.setAttribute("name", "main");
525 ele.setAttribute("depends", "modules, fvs");
526 root.appendChild(ele);
527 //
528 // Modules Target
529 //
530 root.appendChild(document.createComment("Modules target"));
531 ele = document.createElement("target");
532 ele.setAttribute("name", "modules");
533
534 Set set = outfiles.keySet();
535 Iterator iter = set.iterator();
536 while (iter.hasNext()) {
537 FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
538 String baseName = moduleId.getBaseName();
539 Element moduleEle = document.createElement("ant");
540 moduleEle.setAttribute("antfile", GlobalData
541 .getModulePath(baseName)
542 + File.separatorChar + "build.xml");
543 moduleEle.setAttribute("target", baseName);
544 //
545 // ARCH
546 //
547 Element property = document.createElement("property");
548 property.setAttribute("name", "ARCH");
549 property.setAttribute("value", moduleId.getArch());
550 moduleEle.appendChild(property);
551 //
552 // PACKAGE_DIR
553 //
554 property = document.createElement("property");
555 property.setAttribute("name", "PACKAGE_DIR");
556 property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
557 + GlobalData.getPackagePathForModule(baseName));
558 moduleEle.appendChild(property);
559 //
560 // PACKAGE
561 //
562 property = document.createElement("property");
563 property.setAttribute("name", "PACKAGE");
564 property.setAttribute("value", GlobalData
565 .getPackageNameForModule(baseName));
566 moduleEle.appendChild(property);
567 ele.appendChild(moduleEle);
568 }
569 root.appendChild(ele);
570 //
571 // FVS Target
572 //
573 root.appendChild(document.createComment("FVs target"));
574 ele = document.createElement("target");
575 ele.setAttribute("name", "fvs");
576
577 String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
578 for (int i = 0; i < validFv.length; i++) {
579 String inputFile = FV_OUTPUT_DIR + "" + File.separatorChar
580 + validFv[i].toUpperCase() + ".inf";
581 Element fvEle = document.createElement("genfvimage");
582 fvEle.setAttribute("infFile", inputFile);
583 ele.appendChild(fvEle);
584 Element moveEle = document.createElement("move");
585 moveEle.setAttribute("file", validFv[i].toUpperCase() + ".fv");
586 moveEle.setAttribute("todir", FV_OUTPUT_DIR);
587 ele.appendChild(moveEle);
588 }
589 root.appendChild(ele);
590
591 boolean isUnified = false;
592 BuildOptionsDocument.BuildOptions buildOptions = (BuildOptionsDocument.BuildOptions)platformBuildOptions;
593 if (buildOptions.getOutputDirectory() != null){
594 if (buildOptions.getOutputDirectory().getIntermediateDirectories() != null){
595 if (buildOptions.getOutputDirectory().getIntermediateDirectories().toString().equalsIgnoreCase("UNIFIED")){
596 isUnified = true;
597 }
598 }
599 }
600 //
601 // Clean Target
602 //
603 root.appendChild(document.createComment("Clean target"));
604 ele = document.createElement("target");
605 ele.setAttribute("name", "clean");
606
607 if (isUnified) {
608 Element cleanEle = document.createElement("delete");
609 cleanEle.setAttribute("includeemptydirs", "true");
610 Element filesetEle = document.createElement("fileset");
611 filesetEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}");
612 filesetEle.setAttribute("includes", "**/OUTPUT/**");
613 cleanEle.appendChild(filesetEle);
614 ele.appendChild(cleanEle);
615 }
616 else {
617 set = outfiles.keySet();
618 iter = set.iterator();
619 while (iter.hasNext()) {
620 FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
621 String baseName = moduleId.getBaseName();
622
623 Element ifEle = document.createElement("if");
624 Element availableEle = document.createElement("available");
625 availableEle.setAttribute("file", GlobalData
626 .getModulePath(baseName)
627 + File.separatorChar + "build.xml");
628 ifEle.appendChild(availableEle);
629 Element elseEle = document.createElement("then");
630
631 Element moduleEle = document.createElement("ant");
632 moduleEle.setAttribute("antfile", GlobalData
633 .getModulePath(baseName)
634 + File.separatorChar + "build.xml");
635 moduleEle.setAttribute("target", baseName + "_clean");
636 //
637 // ARCH
638 //
639 Element property = document.createElement("property");
640 property.setAttribute("name", "ARCH");
641 property.setAttribute("value", moduleId.getArch());
642 moduleEle.appendChild(property);
643 //
644 // PACKAGE_DIR
645 //
646 property = document.createElement("property");
647 property.setAttribute("name", "PACKAGE_DIR");
648 property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
649 + GlobalData.getPackagePathForModule(baseName));
650 moduleEle.appendChild(property);
651 //
652 // PACKAGE
653 //
654 property = document.createElement("property");
655 property.setAttribute("name", "PACKAGE");
656 property.setAttribute("value", GlobalData
657 .getPackageNameForModule(baseName));
658 moduleEle.appendChild(property);
659 elseEle.appendChild(moduleEle);
660 ifEle.appendChild(elseEle);
661 ele.appendChild(ifEle);
662 }
663 }
664 root.appendChild(ele);
665 //
666 // Deep Clean Target
667 //
668 root.appendChild(document.createComment("Clean All target"));
669 ele = document.createElement("target");
670 ele.setAttribute("name", "cleanall");
671
672 if (isUnified) {
673 Element cleanAllEle = document.createElement("delete");
674 cleanAllEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}");
675 ele.appendChild(cleanAllEle);
676 }
677 else {
678 set = outfiles.keySet();
679 iter = set.iterator();
680 while (iter.hasNext()) {
681 FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
682 String baseName = moduleId.getBaseName();
683
684 Element ifEle = document.createElement("if");
685 Element availableEle = document.createElement("available");
686 availableEle.setAttribute("file", GlobalData
687 .getModulePath(baseName)
688 + File.separatorChar + "build.xml");
689 ifEle.appendChild(availableEle);
690 Element elseEle = document.createElement("then");
691
692 Element moduleEle = document.createElement("ant");
693 moduleEle.setAttribute("antfile", GlobalData
694 .getModulePath(baseName)
695 + File.separatorChar + "build.xml");
696 moduleEle.setAttribute("target", baseName + "_cleanall");
697 //
698 // ARCH
699 //
700 Element property = document.createElement("property");
701 property.setAttribute("name", "ARCH");
702 property.setAttribute("value", moduleId.getArch());
703 moduleEle.appendChild(property);
704 //
705 // PACKAGE_DIR
706 //
707 property = document.createElement("property");
708 property.setAttribute("name", "PACKAGE_DIR");
709 property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
710 + GlobalData.getPackagePathForModule(baseName));
711 moduleEle.appendChild(property);
712 //
713 // PACKAGE
714 //
715 property = document.createElement("property");
716 property.setAttribute("name", "PACKAGE");
717 property.setAttribute("value", GlobalData
718 .getPackageNameForModule(baseName));
719 moduleEle.appendChild(property);
720 elseEle.appendChild(moduleEle);
721 ifEle.appendChild(elseEle);
722 ele.appendChild(ifEle);
723 }
724 }
725 root.appendChild(ele);
726
727 document.appendChild(rootComment);
728 document.appendChild(root);
729 //
730 // Prepare the DOM document for writing
731 //
732 Source source = new DOMSource(document);
733 //
734 // Prepare the output file
735 //
736 File file = new File(getProject().getProperty("PLATFORM_DIR")
737 + File.separatorChar + "build.out.xml");
738 //
739 // generate all directory path
740 //
741 (new File(file.getParent())).mkdirs();
742 Result result = new StreamResult(file);
743 //
744 // Write the DOM document to the file
745 //
746 Transformer xformer = TransformerFactory.newInstance()
747 .newTransformer();
748 xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
749 xformer.setOutputProperty(OutputKeys.INDENT, "yes");
750 xformer.transform(source, result);
751 } catch (Exception ex) {
752 throw new BuildException("Generate build.out.xml failed. \n" + ex.getMessage());
753 }
754 }
755
756 /**
757 Add a property.
758
759 @param p property
760 **/
761 public void addProperty(Property p) {
762 properties.addElement(p);
763 }
764
765 /**
766 Get FPD file name.
767
768 @return FPD file name.
769 **/
770 public File getFpdFilename() {
771 return fpdFilename;
772 }
773
774 /**
775 Set FPD file name.
776
777 @param fpdFilename FPD file name
778 **/
779 public void setFpdFilename(File fpdFilename) {
780 this.fpdFilename = fpdFilename;
781 }
782
783 public File getGuiddatabase() {
784 return guiddatabase;
785 }
786
787 public void setGuiddatabase(File guiddatabase) {
788 this.guiddatabase = guiddatabase;
789 }
790
791 public void collectPCDInformation() {
792 String exceptionString = null;
793 CollectPCDAction collectAction = new CollectPCDAction ();
794 //
795 // Collect all PCD information from FPD to MSA, and get help information from SPD.
796 // These all information will be stored into memory database for future usage such
797 // as autogen.
798 //
799 try {
800 collectAction.perform (getProject().getProperty("WORKSPACE_DIR"),
801 fpdFilename.getPath(),
802 ActionMessage.MAX_MESSAGE_LEVEL
803 );
804 } catch (Exception exp) {
805 exceptionString = exp.getMessage();
806 if (exceptionString == null) {
807 exceptionString = "[Internal Error]Pcd tools catch a internel errors, Please report this bug into TianoCore or send email to Wang, scott or Lu, ken!";
808 }
809 throw new BuildException (String.format("Fail to do PCD preprocess from FPD file: %s", exceptionString));
810 }
811 }
812 }