]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java
Fix two bugs for current PCD workflow:
[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> map = new HashMap<String, XmlObject>();
356 //
357 // Whether the Module SA has parsed before or not
358 //
359 if (!GlobalData.isModuleParsed(baseName)) {
360 OverrideProcess op = new OverrideProcess();
361 //
362 // using overriding rules
363 // Here we can also put platform Build override
364 //
365 map = op.override(mbdMap, msaMap);
366 Map<String, XmlObject> overrideMap = op.override(
367 getPlatformOverrideInfo(moduleSAs[i]),
368 OverrideProcess.deal(map));
369 GlobalData.registerModule(baseName, overrideMap);
370 } else {
371 map = GlobalData.getDoc(baseName);
372 }
373 SurfaceAreaQuery.setDoc(map);
374 String guid = SurfaceAreaQuery.getModuleGuid();
375 String componentType = SurfaceAreaQuery.getComponentType();
376 FpdModuleIdentification moduleId = new FpdModuleIdentification(baseName, guid, arch);
377 updateFvs(fvBinding, moduleId);
378 outfiles.put(moduleId, "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar
379 + "${TARGET}" + File.separatorChar + arch
380 + File.separatorChar + guid + "-" + baseName
381 + getSuffix(componentType));
382 }
383 }
384
385 /**
386 Add the current module to corresponding FV.
387
388 @param fvName current FV name
389 @param moduleName current module identification
390 **/
391 private void updateFvs(String fvName, FpdModuleIdentification moduleName) {
392 String upcaseFvName = fvName.toUpperCase();
393 if (fvs.containsKey(upcaseFvName)) {
394 Set<FpdModuleIdentification> set = fvs.get(upcaseFvName);
395 set.add(moduleName);
396 } else {
397 Set<FpdModuleIdentification> set = new LinkedHashSet<FpdModuleIdentification>();
398 set.add(moduleName);
399 fvs.put(upcaseFvName, set);
400 }
401 }
402
403 /**
404 Get the suffix based on component type. Current relationship are listed:
405
406 <pre>
407 <b>ComponentType</b> <b>Suffix</b>
408 APPLICATION .APP
409 SEC .SEC
410 PEI_CORE .PEI
411 PE32_PEIM .PEI
412 RELOCATABLE_PEIM .PEI
413 PIC_PEIM .PEI
414 COMBINED_PEIM_DRIVER .PEI
415 TE_PEIM .PEI
416 LOGO .FFS
417 others .DXE
418 </pre>
419
420 @param componentType component type
421 @return
422 @throws BuildException
423 If component type is null
424 **/
425 public static String getSuffix(String componentType) throws BuildException{
426 if (componentType == null) {
427 throw new BuildException("Component type is not specified.");
428 }
429 String str = ".DXE";
430 if (componentType.equalsIgnoreCase("APPLICATION")) {
431 str = ".APP";
432 } else if (componentType.equalsIgnoreCase("SEC")) {
433 str = ".SEC";
434 } else if (componentType.equalsIgnoreCase("PEI_CORE")) {
435 str = ".PEI";
436 } else if (componentType.equalsIgnoreCase("PE32_PEIM")) {
437 str = ".PEI";
438 } else if (componentType.equalsIgnoreCase("RELOCATABLE_PEIM")) {
439 str = ".PEI";
440 } else if (componentType.equalsIgnoreCase("PIC_PEIM")) {
441 str = ".PEI";
442 } else if (componentType.equalsIgnoreCase("COMBINED_PEIM_DRIVER")) {
443 str = ".PEI";
444 } else if (componentType.equalsIgnoreCase("TE_PEIM")) {
445 str = ".PEI";
446 } else if (componentType.equalsIgnoreCase("LOGO")) {
447 str = ".FFS";
448 }
449 return str;
450 }
451
452 /**
453 Parse module surface are info described in FPD file and put them into map.
454
455 @param sa module surface area info descibed in FPD file
456 @return map list with top level elements
457 **/
458 private Map<String, XmlObject> getPlatformOverrideInfo(
459 ModuleSADocument.ModuleSA sa) {
460 Map<String, XmlObject> map = new HashMap<String, XmlObject>();
461 map.put("SourceFiles", sa.getSourceFiles());
462 map.put("Includes", sa.getIncludes());
463 map.put("Libraries", sa.getLibraries());
464 map.put("Protocols", sa.getProtocols());
465 map.put("Events", sa.getEvents());
466 map.put("Hobs", sa.getHobs());
467 map.put("PPIs", sa.getPPIs());
468 map.put("Variables", sa.getVariables());
469 map.put("BootModes", sa.getBootModes());
470 map.put("SystemTables", sa.getSystemTables());
471 map.put("DataHubs", sa.getDataHubs());
472 map.put("Formsets", sa.getFormsets());
473 map.put("Guids", sa.getGuids());
474 map.put("Externs", sa.getExterns());
475 map.put("BuildOptions", platformBuildOptions);
476 return map;
477 }
478
479 /**
480 Generate build.out.xml file.
481
482 @throws BuildException
483 build.out.xml XML document create error
484 **/
485 private void genBuildFile() throws BuildException {
486 DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
487 try {
488 DocumentBuilder dombuilder = domfac.newDocumentBuilder();
489 Document document = dombuilder.newDocument();
490 Comment rootComment = document.createComment(info);
491 //
492 // create root element and its attributes
493 //
494 Element root = document.createElement("project");
495 root.setAttribute("name", getProject().getProperty("PLATFORM"));
496 root.setAttribute("default", "main");
497 root.setAttribute("basedir", ".");
498 //
499 // element for External ANT tasks
500 //
501 root.appendChild(document.createComment("Apply external ANT tasks"));
502 Element ele = document.createElement("taskdef");
503 ele.setAttribute("resource", "GenBuild.tasks");
504 root.appendChild(ele);
505
506 ele = document.createElement("taskdef");
507 ele.setAttribute("resource", "frameworktasks.tasks");
508 root.appendChild(ele);
509
510 ele = document.createElement("property");
511 ele.setAttribute("environment", "env");
512 root.appendChild(ele);
513 //
514 // Default Target
515 //
516 root.appendChild(document.createComment("Default target"));
517 ele = document.createElement("target");
518 ele.setAttribute("name", "main");
519 ele.setAttribute("depends", "modules, fvs");
520 root.appendChild(ele);
521 //
522 // Modules Target
523 //
524 root.appendChild(document.createComment("Modules target"));
525 ele = document.createElement("target");
526 ele.setAttribute("name", "modules");
527
528 Set set = outfiles.keySet();
529 Iterator iter = set.iterator();
530 while (iter.hasNext()) {
531 FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
532 String baseName = moduleId.getBaseName();
533 Element moduleEle = document.createElement("ant");
534 moduleEle.setAttribute("antfile", GlobalData
535 .getModulePath(baseName)
536 + File.separatorChar + "build.xml");
537 moduleEle.setAttribute("target", baseName);
538 //
539 // ARCH
540 //
541 Element property = document.createElement("property");
542 property.setAttribute("name", "ARCH");
543 property.setAttribute("value", moduleId.getArch());
544 moduleEle.appendChild(property);
545 //
546 // PACKAGE_DIR
547 //
548 property = document.createElement("property");
549 property.setAttribute("name", "PACKAGE_DIR");
550 property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
551 + GlobalData.getPackagePathForModule(baseName));
552 moduleEle.appendChild(property);
553 //
554 // PACKAGE
555 //
556 property = document.createElement("property");
557 property.setAttribute("name", "PACKAGE");
558 property.setAttribute("value", GlobalData
559 .getPackageNameForModule(baseName));
560 moduleEle.appendChild(property);
561 ele.appendChild(moduleEle);
562 }
563 root.appendChild(ele);
564 //
565 // FVS Target
566 //
567 root.appendChild(document.createComment("FVs target"));
568 ele = document.createElement("target");
569 ele.setAttribute("name", "fvs");
570
571 String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
572 for (int i = 0; i < validFv.length; i++) {
573 String inputFile = FV_OUTPUT_DIR + "" + File.separatorChar
574 + validFv[i].toUpperCase() + ".inf";
575 Element fvEle = document.createElement("genfvimage");
576 fvEle.setAttribute("infFile", inputFile);
577 ele.appendChild(fvEle);
578 Element moveEle = document.createElement("move");
579 moveEle.setAttribute("file", validFv[i].toUpperCase() + ".fv");
580 moveEle.setAttribute("todir", FV_OUTPUT_DIR);
581 ele.appendChild(moveEle);
582 }
583 root.appendChild(ele);
584
585 boolean isUnified = false;
586 BuildOptionsDocument.BuildOptions buildOptions = (BuildOptionsDocument.BuildOptions)platformBuildOptions;
587 if (buildOptions.getOutputDirectory() != null){
588 if (buildOptions.getOutputDirectory().getIntermediateDirectories() != null){
589 if (buildOptions.getOutputDirectory().getIntermediateDirectories().toString().equalsIgnoreCase("UNIFIED")){
590 isUnified = true;
591 }
592 }
593 }
594 //
595 // Clean Target
596 //
597 root.appendChild(document.createComment("Clean target"));
598 ele = document.createElement("target");
599 ele.setAttribute("name", "clean");
600
601 if (isUnified) {
602 Element cleanEle = document.createElement("delete");
603 cleanEle.setAttribute("includeemptydirs", "true");
604 Element filesetEle = document.createElement("fileset");
605 filesetEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}");
606 filesetEle.setAttribute("includes", "**/OUTPUT/**");
607 cleanEle.appendChild(filesetEle);
608 ele.appendChild(cleanEle);
609 }
610 else {
611 set = outfiles.keySet();
612 iter = set.iterator();
613 while (iter.hasNext()) {
614 FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
615 String baseName = moduleId.getBaseName();
616
617 Element ifEle = document.createElement("if");
618 Element availableEle = document.createElement("available");
619 availableEle.setAttribute("file", GlobalData
620 .getModulePath(baseName)
621 + File.separatorChar + "build.xml");
622 ifEle.appendChild(availableEle);
623 Element elseEle = document.createElement("then");
624
625 Element moduleEle = document.createElement("ant");
626 moduleEle.setAttribute("antfile", GlobalData
627 .getModulePath(baseName)
628 + File.separatorChar + "build.xml");
629 moduleEle.setAttribute("target", baseName + "_clean");
630 //
631 // ARCH
632 //
633 Element property = document.createElement("property");
634 property.setAttribute("name", "ARCH");
635 property.setAttribute("value", moduleId.getArch());
636 moduleEle.appendChild(property);
637 //
638 // PACKAGE_DIR
639 //
640 property = document.createElement("property");
641 property.setAttribute("name", "PACKAGE_DIR");
642 property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
643 + GlobalData.getPackagePathForModule(baseName));
644 moduleEle.appendChild(property);
645 //
646 // PACKAGE
647 //
648 property = document.createElement("property");
649 property.setAttribute("name", "PACKAGE");
650 property.setAttribute("value", GlobalData
651 .getPackageNameForModule(baseName));
652 moduleEle.appendChild(property);
653 elseEle.appendChild(moduleEle);
654 ifEle.appendChild(elseEle);
655 ele.appendChild(ifEle);
656 }
657 }
658 root.appendChild(ele);
659 //
660 // Deep Clean Target
661 //
662 root.appendChild(document.createComment("Clean All target"));
663 ele = document.createElement("target");
664 ele.setAttribute("name", "cleanall");
665
666 if (isUnified) {
667 Element cleanAllEle = document.createElement("delete");
668 cleanAllEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}");
669 ele.appendChild(cleanAllEle);
670 }
671 else {
672 set = outfiles.keySet();
673 iter = set.iterator();
674 while (iter.hasNext()) {
675 FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
676 String baseName = moduleId.getBaseName();
677
678 Element ifEle = document.createElement("if");
679 Element availableEle = document.createElement("available");
680 availableEle.setAttribute("file", GlobalData
681 .getModulePath(baseName)
682 + File.separatorChar + "build.xml");
683 ifEle.appendChild(availableEle);
684 Element elseEle = document.createElement("then");
685
686 Element moduleEle = document.createElement("ant");
687 moduleEle.setAttribute("antfile", GlobalData
688 .getModulePath(baseName)
689 + File.separatorChar + "build.xml");
690 moduleEle.setAttribute("target", baseName + "_cleanall");
691 //
692 // ARCH
693 //
694 Element property = document.createElement("property");
695 property.setAttribute("name", "ARCH");
696 property.setAttribute("value", moduleId.getArch());
697 moduleEle.appendChild(property);
698 //
699 // PACKAGE_DIR
700 //
701 property = document.createElement("property");
702 property.setAttribute("name", "PACKAGE_DIR");
703 property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
704 + GlobalData.getPackagePathForModule(baseName));
705 moduleEle.appendChild(property);
706 //
707 // PACKAGE
708 //
709 property = document.createElement("property");
710 property.setAttribute("name", "PACKAGE");
711 property.setAttribute("value", GlobalData
712 .getPackageNameForModule(baseName));
713 moduleEle.appendChild(property);
714 elseEle.appendChild(moduleEle);
715 ifEle.appendChild(elseEle);
716 ele.appendChild(ifEle);
717 }
718 }
719 root.appendChild(ele);
720
721 document.appendChild(rootComment);
722 document.appendChild(root);
723 //
724 // Prepare the DOM document for writing
725 //
726 Source source = new DOMSource(document);
727 //
728 // Prepare the output file
729 //
730 File file = new File(getProject().getProperty("PLATFORM_DIR")
731 + File.separatorChar + "build.out.xml");
732 //
733 // generate all directory path
734 //
735 (new File(file.getParent())).mkdirs();
736 Result result = new StreamResult(file);
737 //
738 // Write the DOM document to the file
739 //
740 Transformer xformer = TransformerFactory.newInstance()
741 .newTransformer();
742 xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
743 xformer.setOutputProperty(OutputKeys.INDENT, "yes");
744 xformer.transform(source, result);
745 } catch (Exception ex) {
746 throw new BuildException("Generate build.out.xml failed. \n" + ex.getMessage());
747 }
748 }
749
750 /**
751 Add a property.
752
753 @param p property
754 **/
755 public void addProperty(Property p) {
756 properties.addElement(p);
757 }
758
759 /**
760 Get FPD file name.
761
762 @return FPD file name.
763 **/
764 public File getFpdFilename() {
765 return fpdFilename;
766 }
767
768 /**
769 Set FPD file name.
770
771 @param fpdFilename FPD file name
772 **/
773 public void setFpdFilename(File fpdFilename) {
774 this.fpdFilename = fpdFilename;
775 }
776
777 public File getGuiddatabase() {
778 return guiddatabase;
779 }
780
781 public void setGuiddatabase(File guiddatabase) {
782 this.guiddatabase = guiddatabase;
783 }
784
785 public void collectPCDInformation() {
786 CollectPCDAction collectAction = new CollectPCDAction ();
787 //
788 // Set memory database log file path. It should be put into same directory with FPD file.
789 //
790 GlobalData.getPCDMemoryDBManager().setLogFileName(
791 fpdFilename.getPath() + ".PCDMemroyDatabaseLog.txt"
792 );
793 //
794 // Collect all PCD information from FPD to MSA, and get help information from SPD.
795 // These all information will be stored into memory database for future usage such
796 // as autogen.
797 //
798 try {
799 collectAction.perform (
800 getProject().getProperty("WORKSPACE_DIR"),
801 fpdFilename.getPath(),
802 ActionMessage.MAX_MESSAGE_LEVEL
803 );
804 } catch (Exception exp) {
805 throw new BuildException (exp.getMessage());
806 }
807 }
808 }