/** @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.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.Property;\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.pcd.action.ActionMessage;\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.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
\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
+\r
<p>The method parseFpdFile is also prepared for single module build. </p>\r
- \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
-\r
@since GenBuild 1.0\r
**/\r
public class FpdParserTask extends Task {\r
- \r
+\r
private String platformName;\r
\r
private File fpdFile = null;\r
- \r
+\r
private PlatformIdentification platformId;\r
- \r
- ///\r
- /// \r
- ///\r
+\r
private String type;\r
- \r
+\r
///\r
/// Mapping from modules identification to out put file name\r
///\r
private 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
+ private 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
+ //\r
+ // If fpdFile is not specified, \r
+ // then try to get FPD file by platformName\r
+ //\r
if ( fpdFile == null) {\r
if (platformName == null) {\r
- throw new BuildException("FpdParserTask parameter error. Please specify platform name or FPD file. ");\r
+ throw new BuildException("FpdParserTask parameter error. Please specify either the platform name or FPD file!");\r
}\r
platformId = GlobalData.getPlatformByName(platformName);\r
fpdFile = platformId.getFpdFile();\r
}\r
- \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
//\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 = getProject().getProperty("BUILD_DIR") + File.separatorChar\r
+ + targetList[i] + File.separatorChar\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
+ PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified);\r
fileGenerator.genBuildFile();\r
- \r
+\r
//\r
// Ant call ${PLATFORM}_build.xml\r
//\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.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
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
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
}\r
bw.newLine();\r
}\r
- \r
+\r
//\r
// Attributes;\r
//\r
}\r
bw.newLine();\r
}\r
- \r
+\r
//\r
// Components\r
//\r
}\r
bw.newLine();\r
}\r
- \r
+\r
//\r
// Files\r
//\r
- Set<FpdModuleIdentification> filesSet = fvs.get(validFv[i].toUpperCase());\r
+ Set<FpdModuleIdentification> filesSet = fvs.get(validFv[i]);\r
if (filesSet != null) {\r
FpdModuleIdentification[] files = filesSet.toArray(new FpdModuleIdentification[filesSet.size()]);\r
bw.write("[files]");\r
bw.close();\r
fw.close();\r
} catch (Exception e) {\r
- throw new BuildException("Generate FV file [" + fvFile.getPath() + "] failed. \n" + e.getMessage());\r
+ throw new BuildException("Generation of the FV file [" + fvFile.getPath() + "] failed!\n" + e.getMessage());\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
this.fpdFile = fpdFile;\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
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
getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\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
// TBD. Deal PCD and BuildOption related Info\r
//\r
GlobalData.setFpdBuildOptions(SurfaceAreaQuery.getFpdBuildOptions());\r
- \r
+\r
GlobalData.setToolChainPlatformInfo(SurfaceAreaQuery.getFpdToolChainInfo());\r
- \r
+\r
//\r
// Parse all list modules SA\r
//\r
parseToolChainOptions();\r
\r
SurfaceAreaQuery.setDoc(map);\r
- \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
+ PlatformPcdPreprocessActionForBuilding ca = new PlatformPcdPreprocessActionForBuilding();\r
+ ca.perform(platformId.getFpdFile().getPath(), ActionMessage.NULL_MESSAGE_LEVEL);\r
} catch (Exception e) {\r
- throw new BuildException("Load FPD file [" + fpdFile.getPath() + "] error. \n" + e.getMessage());\r
+ throw new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + e.getMessage());\r
}\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
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
+\r
GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId));\r
\r
//\r
//\r
SurfaceAreaQuery.push(GlobalData.getDoc(fpdModuleId));\r
String fvBinding = SurfaceAreaQuery.getModuleFvBindingKeyword();\r
- SurfaceAreaQuery.pop();\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
+\r
String baseName = SurfaceAreaQuery.getModuleOutputFileBasename();\r
- SurfaceAreaQuery.pop();\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
}\r
return parseOptions(options);\r
}\r
- \r
+\r
private ToolChainMap parsePlatformBuildOptions(boolean toolChainFamilyFlag) throws EdkException {\r
String[][] options = SurfaceAreaQuery.getPlatformBuildOptions(toolChainFamilyFlag);\r
if (options == null || options.length == 0) {\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
+ private 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
public void setType(String type) {\r
this.type = type;\r
}\r
- \r
-\r
}\r