2 This file is ANT task FpdParserTask.
4 FpdParserTask is used to parse FPD (Framework Platform Description) and generate
5 build.out.xml. It is for Package or Platform build use.
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
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.
16 package org
.tianocore
.build
.fpd
;
18 import java
.io
.BufferedWriter
;
20 import java
.io
.FileWriter
;
21 import java
.io
.IOException
;
22 import java
.util
.HashMap
;
23 import java
.util
.Iterator
;
24 import java
.util
.LinkedHashMap
;
25 import java
.util
.LinkedHashSet
;
28 import java
.util
.Vector
;
30 import org
.apache
.tools
.ant
.BuildException
;
31 import org
.apache
.tools
.ant
.Task
;
32 import org
.apache
.tools
.ant
.taskdefs
.Ant
;
33 import org
.apache
.tools
.ant
.taskdefs
.Property
;
34 import org
.apache
.xmlbeans
.XmlException
;
35 import org
.apache
.xmlbeans
.XmlObject
;
37 import org
.tianocore
.common
.definitions
.EdkDefinitions
;
38 import org
.tianocore
.common
.definitions
.ToolDefinitions
;
39 import org
.tianocore
.common
.exception
.EdkException
;
40 import org
.tianocore
.common
.logger
.EdkLog
;
41 import org
.tianocore
.build
.FrameworkBuildTask
;
42 import org
.tianocore
.build
.global
.GlobalData
;
43 import org
.tianocore
.build
.global
.OutputManager
;
44 import org
.tianocore
.build
.global
.SurfaceAreaQuery
;
45 import org
.tianocore
.build
.id
.FpdModuleIdentification
;
46 import org
.tianocore
.build
.id
.ModuleIdentification
;
47 import org
.tianocore
.build
.id
.PackageIdentification
;
48 import org
.tianocore
.build
.id
.PlatformIdentification
;
49 import org
.tianocore
.build
.pcd
.action
.PlatformPcdPreprocessActionForBuilding
;
50 import org
.tianocore
.build
.toolchain
.ToolChainElement
;
51 import org
.tianocore
.build
.toolchain
.ToolChainMap
;
52 import org
.tianocore
.build
.toolchain
.ToolChainInfo
;
53 import org
.w3c
.dom
.NamedNodeMap
;
54 import org
.w3c
.dom
.Node
;
55 import org
.w3c
.dom
.NodeList
;
58 <code>FpdParserTask</code> is an ANT task. The main function is parsing Framework
59 Platform Descritpion (FPD) XML file and generating its ANT build script for
60 corresponding platform.
62 <p>The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR
65 <p>The task generates ${PLATFORM}_build.xml file which will be called by top level
66 build.xml. The task also generate Fv.inf files (File is for Tool GenFvImage). </p>
68 <p>FpdParserTask task stores all FPD information to GlobalData. And parse
69 tools definition file to set up compiler options for different Target and
70 different ToolChainTag. </p>
72 <p>The method parseFpdFile is also prepared for single module build. </p>
76 public class FpdParserTask
extends Task
{
79 /// Be used to ensure Global data will be initialized only once.
81 private static boolean parsed
= false;
83 private File fpdFile
= null;
85 PlatformIdentification platformId
;
90 /// Mapping from modules identification to out put file name
92 Map
<FpdModuleIdentification
, String
> outfiles
= new LinkedHashMap
<FpdModuleIdentification
, String
>();
95 /// Mapping from FV name to its modules
97 Map
<String
, Set
<FpdModuleIdentification
>> fvs
= new HashMap
<String
, Set
<FpdModuleIdentification
>>();
100 /// Mapping from FV apriori file to its type (PEI or DXE)
102 Map
<String
, String
> aprioriType
= new HashMap
<String
, String
>();
105 /// FpdParserTask can specify some ANT properties.
107 private Vector
<Property
> properties
= new Vector
<Property
>();
109 SurfaceAreaQuery saq
= null;
111 boolean isUnified
= true;
113 public static String PEI_APRIORI_GUID
= "1b45cc0a-156a-428a-af62-49864da0e6e6";
115 public static String DXE_APRIORI_GUID
= "fc510ee7-ffdc-11d4-bd41-0080c73c8881";
118 Public construct method. It is necessary for ANT task.
120 public FpdParserTask() {
124 ANT task's entry method. The main steps is described as following:
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 PlatformName_build.xml file for Flatform build; </li>
132 <li>Collect PCD information. </li>
135 @throws BuildException
136 Surface area is not valid.
138 public void execute() throws BuildException
{
139 this.setTaskName("FpdParser");
149 isUnified
= OutputManager
.getInstance().prepareBuildDir(getProject());
151 String buildDir
= getProject().getProperty("BUILD_DIR");
153 // For every Target and ToolChain
155 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
156 for (int i
= 0; i
< targetList
.length
; i
++) {
157 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
158 for(int j
= 0; j
< toolchainList
.length
; j
++) {
162 String ffsCommonDir
= buildDir
+ File
.separatorChar
163 + targetList
[i
] + "_"
165 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
167 getProject().setProperty("FV_DIR", fvDir
.getPath().replaceAll("(\\\\)", "/"));
172 genFvInfFiles(ffsCommonDir
);
179 String platformBuildFile
= buildDir
+ File
.separatorChar
+ platformId
.getName() + "_build.xml";
180 PlatformBuildFileGenerator fileGenerator
= new PlatformBuildFileGenerator(getProject(), outfiles
, fvs
, isUnified
, saq
, platformBuildFile
, aprioriType
);
181 fileGenerator
.genBuildFile();
184 // Ant call ${PLATFORM}_build.xml
187 ant
.setProject(getProject());
188 ant
.setAntfile(platformBuildFile
);
190 ant
.setInheritAll(true);
196 Generate Fv.inf files. The Fv.inf file is composed with four
197 parts: Options, Attributes, Components and Files. The Fv.inf files
198 will be under FV_DIR.
200 @throws BuildException
201 File write FV.inf files error.
203 void genFvInfFiles(String ffsCommonDir
) throws BuildException
{
204 String
[] validFv
= saq
.getFpdValidImageNames();
205 for (int i
= 0; i
< validFv
.length
; i
++) {
207 // Get all global variables from FPD and set them to properties
209 String
[][] globalVariables
= saq
.getFpdGlobalVariable();
210 for (int j
= 0; j
< globalVariables
.length
; j
++) {
211 getProject().setProperty(globalVariables
[j
][0], globalVariables
[j
][1]);
214 getProject().setProperty("FV_FILENAME", validFv
[i
]);
216 File fvFile
= new File(getProject().replaceProperties( getProject().getProperty("FV_DIR") + File
.separatorChar
+ validFv
[i
] + ".inf"));
217 if (fvFile
.exists() && (fvFile
.lastModified() >= fpdFile
.lastModified())) {
219 // don't re-generate FV.inf if fpd has not been changed
223 fvFile
.getParentFile().mkdirs();
226 FileWriter fw
= new FileWriter(fvFile
);
227 BufferedWriter bw
= new BufferedWriter(fw
);
232 String
[][] options
= saq
.getFpdOptions(validFv
[i
]);
233 if (options
.length
> 0) {
234 bw
.write("[options]");
236 for (int j
= 0; j
< options
.length
; j
++) {
237 StringBuffer str
= new StringBuffer(100);
238 str
.append(options
[j
][0]);
239 while (str
.length() < 40) {
243 str
.append(options
[j
][1]);
244 bw
.write(getProject().replaceProperties(str
.toString()));
253 String
[][] attributes
= saq
.getFpdAttributes(validFv
[i
]);
254 if (attributes
.length
> 0) {
255 bw
.write("[attributes]");
257 for (int j
= 0; j
< attributes
.length
; j
++) {
258 StringBuffer str
= new StringBuffer(100);
259 str
.append(attributes
[j
][0]);
260 while (str
.length() < 40) {
264 str
.append(attributes
[j
][1]);
265 bw
.write(getProject().replaceProperties(str
.toString()));
274 String
[][] components
= saq
.getFpdComponents(validFv
[i
]);
275 if (components
.length
> 0) {
276 bw
.write("[components]");
278 for (int j
= 0; j
< components
.length
; j
++) {
279 StringBuffer str
= new StringBuffer(100);
280 str
.append(components
[j
][0]);
281 while (str
.length() < 40) {
285 str
.append(components
[j
][1]);
286 bw
.write(getProject().replaceProperties(str
.toString()));
295 Set
<FpdModuleIdentification
> moduleSeqSet
= getModuleSequenceForFv(validFv
[i
]);
297 Set
<FpdModuleIdentification
> filesSet
= fvs
.get(validFv
[i
]);
299 FpdModuleIdentification
[] files
= null;
301 if (moduleSeqSet
== null) {
302 if (filesSet
!= null) {
303 files
= filesSet
.toArray(new FpdModuleIdentification
[filesSet
.size()]);
305 } else if (filesSet
== null) {
306 if (moduleSeqSet
.size() != 0) {
307 throw new BuildException("Can not find any modules belongs to FV[" + validFv
[i
] + "], but listed some in BuildOptions.UserExtensions[@UserID='IMAGES' @Identifier='1']");
311 // if moduleSeqSet and filesSet is inconsistent, report error
313 if(moduleSeqSet
.size() != filesSet
.size()){
314 throw new BuildException("Modules for FV[" + validFv
[i
] + "] defined in FrameworkModules and in BuildOptions.UserExtensions[@UserID='IMAGES' @Identifier='1'] are inconsistent. ");
317 // whether all modules in moduleSeqSet listed in filesSet
319 Iterator
<FpdModuleIdentification
> iter
= moduleSeqSet
.iterator();
320 while (iter
.hasNext()) {
321 FpdModuleIdentification item
= iter
.next();
322 if (!filesSet
.contains(item
)) {
323 throw new BuildException("Can not find " + item
+ " belongs to FV[" + validFv
[i
] + "]");
328 files
= moduleSeqSet
.toArray(new FpdModuleIdentification
[moduleSeqSet
.size()]);
336 Set
<FpdModuleIdentification
> modules
= null;
338 if ( (modules
= getPeiApriori(validFv
[i
])) != null) {
340 // Special GUID - validFv[i].FFS
342 String str
= ffsCommonDir
+ File
.separatorChar
+ "FV" + File
.separatorChar
+ PEI_APRIORI_GUID
+ "-" + validFv
[i
] + ".FFS";
343 bw
.write(getProject().replaceProperties("EFI_FILE_NAME = " + str
));
346 File aprioriFile
= new File(getProject().getProperty("FV_DIR") + File
.separatorChar
+ validFv
[i
] + ".apr");
347 aprioriType
.put(validFv
[i
], PEI_APRIORI_GUID
);
348 genAprioriFile(modules
, aprioriFile
);
349 } else if((modules
= getDxeApriori(validFv
[i
])) != null) {
351 // Special GUID - validFv[i].FFS
353 String str
= ffsCommonDir
+ File
.separatorChar
+ "FV" + File
.separatorChar
+ DXE_APRIORI_GUID
+ "-" + validFv
[i
] + ".FFS";
354 bw
.write(getProject().replaceProperties("EFI_FILE_NAME = " + str
));
357 File aprioriFile
= new File(getProject().getProperty("FV_DIR") + File
.separatorChar
+ validFv
[i
] + ".apr");
358 aprioriType
.put(validFv
[i
], DXE_APRIORI_GUID
);
359 genAprioriFile(modules
, aprioriFile
);
362 for (int j
= 0; j
< files
.length
; j
++) {
363 String str
= ffsCommonDir
+ File
.separatorChar
+ outfiles
.get(files
[j
]);
364 bw
.write(getProject().replaceProperties("EFI_FILE_NAME = " + str
));
371 } catch (IOException ex
) {
372 BuildException buildException
= new BuildException("Generation of the FV file [" + fvFile
.getPath() + "] failed!\n" + ex
.getMessage());
373 buildException
.setStackTrace(ex
.getStackTrace());
374 throw buildException
;
375 } catch (EdkException ex
) {
376 BuildException buildException
= new BuildException("Generation of the FV file [" + fvFile
.getPath() + "] failed!\n" + ex
.getMessage());
377 buildException
.setStackTrace(ex
.getStackTrace());
378 throw buildException
;
384 This method is used for Single Module Build.
386 @throws BuildException
387 FPD file is not valid.
389 public void parseFpdFile(File fpdFile
) throws BuildException
, EdkException
{
390 this.fpdFile
= fpdFile
;
394 // Call Platform_build.xml prebuild firstly in stand-alone build
397 isUnified
= OutputManager
.getInstance().prepareBuildDir(getProject());
399 String buildDir
= getProject().getProperty("BUILD_DIR");
401 // For every Target and ToolChain
403 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
404 for (int i
= 0; i
< targetList
.length
; i
++) {
405 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
406 for(int j
= 0; j
< toolchainList
.length
; j
++) {
410 String ffsCommonDir
= buildDir
+ File
.separatorChar
411 + targetList
[i
] + "_"
413 File fvDir
= new File(ffsCommonDir
+ File
.separatorChar
+ "FV");
418 String platformBuildFile
= buildDir
+ File
.separatorChar
+ platformId
.getName() + "_build.xml";
419 PlatformBuildFileGenerator fileGenerator
= new PlatformBuildFileGenerator(getProject(), outfiles
, fvs
, isUnified
, saq
, platformBuildFile
, aprioriType
);
420 fileGenerator
.genBuildFile();
423 ant
.setProject(getProject());
424 ant
.setAntfile(platformBuildFile
);
425 ant
.setTarget("prebuild");
426 ant
.setInheritAll(true);
434 @throws BuildException
435 FPD file is not valid.
437 void parseFpdFile() throws BuildException
{
439 XmlObject doc
= XmlObject
.Factory
.parse(fpdFile
);
441 if (!doc
.validate()) {
442 throw new BuildException("Platform Surface Area file [" + fpdFile
.getPath() + "] format is invalid!");
445 Map
<String
, XmlObject
> map
= new HashMap
<String
, XmlObject
>();
446 map
.put("PlatformSurfaceArea", doc
);
447 saq
= new SurfaceAreaQuery(map
);
452 platformId
= saq
.getFpdHeader();
453 platformId
.setFpdFile(fpdFile
);
454 getProject().setProperty("PLATFORM", platformId
.getName());
455 getProject().setProperty("PLATFORM_FILE", platformId
.getRelativeFpdFile().replaceAll("(\\\\)", "/"));
456 getProject().setProperty("PLATFORM_DIR", platformId
.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
457 getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId
.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
459 if( !FrameworkBuildTask
.multithread
) {
460 FrameworkBuildTask
.originalProperties
.put("PLATFORM", platformId
.getName());
461 FrameworkBuildTask
.originalProperties
.put("PLATFORM_FILE", platformId
.getRelativeFpdFile().replaceAll("(\\\\)", "/"));
462 FrameworkBuildTask
.originalProperties
.put("PLATFORM_DIR", platformId
.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
463 FrameworkBuildTask
.originalProperties
.put("PLATFORM_RELATIVE_DIR", platformId
.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
467 // Build mode. User-defined output dir.
469 String buildMode
= saq
.getFpdIntermediateDirectories();
470 String userDefinedOutputDir
= saq
.getFpdOutputDirectory();
472 OutputManager
.getInstance().setup(userDefinedOutputDir
, buildMode
);
475 // TBD. Deal PCD and BuildOption related Info
477 GlobalData
.setFpdBuildOptions(saq
.getFpdBuildOptions());
479 GlobalData
.setToolChainPlatformInfo(saq
.getFpdToolChainInfo());
482 // Parse all list modules SA
484 parseModuleSAFiles();
487 // TBD. Deal PCD and BuildOption related Info
489 parseToolChainFamilyOptions();
490 parseToolChainOptions();
493 // check if the tool chain is valid or not
500 // Pcd Collection. Call CollectPCDAction to collect pcd info.
503 PlatformPcdPreprocessActionForBuilding ca
= new PlatformPcdPreprocessActionForBuilding();
504 ca
.perform(platformId
.getFpdFile().getPath());
506 } catch (IOException ex
) {
507 BuildException buildException
= new BuildException("Parsing of the FPD file [" + fpdFile
.getPath() + "] failed!\n" + ex
.getMessage());
508 buildException
.setStackTrace(ex
.getStackTrace());
509 throw buildException
;
510 } catch (XmlException ex
) {
511 BuildException buildException
= new BuildException("Parsing of the FPD file [" + fpdFile
.getPath() + "] failed!\n" + ex
.getMessage());
512 buildException
.setStackTrace(ex
.getStackTrace());
513 throw buildException
;
514 } catch (EdkException ex
) {
515 BuildException buildException
= new BuildException("Parsing of the FPD file [" + fpdFile
.getPath() + "] failed!\n" + ex
.getMessage());
516 buildException
.setStackTrace(ex
.getStackTrace());
517 throw buildException
;
525 Parse all modules listed in FPD file.
527 void parseModuleSAFiles() throws EdkException
{
528 Map
<FpdModuleIdentification
, Map
<String
, XmlObject
>> moduleSAs
= saq
.getFpdModules();
531 // For every Module lists in FPD file.
533 Set
<FpdModuleIdentification
> keys
= moduleSAs
.keySet();
534 Iterator iter
= keys
.iterator();
535 while (iter
.hasNext()) {
536 FpdModuleIdentification fpdModuleId
= (FpdModuleIdentification
) iter
.next();
539 // Judge if Module is existed?
541 GlobalData
.registerFpdModuleSA(fpdModuleId
, moduleSAs
.get(fpdModuleId
));
544 // Put fpdModuleId to the corresponding FV
546 saq
.push(GlobalData
.getDoc(fpdModuleId
));
547 String fvBinding
= saq
.getModuleFvBindingKeyword();
549 fpdModuleId
.setFvBinding(fvBinding
);
550 updateFvs(fvBinding
, fpdModuleId
);
553 // Prepare for out put file name
555 ModuleIdentification moduleId
= fpdModuleId
.getModule();
557 String baseName
= saq
.getModuleOutputFileBasename();
559 if (baseName
== null) {
560 baseName
= moduleId
.getName();
562 outfiles
.put(fpdModuleId
, fpdModuleId
.getArch() + File
.separatorChar
563 + moduleId
.getGuid() + "-" + baseName
564 + getSuffix(moduleId
.getModuleType()));
567 // parse module build options, if any
569 GlobalData
.addModuleToolChainOption(fpdModuleId
, parseModuleBuildOptions(false));
570 GlobalData
.addModuleToolChainFamilyOption(fpdModuleId
, parseModuleBuildOptions(true));
573 // parse MSA build options
575 GlobalData
.addMsaBuildOption(moduleId
, parseMsaBuildOptions(false));
576 GlobalData
.addMsaFamilyBuildOption(moduleId
, parseMsaBuildOptions(true));
578 ModuleIdentification
[] libraryInstances
= saq
.getLibraryInstance(null);
579 for (int i
= 0; i
< libraryInstances
.length
; i
++) {
580 saq
.push(GlobalData
.getDoc(libraryInstances
[i
], fpdModuleId
.getArch()));
581 GlobalData
.addMsaBuildOption(libraryInstances
[i
], parseMsaBuildOptions(false));
582 GlobalData
.addMsaFamilyBuildOption(libraryInstances
[i
], parseMsaBuildOptions(true));
590 ToolChainMap
parseModuleBuildOptions(boolean toolChainFamilyFlag
) throws EdkException
{
591 String
[][] options
= saq
.getModuleBuildOptions(toolChainFamilyFlag
);
592 if (options
== null || options
.length
== 0) {
593 return new ToolChainMap();
595 return parseOptions(options
);
598 private ToolChainMap
parsePlatformBuildOptions(boolean toolChainFamilyFlag
) throws EdkException
{
599 String
[][] options
= saq
.getPlatformBuildOptions(toolChainFamilyFlag
);
600 if (options
== null || options
.length
== 0) {
601 return new ToolChainMap();
603 return parseOptions(options
);
606 ToolChainMap
parseMsaBuildOptions(boolean toolChainFamilyFlag
) throws EdkException
{
607 String
[][] options
= saq
.getMsaBuildOptions(toolChainFamilyFlag
);
608 if (options
== null || options
.length
== 0) {
609 return new ToolChainMap();
611 return parseOptions(options
);
614 private ToolChainMap
parseOptions(String
[][] options
) throws EdkException
{
615 ToolChainMap map
= new ToolChainMap();
616 int flagIndex
= ToolChainElement
.ATTRIBUTE
.value
;
618 for (int i
= 0; i
< options
.length
; ++i
) {
619 String flagString
= options
[i
][flagIndex
];
620 if (flagString
== null) {
623 options
[i
][flagIndex
] = ToolDefinitions
.TOOLS_DEF_ATTRIBUTE_FLAGS
;
624 map
.put(options
[i
], flagString
.trim());
630 private void parseToolChainFamilyOptions() throws EdkException
{
631 GlobalData
.setPlatformToolChainFamilyOption(parsePlatformBuildOptions(true));
634 private void parseToolChainOptions() throws EdkException
{
635 GlobalData
.setPlatformToolChainOption(parsePlatformBuildOptions(false));
639 Add the current module to corresponding FV.
641 @param fvName current FV name
642 @param moduleName current module identification
644 void updateFvs(String fvName
, FpdModuleIdentification fpdModuleId
) {
645 if (fvName
== null || fvName
.trim().length() == 0) {
648 String
[] fvNameArray
= fvName
.split("[, \t]+");
649 for (int i
= 0; i
< fvNameArray
.length
; i
++) {
651 // Put module to corresponding fvName
653 if (fvs
.containsKey(fvNameArray
[i
])) {
654 Set
<FpdModuleIdentification
> set
= fvs
.get(fvNameArray
[i
]);
655 set
.add(fpdModuleId
);
657 Set
<FpdModuleIdentification
> set
= new LinkedHashSet
<FpdModuleIdentification
>();
658 set
.add(fpdModuleId
);
659 fvs
.put(fvNameArray
[i
], set
);
665 Get the suffix based on module type. Current relationship are listed:
668 <b>ModuleType</b> <b>Suffix</b>
675 DXE_RUNTIME_DRIVER .DXE
680 UEFI_APPLICATION .APP
684 @param moduleType module type
686 @throws BuildException
687 If module type is null
689 public static String
getSuffix(String moduleType
) throws BuildException
{
690 if (moduleType
== null) {
691 throw new BuildException("Module type is not specified.");
694 String
[][] suffix
= EdkDefinitions
.ModuleTypeExtensions
;
696 for (int i
= 0; i
< suffix
.length
; i
++) {
697 if (suffix
[i
][0].equalsIgnoreCase(moduleType
)) {
711 public void addProperty(Property p
) {
712 properties
.addElement(p
);
715 public void setFpdFile(File fpdFile
) {
716 this.fpdFile
= fpdFile
;
719 public void setType(String type
) {
723 public String
getAllArchForModule(ModuleIdentification moduleId
) {
725 Iterator
<FpdModuleIdentification
> iter
= outfiles
.keySet().iterator();
726 while (iter
.hasNext()) {
727 FpdModuleIdentification fpdModuleId
= iter
.next();
729 if (fpdModuleId
.getModule().equals(moduleId
)) {
730 archs
+= fpdModuleId
.getArch() + " ";
737 private void genAprioriFile(Set
<FpdModuleIdentification
> modules
, File file
) {
739 FileWriter fw
= new FileWriter(file
);
740 BufferedWriter bw
= new BufferedWriter(fw
);
742 Iterator
<FpdModuleIdentification
> iter
= modules
.iterator();
743 while(iter
.hasNext()) {
744 bw
.write(iter
.next().getModule().getGuid());
751 } catch (IOException ex
) {
752 BuildException buildException
= new BuildException("Generation of the Apriori file [" + file
.getPath() + "] failed!\n" + ex
.getMessage());
753 buildException
.setStackTrace(ex
.getStackTrace());
754 throw buildException
;
758 private Set
<FpdModuleIdentification
> getPeiApriori(String fvName
) throws EdkException
{
759 Node node
= saq
.getPeiApriori(fvName
);
760 Set
<FpdModuleIdentification
> result
= new LinkedHashSet
<FpdModuleIdentification
>();
765 NodeList childNodes
= node
.getChildNodes();
766 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
767 Node childItem
= childNodes
.item(i
);
768 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
770 // Find child elements "IncludeModules"
772 if (childItem
.getNodeName().compareTo("IncludeModules") == 0) {
774 // result will be updated
776 processNodes(childItem
, result
);
777 } else if (childItem
.getNodeName().compareTo("FvName") == 0) {
779 } else if (childItem
.getNodeName().compareTo("InfFileName") == 0) {
785 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Unrecognised element " + childItem
.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='APRIORI' Identifier='0']");
793 private Set
<FpdModuleIdentification
> getDxeApriori(String fvName
) throws EdkException
{
794 Node node
= saq
.getDxeApriori(fvName
);
795 Set
<FpdModuleIdentification
> result
= new LinkedHashSet
<FpdModuleIdentification
>();
800 NodeList childNodes
= node
.getChildNodes();
801 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
802 Node childItem
= childNodes
.item(i
);
803 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
805 // Find child elements "IncludeModules"
807 if (childItem
.getNodeName().compareTo("IncludeModules") == 0) {
809 // result will be updated
811 processNodes(childItem
, result
);
812 } else if (childItem
.getNodeName().compareTo("FvName") == 0) {
814 } else if (childItem
.getNodeName().compareTo("InfFileName") == 0) {
820 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Unrecognised element " + childItem
.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='APRIORI' Identifier='1']");
828 private Set
<FpdModuleIdentification
> getModuleSequenceForFv(String fvName
) throws EdkException
{
829 Node node
= saq
.getFpdModuleSequence(fvName
);
830 Set
<FpdModuleIdentification
> result
= new LinkedHashSet
<FpdModuleIdentification
>();
833 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "FV[" + fvName
+ "] does not specify module sequence in FPD. Assuming present sequence as default sequence in FV. ");
836 NodeList childNodes
= node
.getChildNodes();
837 for (int i
= 0; i
< childNodes
.getLength(); i
++) {
838 Node childItem
= childNodes
.item(i
);
839 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
841 // Find child elements "IncludeModules"
843 if (childItem
.getNodeName().compareTo("IncludeModules") == 0) {
845 // result will be updated
847 processNodes(childItem
, result
);
848 } else if (childItem
.getNodeName().compareTo("FvName") == 0) {
850 } else if (childItem
.getNodeName().compareTo("InfFileName") == 0) {
856 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Unrecognised element " + childItem
.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1']");
865 private void processNodes(Node node
, Set
<FpdModuleIdentification
> result
) throws EdkException
{
867 // Found out all elements "Module"
869 NodeList childNodes
= node
.getChildNodes();
870 for (int j
= 0; j
< childNodes
.getLength(); j
++) {
871 Node childItem
= childNodes
.item(j
);
872 if (childItem
.getNodeType() == Node
.ELEMENT_NODE
) {
873 if (childItem
.getNodeName().compareTo("Module") == 0) {
874 String moduleGuid
= null;
875 String moduleVersion
= null;
876 String packageGuid
= null;
877 String packageVersion
= null;
880 NamedNodeMap attr
= childItem
.getAttributes();
881 for (int i
= 0; i
< attr
.getLength(); i
++) {
882 Node attrItem
= attr
.item(i
);
883 if (attrItem
.getNodeName().compareTo("ModuleGuid") == 0) {
884 moduleGuid
= attrItem
.getNodeValue();
885 } else if (attrItem
.getNodeName().compareTo("ModuleVersion") == 0) {
886 moduleVersion
= attrItem
.getNodeValue();
887 } else if (attrItem
.getNodeName().compareTo("PackageGuid") == 0) {
888 packageGuid
= attrItem
.getNodeValue();
889 } else if (attrItem
.getNodeName().compareTo("PackageVersion") == 0) {
890 packageVersion
= attrItem
.getNodeValue();
891 } else if (attrItem
.getNodeName().compareTo("Arch") == 0) {
892 arch
= attrItem
.getNodeValue();
897 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Unrecognised attribute " + attrItem
.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules.Module");
901 PackageIdentification packageId
= new PackageIdentification(packageGuid
, packageVersion
);
902 GlobalData
.refreshPackageIdentification(packageId
);
904 ModuleIdentification moduleId
= new ModuleIdentification(moduleGuid
, moduleVersion
);
905 moduleId
.setPackage(packageId
);
906 GlobalData
.refreshModuleIdentification(moduleId
);
909 throw new EdkException("Attribute [Arch] is required for element FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules.Module. ");
912 result
.add(new FpdModuleIdentification(moduleId
, arch
));
917 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Unrecognised element " + childItem
.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules");
924 private void checkToolChain() throws EdkException
{
925 ToolChainInfo toolChainInfo
= GlobalData
.getToolChainInfo();
927 if (toolChainInfo
.getTargets().length
== 0) {
928 throw new EdkException("No valid target found! "+
929 "Please check the TARGET definition in Tools/Conf/target.txt, "+
930 "or the <BuildTarget>, <BuildOptions> in the FPD file.");
933 if (toolChainInfo
.getTagnames().length
== 0) {
934 throw new EdkException("No valid tool chain found! "+
935 "Please check the TOOL_CHAIN_TAG definition in Tools/Conf/target.txt, "+
936 "or the <BuildOptions> in the FPD file.");
939 if (toolChainInfo
.getArchs().length
== 0) {
940 throw new EdkException("No valid architecture found! "+
941 "Please check the TARGET_ARCH definition in Tools/Conf/target.txt, "+
942 "or the <SupportedArchitectures>, <BuildOptions> in the FPD file.");
945 if (toolChainInfo
.getCommands().length
== 0) {
946 throw new EdkException("No valid COMMAND found! Please check the tool chain definitions "+
947 "in Tools/Conf/tools_def.txt.");