/** @file\r
- This file is ANT task FpdParserTask. \r
- \r
+ This file is ANT task FpdParserTask.\r
+\r
FpdParserTask is used to parse FPD (Framework Platform Description) and generate\r
- build.out.xml. It is for Package or Platform build use. \r
- \r
+ build.out.xml. It is for Package or Platform build use.\r
+\r
Copyright (c) 2006, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
import java.io.BufferedWriter;\r
import java.io.File;\r
import java.io.FileWriter;\r
+import java.io.IOException;\r
import java.util.HashMap;\r
import java.util.Iterator;\r
import java.util.LinkedHashMap;\r
import java.util.Map;\r
import java.util.Set;\r
import java.util.Vector;\r
-import java.util.TreeMap;\r
\r
import org.apache.tools.ant.BuildException;\r
import org.apache.tools.ant.Task;\r
import org.apache.tools.ant.taskdefs.Ant;\r
import org.apache.tools.ant.taskdefs.Property;\r
+import org.apache.xmlbeans.XmlException;\r
import org.apache.xmlbeans.XmlObject;\r
\r
+import org.tianocore.common.definitions.EdkDefinitions;\r
+import org.tianocore.common.exception.EdkException;\r
+import org.tianocore.common.logger.EdkLog;\r
+import org.tianocore.pcd.action.ActionMessage;\r
+import org.tianocore.build.FrameworkBuildTask;\r
import org.tianocore.build.global.GlobalData;\r
import org.tianocore.build.global.OutputManager;\r
import org.tianocore.build.global.SurfaceAreaQuery;\r
import org.tianocore.build.id.FpdModuleIdentification;\r
import org.tianocore.build.id.ModuleIdentification;\r
+import org.tianocore.build.id.PackageIdentification;\r
import org.tianocore.build.id.PlatformIdentification;\r
-import org.tianocore.build.pcd.action.ActionMessage;\r
-import org.tianocore.build.pcd.action.CollectPCDAction;\r
+import org.tianocore.build.pcd.action.PlatformPcdPreprocessActionForBuilding;\r
import org.tianocore.build.toolchain.ToolChainAttribute;\r
import org.tianocore.build.toolchain.ToolChainElement;\r
import org.tianocore.build.toolchain.ToolChainMap;\r
-import org.tianocore.exception.EdkException;\r
+import org.w3c.dom.NamedNodeMap;\r
+import org.w3c.dom.Node;\r
+import org.w3c.dom.NodeList;\r
\r
/**\r
<code>FpdParserTask</code> is an ANT task. The main function is parsing Framework\r
- Platform Descritpion (FPD) XML file and generating its ANT build script for \r
- corresponding platform. \r
+ Platform Descritpion (FPD) XML file and generating its ANT build script for\r
+ corresponding platform.\r
\r
<p>The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR\r
and BUILD_DIR. </p>\r
- \r
+\r
<p>The task generates ${PLATFORM}_build.xml file which will be called by top level\r
- build.xml. The task also generate Fv.inf files (File is for Tool GenFvImage) \r
- and flash definition file (File is for Tool FlashMap) if necessary. </p>\r
- \r
+ build.xml. The task also generate Fv.inf files (File is for Tool GenFvImage). </p>\r
+\r
<p>FpdParserTask task stores all FPD information to GlobalData. And parse\r
tools definition file to set up compiler options for different Target and\r
different ToolChainTag. </p>\r
- \r
- <p>The method parseFpdFile is also prepared for single module build. </p>\r
- \r
- <p>The usage is (take NT32 Platform for example):</p>\r
\r
- <pre>\r
- <FPDParser platformName="Nt32" />\r
- </pre>\r
-\r
- <p>The task will initialize all information through parsing Framework Database, \r
- SPD, Tool chain configuration files. </p>\r
+ <p>The method parseFpdFile is also prepared for single module build. </p>\r
\r
@since GenBuild 1.0\r
**/\r
public class FpdParserTask extends Task {\r
- \r
- private String platformName;\r
\r
private File fpdFile = null;\r
- \r
- private PlatformIdentification platformId;\r
- \r
- ///\r
- /// \r
- ///\r
+\r
+ PlatformIdentification platformId;\r
+\r
private String type;\r
- \r
+\r
///\r
/// Mapping from modules identification to out put file name\r
///\r
- private Map<FpdModuleIdentification, String> outfiles = new LinkedHashMap<FpdModuleIdentification, String>();\r
+ Map<FpdModuleIdentification, String> outfiles = new LinkedHashMap<FpdModuleIdentification, String>();\r
\r
///\r
/// Mapping from FV name to its modules\r
///\r
- private Map<String, Set<FpdModuleIdentification>> fvs = new HashMap<String, Set<FpdModuleIdentification>>();\r
+ Map<String, Set<FpdModuleIdentification>> fvs = new HashMap<String, Set<FpdModuleIdentification>>();\r
\r
///\r
- /// Mapping from sequence number to FV names\r
- ///\r
- private Map<String, Set<String>> sequences = new TreeMap<String, Set<String>>();\r
-\r
- ///\r
- /// FpdParserTask can specify some ANT properties. \r
+ /// FpdParserTask can specify some ANT properties.\r
///\r
private Vector<Property> properties = new Vector<Property>();\r
- \r
- private boolean isUnified = true;\r
\r
+ SurfaceAreaQuery saq = null;\r
+ \r
+ boolean isUnified = true;\r
\r
/**\r
Public construct method. It is necessary for ANT task.\r
}\r
\r
/**\r
- ANT task's entry method. The main steps is described as following: \r
- \r
+ ANT task's entry method. The main steps is described as following:\r
+\r
<ul>\r
- <li>Initialize global information (Framework DB, SPD files and all MSA files \r
+ <li>Initialize global information (Framework DB, SPD files and all MSA files\r
listed in SPD). This step will execute only once in whole build process;</li>\r
<li>Parse specified FPD file; </li>\r
<li>Generate FV.inf files; </li>\r
<li>Generate PlatformName_build.xml file for Flatform build; </li>\r
<li>Collect PCD information. </li>\r
</ul>\r
- \r
+\r
@throws BuildException\r
- Surface area is not valid. \r
+ Surface area is not valid.\r
**/\r
public void execute() throws BuildException {\r
- // Remove !!\r
- if ( fpdFile == null) {\r
- if (platformName == null) {\r
- throw new BuildException("FpdParserTask parameter error. Please specify platform name or FPD file. ");\r
- }\r
- platformId = GlobalData.getPlatformByName(platformName);\r
- fpdFile = platformId.getFpdFile();\r
- }\r
+ this.setTaskName("FpdParser");\r
\r
//\r
// Parse FPD file\r
//\r
parseFpdFile();\r
- \r
+\r
//\r
// Prepare BUILD_DIR\r
//\r
isUnified = OutputManager.getInstance().prepareBuildDir(getProject());\r
- \r
- //\r
- // Generate FDF (Flash Definition File) file\r
- //\r
\r
+ String buildDir = getProject().getProperty("BUILD_DIR");\r
//\r
// For every Target and ToolChain\r
//\r
String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
- for (int i = 0; i < targetList.length; i++){\r
+ for (int i = 0; i < targetList.length; i++) {\r
String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
- for(int j = 0; j < toolchainList.length; j++){\r
+ for(int j = 0; j < toolchainList.length; j++) {\r
//\r
// Prepare FV_DIR\r
//\r
- String ffsCommonDir = getProject().getProperty("BUILD_DIR") + File.separatorChar \r
- + targetList[i] + File.separatorChar \r
+ String ffsCommonDir = buildDir + File.separatorChar\r
+ + targetList[i] + "_"\r
+ toolchainList[j];\r
File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");\r
fvDir.mkdirs();\r
getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/"));\r
- \r
+\r
//\r
// Gen Fv.inf files\r
//\r
//\r
// Gen build.xml\r
//\r
- PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, sequences, isUnified);\r
+ String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml";\r
+ PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile);\r
fileGenerator.genBuildFile();\r
- \r
+\r
//\r
// Ant call ${PLATFORM}_build.xml\r
//\r
- \r
Ant ant = new Ant();\r
ant.setProject(getProject());\r
- ant.setAntfile(platformId.getFpdFile().getParent() + File.separatorChar + platformId.getName() + "_build.xml");\r
+ ant.setAntfile(platformBuildFile);\r
ant.setTarget(type);\r
ant.setInheritAll(true);\r
ant.init();\r
ant.execute();\r
- \r
-// GlobalData.log.info("Fpd build end. ");\r
}\r
\r
/**\r
- Generate Fv.inf files. The Fv.inf file is composed with four \r
- parts: Options, Attributes, Components and Files. The Fv.inf files \r
+ Generate Fv.inf files. The Fv.inf file is composed with four\r
+ parts: Options, Attributes, Components and Files. The Fv.inf files\r
will be under FV_DIR.\r
- \r
+\r
@throws BuildException\r
- File write FV.inf files error. \r
+ File write FV.inf files error.\r
**/\r
- private void genFvInfFiles(String ffsCommonDir) throws BuildException {\r
- String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();\r
+ void genFvInfFiles(String ffsCommonDir) throws BuildException {\r
+ String[] validFv = saq.getFpdValidImageNames();\r
for (int i = 0; i < validFv.length; i++) {\r
//\r
// Get all global variables from FPD and set them to properties\r
//\r
- String[][] globalVariables = SurfaceAreaQuery.getFpdGlobalVariable();\r
+ String[][] globalVariables = saq.getFpdGlobalVariable();\r
for (int j = 0; j < globalVariables.length; j++) {\r
getProject().setProperty(globalVariables[j][0], globalVariables[j][1]);\r
}\r
\r
- getProject().setProperty("FV_FILENAME", validFv[i].toUpperCase());\r
- \r
- File fvFile = new File(getProject().replaceProperties( getProject().getProperty("FV_DIR") + File.separatorChar + validFv[i].toUpperCase() + ".inf"));\r
+ getProject().setProperty("FV_FILENAME", validFv[i]);\r
+\r
+ File fvFile = new File(getProject().replaceProperties( getProject().getProperty("FV_DIR") + File.separatorChar + validFv[i] + ".inf"));\r
+ if (fvFile.exists() && (fvFile.lastModified() >= fpdFile.lastModified())) {\r
+ //\r
+ // don't re-generate FV.inf if fpd has not been changed\r
+ // \r
+ continue;\r
+ }\r
fvFile.getParentFile().mkdirs();\r
\r
try {\r
FileWriter fw = new FileWriter(fvFile);\r
BufferedWriter bw = new BufferedWriter(fw);\r
- \r
+\r
//\r
// Options\r
//\r
- String[][] options = SurfaceAreaQuery.getFpdOptions(validFv[i]);\r
+ String[][] options = saq.getFpdOptions(validFv[i]);\r
if (options.length > 0) {\r
bw.write("[options]");\r
bw.newLine();\r
}\r
bw.newLine();\r
}\r
- \r
+\r
//\r
// Attributes;\r
//\r
- String[][] attributes = SurfaceAreaQuery.getFpdAttributes(validFv[i]);\r
+ String[][] attributes = saq.getFpdAttributes(validFv[i]);\r
if (attributes.length > 0) {\r
bw.write("[attributes]");\r
bw.newLine();\r
}\r
bw.newLine();\r
}\r
- \r
+\r
//\r
// Components\r
//\r
- String[][] components = SurfaceAreaQuery.getFpdComponents(validFv[i]);\r
+ String[][] components = saq.getFpdComponents(validFv[i]);\r
if (components.length > 0) {\r
bw.write("[components]");\r
bw.newLine();\r
//\r
// Files\r
//\r
- Set<FpdModuleIdentification> filesSet = fvs.get(validFv[i].toUpperCase());\r
- if (filesSet != null) {\r
- FpdModuleIdentification[] files = filesSet.toArray(new FpdModuleIdentification[filesSet.size()]);\r
+ Set<FpdModuleIdentification> moduleSeqSet = getModuleSequenceForFv(validFv[i]);\r
+ \r
+ Set<FpdModuleIdentification> filesSet = fvs.get(validFv[i]);\r
+ \r
+ FpdModuleIdentification[] files = null;\r
+ \r
+ if (moduleSeqSet == null) {\r
+ if (filesSet != null) {\r
+ files = filesSet.toArray(new FpdModuleIdentification[filesSet.size()]);\r
+ }\r
+ } else if (filesSet == null) {\r
+ if (moduleSeqSet.size() != 0) {\r
+ throw new BuildException("Can not find any modules belongs to FV[" + validFv[i] + "], but listed some in BuildOptions.UserExtensions[@UserID='IMAGES' @Identifier='1']");\r
+ }\r
+ } else {\r
+ //\r
+ // if moduleSeqSet and filesSet is inconsistent, report error\r
+ //\r
+ if(moduleSeqSet.size() != filesSet.size()){\r
+ throw new BuildException("Modules for FV[" + validFv[i] + "] defined in FrameworkModules and in BuildOptions.UserExtensions[@UserID='IMAGES' @Identifier='1'] are inconsistent. ");\r
+ } else {\r
+ //\r
+ // whether all modules in moduleSeqSet listed in filesSet\r
+ //\r
+ Iterator<FpdModuleIdentification> iter = moduleSeqSet.iterator();\r
+ while (iter.hasNext()) {\r
+ FpdModuleIdentification item = iter.next();\r
+ if (!filesSet.contains(item)) {\r
+ throw new BuildException("Can not find " + item + " belongs to FV[" + validFv[i] + "]");\r
+ }\r
+ }\r
+ }\r
+ \r
+ files = moduleSeqSet.toArray(new FpdModuleIdentification[moduleSeqSet.size()]);\r
+ }\r
+ \r
+ \r
+ if (files != null) {\r
bw.write("[files]");\r
bw.newLine();\r
for (int j = 0; j < files.length; j++) {\r
bw.flush();\r
bw.close();\r
fw.close();\r
- } catch (Exception e) {\r
- throw new BuildException("Generate FV file [" + fvFile.getPath() + "] failed. \n" + e.getMessage());\r
+ } catch (IOException ex) {\r
+ BuildException buildException = new BuildException("Generation of the FV file [" + fvFile.getPath() + "] failed!\n" + ex.getMessage());\r
+ buildException.setStackTrace(ex.getStackTrace());\r
+ throw buildException;\r
+ } catch (EdkException ex) {\r
+ BuildException buildException = new BuildException("Generation of the FV file [" + fvFile.getPath() + "] failed!\n" + ex.getMessage());\r
+ buildException.setStackTrace(ex.getStackTrace());\r
+ throw buildException;\r
}\r
}\r
}\r
/**\r
This method is used for Single Module Build.\r
- \r
- \r
+\r
+\r
@throws BuildException\r
- FPD file is not valid. \r
+ FPD file is not valid.\r
**/\r
- public void parseFpdFile(File fpdFile) throws BuildException {\r
+ public void parseFpdFile(File fpdFile) throws BuildException, EdkException {\r
this.fpdFile = fpdFile;\r
parseFpdFile();\r
+ \r
+ //\r
+ // Call Platform_build.xml prebuild firstly in stand-alone build\r
+ // Prepare BUILD_DIR\r
+ //\r
+ isUnified = OutputManager.getInstance().prepareBuildDir(getProject());\r
+\r
+ String buildDir = getProject().getProperty("BUILD_DIR");\r
+ //\r
+ // For every Target and ToolChain\r
+ //\r
+ String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
+ for (int i = 0; i < targetList.length; i++) {\r
+ String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
+ for(int j = 0; j < toolchainList.length; j++) {\r
+ //\r
+ // Prepare FV_DIR\r
+ //\r
+ String ffsCommonDir = buildDir + File.separatorChar\r
+ + targetList[i] + "_"\r
+ + toolchainList[j];\r
+ File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");\r
+ fvDir.mkdirs();\r
+ }\r
+ }\r
+\r
+ String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml";\r
+ PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile);\r
+ fileGenerator.genBuildFile();\r
+ \r
+ Ant ant = new Ant();\r
+ ant.setProject(getProject());\r
+ ant.setAntfile(platformBuildFile);\r
+ ant.setTarget("prebuild");\r
+ ant.setInheritAll(true);\r
+ ant.init();\r
+ ant.execute();\r
}\r
\r
/**\r
- Parse FPD file. \r
- \r
+ Parse FPD file.\r
+\r
@throws BuildException\r
- FPD file is not valid. \r
+ FPD file is not valid.\r
**/\r
- private void parseFpdFile() throws BuildException {\r
+ void parseFpdFile() throws BuildException {\r
try {\r
XmlObject doc = XmlObject.Factory.parse(fpdFile);\r
- \r
+\r
if (!doc.validate()) {\r
- throw new BuildException("Platform Surface Area file [" + fpdFile.getPath() + "] is invalid.");\r
+ throw new BuildException("Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!");\r
}\r
- \r
+\r
Map<String, XmlObject> map = new HashMap<String, XmlObject>();\r
map.put("PlatformSurfaceArea", doc);\r
- SurfaceAreaQuery.setDoc(map);\r
+ saq = new SurfaceAreaQuery(map);\r
\r
//\r
// Initialize\r
//\r
- platformId = SurfaceAreaQuery.getFpdHeader();\r
+ platformId = saq.getFpdHeader();\r
platformId.setFpdFile(fpdFile);\r
getProject().setProperty("PLATFORM", platformId.getName());\r
getProject().setProperty("PLATFORM_FILE", platformId.getRelativeFpdFile().replaceAll("(\\\\)", "/"));\r
getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
+ \r
+ if( !FrameworkBuildTask.multithread) {\r
+ FrameworkBuildTask.originalProperties.put("PLATFORM", platformId.getName());\r
+ FrameworkBuildTask.originalProperties.put("PLATFORM_FILE", platformId.getRelativeFpdFile().replaceAll("(\\\\)", "/"));\r
+ FrameworkBuildTask.originalProperties.put("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
+ FrameworkBuildTask.originalProperties.put("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
+ }\r
\r
//\r
- // Build mode. User-defined output dir. \r
+ // Build mode. User-defined output dir.\r
//\r
- String buildMode = SurfaceAreaQuery.getFpdIntermediateDirectories();\r
- String userDefinedOutputDir = SurfaceAreaQuery.getFpdOutputDirectory();\r
+ String buildMode = saq.getFpdIntermediateDirectories();\r
+ String userDefinedOutputDir = saq.getFpdOutputDirectory();\r
\r
OutputManager.getInstance().setup(userDefinedOutputDir, buildMode);\r
\r
//\r
// TBD. Deal PCD and BuildOption related Info\r
//\r
- GlobalData.setFpdBuildOptions(SurfaceAreaQuery.getFpdBuildOptions());\r
- \r
- GlobalData.setToolChainPlatformInfo(SurfaceAreaQuery.getFpdToolChainInfo());\r
- \r
+ GlobalData.setFpdBuildOptions(saq.getFpdBuildOptions());\r
+\r
+ GlobalData.setToolChainPlatformInfo(saq.getFpdToolChainInfo());\r
+\r
//\r
// Parse all list modules SA\r
//\r
parseToolChainFamilyOptions();\r
parseToolChainOptions();\r
\r
- SurfaceAreaQuery.setDoc(map);\r
- \r
+ saq.push(map);\r
+\r
//\r
// Pcd Collection. Call CollectPCDAction to collect pcd info.\r
//\r
- try {\r
- CollectPCDAction ca = new CollectPCDAction();\r
- ca.perform(GlobalData.getWorkspacePath(),platformId.getFpdFile().getPath(),ActionMessage.NULL_MESSAGE_LEVEL);\r
- } catch (Exception e){\r
- throw new BuildException(e.getMessage());\r
- }\r
- } catch (Exception e) {\r
- throw new BuildException("Load FPD file [" + fpdFile.getPath() + "] error. \n" + e.getMessage());\r
+ PlatformPcdPreprocessActionForBuilding ca = new PlatformPcdPreprocessActionForBuilding();\r
+ ca.perform(platformId.getFpdFile().getPath(), ActionMessage.NULL_MESSAGE_LEVEL);\r
+ } catch (IOException ex) {\r
+ BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());\r
+ buildException.setStackTrace(ex.getStackTrace());\r
+ throw buildException;\r
+ } catch (XmlException ex) {\r
+ BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());\r
+ buildException.setStackTrace(ex.getStackTrace());\r
+ throw buildException;\r
+ } catch (EdkException ex) {\r
+ BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());\r
+ buildException.setStackTrace(ex.getStackTrace());\r
+ throw buildException;\r
}\r
}\r
\r
-\r
- \r
/**\r
- Parse all modules listed in FPD file. \r
+ Parse all modules listed in FPD file.\r
**/\r
- private void parseModuleSAFiles() throws EdkException{\r
- Map<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = SurfaceAreaQuery.getFpdModules();\r
+ void parseModuleSAFiles() throws EdkException{\r
+ Map<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = saq.getFpdModules();\r
\r
//\r
// For every Module lists in FPD file.\r
Iterator iter = keys.iterator();\r
while (iter.hasNext()) {\r
FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();\r
- \r
+\r
//\r
- // Judge if Module is existed? \r
+ // Judge if Module is existed?\r
// TBD\r
- \r
GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId));\r
\r
//\r
// Put fpdModuleId to the corresponding FV\r
//\r
- SurfaceAreaQuery.push(GlobalData.getDoc(fpdModuleId));\r
- String fvBinding = SurfaceAreaQuery.getModuleFvBindingKeyword();\r
- SurfaceAreaQuery.pop();\r
+ saq.push(GlobalData.getDoc(fpdModuleId));\r
+ String fvBinding = saq.getModuleFvBindingKeyword();\r
\r
fpdModuleId.setFvBinding(fvBinding);\r
- String fvSequence = fpdModuleId.getSequence();\r
- updateFvs(fvSequence, fvBinding, fpdModuleId);\r
- \r
+ updateFvs(fvBinding, fpdModuleId);\r
+\r
//\r
// Prepare for out put file name\r
//\r
ModuleIdentification moduleId = fpdModuleId.getModule();\r
- SurfaceAreaQuery.push(GlobalData.getDoc(fpdModuleId));\r
- String baseName = SurfaceAreaQuery.getModuleOutputFileBasename();\r
- SurfaceAreaQuery.pop();\r
+\r
+ String baseName = saq.getModuleOutputFileBasename();\r
+ \r
if (baseName == null) {\r
baseName = moduleId.getName();\r
}\r
- outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar \r
- + moduleId.getGuid() + "-" + baseName \r
+ outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar\r
+ + moduleId.getGuid() + "-" + baseName\r
+ getSuffix(moduleId.getModuleType()));\r
\r
//\r
// parse module build options, if any\r
- // \r
- SurfaceAreaQuery.push(GlobalData.getDoc(fpdModuleId));\r
+ //\r
GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false));\r
GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true));\r
- SurfaceAreaQuery.pop();\r
+ saq.pop();\r
}\r
}\r
\r
- private ToolChainMap parseModuleBuildOptions(boolean toolChainFamilyFlag) throws EdkException {\r
- String[][] options = SurfaceAreaQuery.getModuleBuildOptions(toolChainFamilyFlag);\r
+ ToolChainMap parseModuleBuildOptions(boolean toolChainFamilyFlag) throws EdkException {\r
+ String[][] options = saq.getModuleBuildOptions(toolChainFamilyFlag);\r
if (options == null || options.length == 0) {\r
- return null;\r
+ return new ToolChainMap();\r
}\r
return parseOptions(options);\r
}\r
- \r
+\r
private ToolChainMap parsePlatformBuildOptions(boolean toolChainFamilyFlag) throws EdkException {\r
- String[][] options = SurfaceAreaQuery.getPlatformBuildOptions(toolChainFamilyFlag);\r
+ String[][] options = saq.getPlatformBuildOptions(toolChainFamilyFlag);\r
if (options == null || options.length == 0) {\r
- return null;\r
+ return new ToolChainMap();\r
}\r
return parseOptions(options);\r
}\r
\r
return map;\r
}\r
- \r
+\r
private void parseToolChainFamilyOptions() throws EdkException {\r
GlobalData.setPlatformToolChainFamilyOption(parsePlatformBuildOptions(true));\r
}\r
}\r
\r
/**\r
- Add the current module to corresponding FV. \r
- \r
+ Add the current module to corresponding FV.\r
+\r
@param fvName current FV name\r
@param moduleName current module identification\r
**/\r
- private void updateFvs(String fvSequence, String fvName, FpdModuleIdentification fpdModuleId) {\r
+ void updateFvs(String fvName, FpdModuleIdentification fpdModuleId) {\r
if (fvName == null || fvName.trim().length() == 0) {\r
fvName = "NULL";\r
}\r
- String upcaseFvName = fvName.toUpperCase();\r
- String[] fvNameArray = upcaseFvName.split("[, \t]+");\r
+ String[] fvNameArray = fvName.split("[, \t]+");\r
for (int i = 0; i < fvNameArray.length; i++) {\r
//\r
// Put module to corresponding fvName\r
if (fvs.containsKey(fvNameArray[i])) {\r
Set<FpdModuleIdentification> set = fvs.get(fvNameArray[i]);\r
set.add(fpdModuleId);\r
- }\r
- else {\r
+ } else {\r
Set<FpdModuleIdentification> set = new LinkedHashSet<FpdModuleIdentification>();\r
set.add(fpdModuleId);\r
fvs.put(fvNameArray[i], set);\r
}\r
- \r
- //\r
- // Put fvName to corresponding fvSequence\r
- //\r
- if (sequences.containsKey(fvSequence)) {\r
- Set<String> set = sequences.get(fvSequence);\r
- set.add(fvNameArray[i]);\r
- }\r
- else {\r
- Set<String> set = new LinkedHashSet<String>();\r
- set.add(fvNameArray[i]);\r
- sequences.put(fvSequence, set);\r
- }\r
}\r
}\r
\r
/**\r
- Get the suffix based on module type. Current relationship are listed: \r
- \r
+ Get the suffix based on module type. Current relationship are listed:\r
+\r
<pre>\r
<b>ModuleType</b> <b>Suffix</b>\r
BASE .FFS\r
UEFI_APPLICATION .APP\r
USER_DEFINED .FFS\r
</pre>\r
- \r
+\r
@param moduleType module type\r
@return\r
@throws BuildException\r
throw new BuildException("Module type is not specified.");\r
}\r
\r
- String[][] suffix = { { "BASE", ".FFS"},\r
- { "SEC", ".SEC" }, { "PEI_CORE", ".PEI" }, \r
- { "PEIM", ".PEI" }, { "DXE_CORE", ".DXE" },\r
- { "DXE_DRIVER", ".DXE" }, { "DXE_RUNTIME_DRIVER", ".DXE" }, \r
- { "DXE_SAL_DRIVER", ".DXE" }, { "DXE_SMM_DRIVER", ".DXE" }, \r
- { "TOOL", ".FFS" }, { "UEFI_DRIVER", ".DXE" },\r
- { "UEFI_APPLICATION", ".APP" }, { "USER_DEFINED", ".FFS" } };\r
- \r
+ String[][] suffix = EdkDefinitions.ModuleTypeExtensions;\r
+\r
for (int i = 0; i < suffix.length; i++) {\r
if (suffix[i][0].equalsIgnoreCase(moduleType)) {\r
return suffix[i][1];\r
return ".FFS";\r
}\r
/**\r
- Add a property. \r
- \r
+ Add a property.\r
+\r
@param p property\r
**/\r
public void addProperty(Property p) {\r
properties.addElement(p);\r
}\r
\r
- public void setPlatformName(String platformName) {\r
- this.platformName = platformName;\r
- }\r
-\r
public void setFpdFile(File fpdFile) {\r
this.fpdFile = fpdFile;\r
}\r
this.type = type;\r
}\r
\r
-\r
+ public String getAllArchForModule(ModuleIdentification moduleId) {\r
+ String archs = "";\r
+ Iterator<FpdModuleIdentification> iter = outfiles.keySet().iterator();\r
+ while (iter.hasNext()) {\r
+ FpdModuleIdentification fpdModuleId = iter.next();\r
+ \r
+ if (fpdModuleId.getModule().equals(moduleId)) {\r
+ archs += fpdModuleId.getArch() + " ";\r
+ }\r
+ }\r
+ \r
+ return archs;\r
+ }\r
+ \r
+ private Set<FpdModuleIdentification> getModuleSequenceForFv(String fvName) throws EdkException {\r
+ Node node = saq.getFpdModuleSequence(fvName);\r
+ Set<FpdModuleIdentification> result = new LinkedHashSet<FpdModuleIdentification>();\r
+ \r
+ if ( node == null) {\r
+ EdkLog.log(this, EdkLog.EDK_WARNING, "FV[" + fvName + "] does not specify module sequence in FPD. Assuming present sequence as default sequence in FV. ");\r
+ return null;\r
+ } else {\r
+ NodeList childNodes = node.getChildNodes();\r
+ for (int i = 0; i < childNodes.getLength(); i++) {\r
+ Node childItem = childNodes.item(i);\r
+ if (childItem.getNodeType() == Node.ELEMENT_NODE) {\r
+ //\r
+ // Find child elements "IncludeModules"\r
+ //\r
+ if (childItem.getNodeName().compareTo("IncludeModules") == 0) {\r
+ //\r
+ // result will be updated\r
+ //\r
+ processNodes(childItem, result);\r
+ } else if (childItem.getNodeName().compareTo("FvName") == 0) {\r
+ \r
+ } else if (childItem.getNodeName().compareTo("InfFileName") == 0) {\r
+ \r
+ } else {\r
+ //\r
+ // Report Warning\r
+ //\r
+ EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised element " + childItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1']");\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ return result;\r
+ }\r
+ \r
+ private void processNodes(Node node, Set<FpdModuleIdentification> result) throws EdkException {\r
+ //\r
+ // Found out all elements "Module"\r
+ //\r
+ NodeList childNodes = node.getChildNodes();\r
+ for (int j = 0; j < childNodes.getLength(); j++) {\r
+ Node childItem = childNodes.item(j);\r
+ if (childItem.getNodeType() == Node.ELEMENT_NODE) {\r
+ if (childItem.getNodeName().compareTo("Module") == 0) {\r
+ String moduleGuid = null;\r
+ String moduleVersion = null;\r
+ String packageGuid = null;\r
+ String packageVersion = null;\r
+ String arch = null;\r
+ \r
+ NamedNodeMap attr = childItem.getAttributes();\r
+ for (int i = 0; i < attr.getLength(); i++) {\r
+ Node attrItem = attr.item(i);\r
+ if (attrItem.getNodeName().compareTo("ModuleGuid") == 0) {\r
+ moduleGuid = attrItem.getNodeValue();\r
+ } else if (attrItem.getNodeName().compareTo("ModuleVersion") == 0) {\r
+ moduleVersion = attrItem.getNodeValue();\r
+ } else if (attrItem.getNodeName().compareTo("PackageGuid") == 0) {\r
+ packageGuid = attrItem.getNodeValue();\r
+ } else if (attrItem.getNodeName().compareTo("PackageVersion") == 0) {\r
+ packageVersion = attrItem.getNodeValue();\r
+ } else if (attrItem.getNodeName().compareTo("Arch") == 0) {\r
+ arch = attrItem.getNodeValue();\r
+ } else {\r
+ //\r
+ // Report warning\r
+ //\r
+ EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised attribute " + attrItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules.Module");\r
+ }\r
+ }\r
+ \r
+ PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);\r
+ GlobalData.refreshPackageIdentification(packageId);\r
+ \r
+ ModuleIdentification moduleId = new ModuleIdentification(moduleGuid, moduleVersion);\r
+ moduleId.setPackage(packageId);\r
+ GlobalData.refreshModuleIdentification(moduleId);\r
+ \r
+ if (arch == null) {\r
+ throw new EdkException("Attribute [Arch] is required for element FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules.Module. ");\r
+ }\r
+ \r
+ result.add(new FpdModuleIdentification(moduleId, arch));\r
+ } else {\r
+ //\r
+ // Report Warning\r
+ //\r
+ EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised element " + childItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules");\r
+ }\r
+ }\r
+ }\r
+ }\r
}\r