X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=Tools%2FSource%2FGenBuild%2Forg%2Ftianocore%2Fbuild%2Ffpd%2FFpdParserTask.java;h=b496e32ed5de3ea933167369a1b7573bbc15bb45;hp=011e13de527af8a867d0d7b7f3dfc8a5809e32f9;hb=f6390d375c84a8dd7adbc2c76381b6bd41e256d8;hpb=7db4ab705a654e2202b083968e92d5b552007d6b diff --git a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java index 011e13de52..b496e32ed5 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java +++ b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java @@ -1,23 +1,24 @@ /** @file - This file is ANT task FpdParserTask. - - FpdParserTask is used to parse FPD (Framework Platform Description) and generate - build.out.xml. It is for Package or Platform build use. - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ + This file is ANT task FpdParserTask. + + FpdParserTask is used to parse FPD (Framework Platform Description) and generate + build.out.xml. It is for Package or Platform build use. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + **/ package org.tianocore.build.fpd; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; +import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -26,174 +27,195 @@ import java.util.Map; import java.util.Set; import java.util.Vector; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.Ant; import org.apache.tools.ant.taskdefs.Property; +import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; -import org.w3c.dom.Comment; -import org.w3c.dom.Document; -import org.w3c.dom.Element; +import org.tianocore.common.definitions.EdkDefinitions; +import org.tianocore.common.exception.EdkException; +import org.tianocore.common.logger.EdkLog; +import org.tianocore.pcd.action.ActionMessage; +import org.tianocore.build.FrameworkBuildTask; import org.tianocore.build.global.GlobalData; import org.tianocore.build.global.OutputManager; -import org.tianocore.build.global.OverrideProcess; import org.tianocore.build.global.SurfaceAreaQuery; -import org.tianocore.build.pcd.action.CollectPCDAction; -import org.tianocore.build.pcd.action.ActionMessage; -import org.tianocore.BuildOptionsDocument; -import org.tianocore.FrameworkPlatformDescriptionDocument; -import org.tianocore.ModuleSADocument; - +import org.tianocore.build.id.FpdModuleIdentification; +import org.tianocore.build.id.ModuleIdentification; +import org.tianocore.build.id.PackageIdentification; +import org.tianocore.build.id.PlatformIdentification; +import org.tianocore.build.pcd.action.PlatformPcdPreprocessActionForBuilding; +import org.tianocore.build.toolchain.ToolChainAttribute; +import org.tianocore.build.toolchain.ToolChainElement; +import org.tianocore.build.toolchain.ToolChainMap; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** - FpdParserTask is an ANT task. The main function is parsing FPD - XML file and generating its ANT build script for Platform or Package. - -

The usage is (take NT32 Platform for example):

- -
-    <FPDParser fpdfilename="Build\Nt32.fpd" />
-  
- -

The task will initialize all information through parsing Framework Database, - SPD, Tool chain configuration files.

- + FpdParserTask is an ANT task. The main function is parsing Framework + Platform Descritpion (FPD) XML file and generating its ANT build script for + corresponding platform. + +

The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR + and BUILD_DIR.

+ +

The task generates ${PLATFORM}_build.xml file which will be called by top level + build.xml. The task also generate Fv.inf files (File is for Tool GenFvImage).

+ +

FpdParserTask task stores all FPD information to GlobalData. And parse + tools definition file to set up compiler options for different Target and + different ToolChainTag.

+ +

The method parseFpdFile is also prepared for single module build.

+ @since GenBuild 1.0 **/ public class FpdParserTask extends Task { - /// - /// FV dir: ${PLATFORM_DIR}/Build/FV - /// - public static final String FV_OUTPUT_DIR = "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "FV"; - - private File fpdFilename; + private File fpdFile = null; - private File guiddatabase; + PlatformIdentification platformId; - /// - /// Keep platform buildoption information - /// - public static XmlObject platformBuildOptions = null; + private String type; /// /// Mapping from modules identification to out put file name /// - private Map outfiles = new LinkedHashMap(); + Map outfiles = new LinkedHashMap(); /// /// Mapping from FV name to its modules /// - private Map > fvs = new HashMap >(); + Map> fvs = new HashMap>(); /// - /// Mapping from sequence number to its modules - /// - private Map > sequences = new HashMap >(); - - /// - /// FpdParserTask can specify some ANT properties. + /// FpdParserTask can specify some ANT properties. /// private Vector properties = new Vector(); - private String info = "====================================================================\n" - + "DO NOT EDIT \n" - + "File auto-generated by build utility\n" - + "\n" - + "Abstract:\n" - + "Auto-generated ANT build file for building of EFI Modules/Platforms\n" - + "====================================================================="; + SurfaceAreaQuery saq = null; + + boolean isUnified = true; /** Public construct method. It is necessary for ANT task. **/ - public FpdParserTask () { + public FpdParserTask() { } /** - ANT task's entry method. The main steps is described as following: - -
    -
  • Initialize global information (Framework DB, SPD files and all MSA files - listed in SPD). This step will execute only once in whole build process;
  • -
  • Parse specified FPD file;
  • -
  • Generate FV.inf files;
  • -
  • Generate build.out.xml file for Flatform or Package build;
  • -
  • Collect PCD information.
  • -
- - @throws BuildException - Surface area is not valid. + ANT task's entry method. The main steps is described as following: + +
    +
  • Initialize global information (Framework DB, SPD files and all MSA files + listed in SPD). This step will execute only once in whole build process;
  • +
  • Parse specified FPD file;
  • +
  • Generate FV.inf files;
  • +
  • Generate PlatformName_build.xml file for Flatform build;
  • +
  • Collect PCD information.
  • +
+ + @throws BuildException + Surface area is not valid. **/ public void execute() throws BuildException { - OutputManager.update(getProject()); - // - // Parse DB and SPDs files. Initialize Global Data - // - GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db", getProject() - .getProperty("WORKSPACE_DIR")); + this.setTaskName("FpdParser"); + // // Parse FPD file // parseFpdFile(); + // - // Gen Fv.inf files + // Prepare BUILD_DIR // - genFvInfFiles(); + isUnified = OutputManager.getInstance().prepareBuildDir(getProject()); + + String buildDir = getProject().getProperty("BUILD_DIR"); + // + // For every Target and ToolChain + // + String[] targetList = GlobalData.getToolChainInfo().getTargets(); + for (int i = 0; i < targetList.length; i++) { + String[] toolchainList = GlobalData.getToolChainInfo().getTagnames(); + for(int j = 0; j < toolchainList.length; j++) { + // + // Prepare FV_DIR + // + String ffsCommonDir = buildDir + File.separatorChar + + targetList[i] + "_" + + toolchainList[j]; + File fvDir = new File(ffsCommonDir + File.separatorChar + "FV"); + fvDir.mkdirs(); + getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/")); + + // + // Gen Fv.inf files + // + genFvInfFiles(ffsCommonDir); + } + } + // // Gen build.xml // - genBuildFile(); + String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml"; + PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile); + fileGenerator.genBuildFile(); + + // + // Ant call ${PLATFORM}_build.xml // - // Collect PCD information - // - collectPCDInformation (); + Ant ant = new Ant(); + ant.setProject(getProject()); + ant.setAntfile(platformBuildFile); + ant.setTarget(type); + ant.setInheritAll(true); + ant.init(); + ant.execute(); } - + /** - Generate Fv.inf files. The Fv.inf file is composed with four - parts: Options, Attributes, Components and Files. The Fv.inf files - will be under ${PLATFOMR_DIR}\Build\Fv. - + Generate Fv.inf files. The Fv.inf file is composed with four + parts: Options, Attributes, Components and Files. The Fv.inf files + will be under FV_DIR. + @throws BuildException - File write FV.inf files error. + File write FV.inf files error. **/ - private void genFvInfFiles() throws BuildException{ - String[] validFv = SurfaceAreaQuery.getFpdValidImageNames(); + void genFvInfFiles(String ffsCommonDir) throws BuildException { + String[] validFv = saq.getFpdValidImageNames(); for (int i = 0; i < validFv.length; i++) { - getProject().setProperty("FV_FILENAME", validFv[i].toUpperCase()); // // Get all global variables from FPD and set them to properties // - String[][] globalVariables = SurfaceAreaQuery - .getFpdGlobalVariable(); + String[][] globalVariables = saq.getFpdGlobalVariable(); for (int j = 0; j < globalVariables.length; j++) { - getProject().setProperty(globalVariables[j][0], - globalVariables[j][1]); + getProject().setProperty(globalVariables[j][0], globalVariables[j][1]); } - File fvFile = new File(getProject().replaceProperties( - FV_OUTPUT_DIR + File.separatorChar + validFv[i].toUpperCase() - + ".inf")); + getProject().setProperty("FV_FILENAME", validFv[i]); + + File fvFile = new File(getProject().replaceProperties( getProject().getProperty("FV_DIR") + File.separatorChar + validFv[i] + ".inf")); + if (fvFile.exists() && (fvFile.lastModified() >= fpdFile.lastModified())) { + // + // don't re-generate FV.inf if fpd has not been changed + // + continue; + } fvFile.getParentFile().mkdirs(); try { FileWriter fw = new FileWriter(fvFile); BufferedWriter bw = new BufferedWriter(fw); + // // Options // - String[][] options = SurfaceAreaQuery.getFpdOptions(validFv[i]); + String[][] options = saq.getFpdOptions(validFv[i]); if (options.length > 0) { bw.write("[options]"); bw.newLine(); @@ -210,11 +232,11 @@ public class FpdParserTask extends Task { } bw.newLine(); } + // // Attributes; // - String[][] attributes = SurfaceAreaQuery - .getFpdAttributes(validFv[i]); + String[][] attributes = saq.getFpdAttributes(validFv[i]); if (attributes.length > 0) { bw.write("[attributes]"); bw.newLine(); @@ -226,18 +248,16 @@ public class FpdParserTask extends Task { } str.append("= "); str.append(attributes[j][1]); - bw - .write(getProject().replaceProperties( - str.toString())); + bw.write(getProject().replaceProperties(str.toString())); bw.newLine(); } bw.newLine(); } + // // Components // - String[][] components = SurfaceAreaQuery - .getFpdComponents(validFv[i]); + String[][] components = saq.getFpdComponents(validFv[i]); if (components.length > 0) { bw.write("[components]"); bw.newLine(); @@ -249,558 +269,489 @@ public class FpdParserTask extends Task { } str.append("= "); str.append(components[j][1]); - bw - .write(getProject().replaceProperties( - str.toString())); + bw.write(getProject().replaceProperties(str.toString())); bw.newLine(); } bw.newLine(); } + // // Files // - Set filesSet = fvs.get(validFv[i].toUpperCase()); - if (filesSet != null) { - FpdModuleIdentification[] files = filesSet.toArray(new FpdModuleIdentification[filesSet - .size()]); + Set moduleSeqSet = getModuleSequenceForFv(validFv[i]); + + Set filesSet = fvs.get(validFv[i]); + + FpdModuleIdentification[] files = null; + + if (moduleSeqSet == null) { + if (filesSet != null) { + files = filesSet.toArray(new FpdModuleIdentification[filesSet.size()]); + } + } else if (filesSet == null) { + if (moduleSeqSet.size() != 0) { + throw new BuildException("Can not find any modules belongs to FV[" + validFv[i] + "], but listed some in BuildOptions.UserExtensions[@UserID='IMAGES' @Identifier='1']"); + } + } else { + // + // if moduleSeqSet and filesSet is inconsistent, report error + // + if(moduleSeqSet.size() != filesSet.size()){ + throw new BuildException("Modules for FV[" + validFv[i] + "] defined in FrameworkModules and in BuildOptions.UserExtensions[@UserID='IMAGES' @Identifier='1'] are inconsistent. "); + } else { + // + // whether all modules in moduleSeqSet listed in filesSet + // + Iterator iter = moduleSeqSet.iterator(); + while (iter.hasNext()) { + FpdModuleIdentification item = iter.next(); + if (!filesSet.contains(item)) { + throw new BuildException("Can not find " + item + " belongs to FV[" + validFv[i] + "]"); + } + } + } + + files = moduleSeqSet.toArray(new FpdModuleIdentification[moduleSeqSet.size()]); + } + + + if (files != null) { bw.write("[files]"); bw.newLine(); for (int j = 0; j < files.length; j++) { - String str = outfiles.get(files[j]); - bw.write(getProject().replaceProperties( - "EFI_FILE_NAME = " + str)); + String str = ffsCommonDir + File.separatorChar + outfiles.get(files[j]); + bw.write(getProject().replaceProperties("EFI_FILE_NAME = " + str)); bw.newLine(); } } bw.flush(); bw.close(); fw.close(); - } catch (Exception e) { - throw new BuildException("Generate Fv.inf file failed. \n" + e.getMessage()); + } catch (IOException ex) { + BuildException buildException = new BuildException("Generation of the FV file [" + fvFile.getPath() + "] failed!\n" + ex.getMessage()); + buildException.setStackTrace(ex.getStackTrace()); + throw buildException; + } catch (EdkException ex) { + BuildException buildException = new BuildException("Generation of the FV file [" + fvFile.getPath() + "] failed!\n" + ex.getMessage()); + buildException.setStackTrace(ex.getStackTrace()); + throw buildException; } } } - /** - Parse FPD file. - + This method is used for Single Module Build. + + @throws BuildException - FPD file is not valid. + FPD file is not valid. **/ - private void parseFpdFile() throws BuildException { + public void parseFpdFile(File fpdFile) throws BuildException, EdkException { + this.fpdFile = fpdFile; + parseFpdFile(); + + // + // Call Platform_build.xml prebuild firstly in stand-alone build + // Prepare BUILD_DIR + // + isUnified = OutputManager.getInstance().prepareBuildDir(getProject()); + + String buildDir = getProject().getProperty("BUILD_DIR"); + // + // For every Target and ToolChain + // + String[] targetList = GlobalData.getToolChainInfo().getTargets(); + for (int i = 0; i < targetList.length; i++) { + String[] toolchainList = GlobalData.getToolChainInfo().getTagnames(); + for(int j = 0; j < toolchainList.length; j++) { + // + // Prepare FV_DIR + // + String ffsCommonDir = buildDir + File.separatorChar + + targetList[i] + "_" + + toolchainList[j]; + File fvDir = new File(ffsCommonDir + File.separatorChar + "FV"); + fvDir.mkdirs(); + } + } + + String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml"; + PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile); + fileGenerator.genBuildFile(); + + Ant ant = new Ant(); + ant.setProject(getProject()); + ant.setAntfile(platformBuildFile); + ant.setTarget("prebuild"); + ant.setInheritAll(true); + ant.init(); + ant.execute(); + } + + /** + Parse FPD file. + + @throws BuildException + FPD file is not valid. + **/ + void parseFpdFile() throws BuildException { try { - FrameworkPlatformDescriptionDocument doc = (FrameworkPlatformDescriptionDocument) XmlObject.Factory - .parse(fpdFilename); - if ( ! doc.validate() ){ - throw new BuildException("FPD file is invalid."); + XmlObject doc = XmlObject.Factory.parse(fpdFile); + + if (!doc.validate()) { + throw new BuildException("Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!"); } - platformBuildOptions = doc.getFrameworkPlatformDescription() - .getBuildOptions(); - HashMap map = new HashMap(); - map.put("FrameworkPlatformDescription", doc); - SurfaceAreaQuery.setDoc(map); + + Map map = new HashMap(); + map.put("PlatformSurfaceArea", doc); + saq = new SurfaceAreaQuery(map); + + // + // Initialize + // + platformId = saq.getFpdHeader(); + platformId.setFpdFile(fpdFile); + getProject().setProperty("PLATFORM", platformId.getName()); + getProject().setProperty("PLATFORM_FILE", platformId.getRelativeFpdFile().replaceAll("(\\\\)", "/")); + getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/")); + getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/")); + + if( !FrameworkBuildTask.multithread) { + FrameworkBuildTask.originalProperties.put("PLATFORM", platformId.getName()); + FrameworkBuildTask.originalProperties.put("PLATFORM_FILE", platformId.getRelativeFpdFile().replaceAll("(\\\\)", "/")); + FrameworkBuildTask.originalProperties.put("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/")); + FrameworkBuildTask.originalProperties.put("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/")); + } + + // + // Build mode. User-defined output dir. + // + String buildMode = saq.getFpdIntermediateDirectories(); + String userDefinedOutputDir = saq.getFpdOutputDirectory(); + + OutputManager.getInstance().setup(userDefinedOutputDir, buildMode); + + // + // TBD. Deal PCD and BuildOption related Info + // + GlobalData.setFpdBuildOptions(saq.getFpdBuildOptions()); + + GlobalData.setToolChainPlatformInfo(saq.getFpdToolChainInfo()); + // // Parse all list modules SA // parseModuleSAFiles(); - SurfaceAreaQuery.setDoc(map); - } catch (Exception e) { - throw new BuildException("Load FPD file [" + fpdFilename.getPath() - + "] error. \n" + e.getMessage()); + + // + // TBD. Deal PCD and BuildOption related Info + // + parseToolChainFamilyOptions(); + parseToolChainOptions(); + + saq.push(map); + + // + // Pcd Collection. Call CollectPCDAction to collect pcd info. + // + PlatformPcdPreprocessActionForBuilding ca = new PlatformPcdPreprocessActionForBuilding(); + ca.perform(platformId.getFpdFile().getPath(), ActionMessage.NULL_MESSAGE_LEVEL); + } catch (IOException ex) { + BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage()); + buildException.setStackTrace(ex.getStackTrace()); + throw buildException; + } catch (XmlException ex) { + BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage()); + buildException.setStackTrace(ex.getStackTrace()); + throw buildException; + } catch (EdkException ex) { + BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage()); + buildException.setStackTrace(ex.getStackTrace()); + throw buildException; } } /** - Parse all modules listed in FPD file. + Parse all modules listed in FPD file. **/ - private void parseModuleSAFiles() { - ModuleSADocument.ModuleSA[] moduleSAs = SurfaceAreaQuery - .getFpdModules(); + void parseModuleSAFiles() throws EdkException{ + Map> moduleSAs = saq.getFpdModules(); + // // For every Module lists in FPD file. // - for (int i = 0; i < moduleSAs.length; i++) { - String defaultFv = "NULL"; - String defaultArch = "IA32"; - String baseName = moduleSAs[i].getModuleName(); - if (baseName == null) { - System.out.println("Warning: Module Name is not specified."); - continue; - } - String fvBinding = moduleSAs[i].getFvBinding(); + Set keys = moduleSAs.keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()) { + FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next(); + // - // If the module do not specify any FvBinding, use the default value. - // Else update the default FvBinding value to this value. + // Judge if Module is existed? + // TBD + GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId)); + // - if (fvBinding == null) { - fvBinding = defaultFv; - } - else { - defaultFv = fvBinding; - } - String arch; + // Put fpdModuleId to the corresponding FV // - // If the module do not specify any Arch, use the default value. - // Else update the default Arch value to this value. + saq.push(GlobalData.getDoc(fpdModuleId)); + String fvBinding = saq.getModuleFvBindingKeyword(); + + fpdModuleId.setFvBinding(fvBinding); + updateFvs(fvBinding, fpdModuleId); + // - if (moduleSAs[i].getArch() == null ){ - arch = defaultArch; - } - else { - arch = moduleSAs[i].getArch().toString(); - defaultArch = arch; + // Prepare for out put file name + // + ModuleIdentification moduleId = fpdModuleId.getModule(); + + String baseName = saq.getModuleOutputFileBasename(); + + if (baseName == null) { + baseName = moduleId.getName(); } - Map msaMap = GlobalData.getNativeMsa(baseName); - Map mbdMap = GlobalData.getNativeMbd(baseName); - Map map = new HashMap(); + outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar + + moduleId.getGuid() + "-" + baseName + + getSuffix(moduleId.getModuleType())); + // - // Whether the Module SA has parsed before or not + // parse module build options, if any // - if (!GlobalData.isModuleParsed(baseName)) { - OverrideProcess op = new OverrideProcess(); - // - // using overriding rules - // Here we can also put platform Build override - // - map = op.override(mbdMap, msaMap); - Map overrideMap = op.override( - getPlatformOverrideInfo(moduleSAs[i]), - OverrideProcess.deal(map)); - GlobalData.registerModule(baseName, overrideMap); - } else { - map = GlobalData.getDoc(baseName); + GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false)); + GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true)); + saq.pop(); + } + } + + ToolChainMap parseModuleBuildOptions(boolean toolChainFamilyFlag) throws EdkException { + String[][] options = saq.getModuleBuildOptions(toolChainFamilyFlag); + if (options == null || options.length == 0) { + return new ToolChainMap(); + } + return parseOptions(options); + } + + private ToolChainMap parsePlatformBuildOptions(boolean toolChainFamilyFlag) throws EdkException { + String[][] options = saq.getPlatformBuildOptions(toolChainFamilyFlag); + if (options == null || options.length == 0) { + return new ToolChainMap(); + } + return parseOptions(options); + } + + private ToolChainMap parseOptions(String[][] options) throws EdkException { + ToolChainMap map = new ToolChainMap(); + int flagIndex = ToolChainElement.ATTRIBUTE.value; + + for (int i = 0; i < options.length; ++i) { + String flagString = options[i][flagIndex]; + if (flagString == null) { + flagString = ""; } - SurfaceAreaQuery.setDoc(map); - String guid = SurfaceAreaQuery.getModuleGuid(); - String componentType = SurfaceAreaQuery.getComponentType(); - FpdModuleIdentification moduleId = new FpdModuleIdentification(baseName, guid, arch); - updateFvs(fvBinding, moduleId); - outfiles.put(moduleId, "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar - + "${TARGET}" + File.separatorChar + arch - + File.separatorChar + guid + "-" + baseName - + getSuffix(componentType)); + options[i][flagIndex] = ToolChainAttribute.FLAGS + ""; + map.put(options[i], flagString.trim()); } + + return map; + } + + private void parseToolChainFamilyOptions() throws EdkException { + GlobalData.setPlatformToolChainFamilyOption(parsePlatformBuildOptions(true)); + } + + private void parseToolChainOptions() throws EdkException { + GlobalData.setPlatformToolChainOption(parsePlatformBuildOptions(false)); } /** - Add the current module to corresponding FV. - + Add the current module to corresponding FV. + @param fvName current FV name @param moduleName current module identification **/ - private void updateFvs(String fvName, FpdModuleIdentification moduleName) { - String upcaseFvName = fvName.toUpperCase(); - if (fvs.containsKey(upcaseFvName)) { - Set set = fvs.get(upcaseFvName); - set.add(moduleName); - } else { - Set set = new LinkedHashSet(); - set.add(moduleName); - fvs.put(upcaseFvName, set); + void updateFvs(String fvName, FpdModuleIdentification fpdModuleId) { + if (fvName == null || fvName.trim().length() == 0) { + fvName = "NULL"; + } + String[] fvNameArray = fvName.split("[, \t]+"); + for (int i = 0; i < fvNameArray.length; i++) { + // + // Put module to corresponding fvName + // + if (fvs.containsKey(fvNameArray[i])) { + Set set = fvs.get(fvNameArray[i]); + set.add(fpdModuleId); + } else { + Set set = new LinkedHashSet(); + set.add(fpdModuleId); + fvs.put(fvNameArray[i], set); + } } } /** - Get the suffix based on component type. Current relationship are listed: - + Get the suffix based on module type. Current relationship are listed: +
-        ComponentType   Suffix
-           APPLICATION          .APP
-           SEC                  .SEC
-           PEI_CORE             .PEI
-           PE32_PEIM            .PEI
-           RELOCATABLE_PEIM     .PEI
-           PIC_PEIM             .PEI
-           COMBINED_PEIM_DRIVER .PEI
-           TE_PEIM              .PEI
-           LOGO                 .FFS
-           others               .DXE
+      ModuleType     Suffix
+      BASE                 .FFS
+      SEC                  .SEC
+      PEI_CORE             .PEI
+      PEIM                 .PEI
+      DXE_CORE             .DXE
+      DXE_DRIVER           .DXE
+      DXE_RUNTIME_DRIVER   .DXE
+      DXE_SAL_DRIVER       .DXE
+      DXE_SMM_DRIVER       .DXE
+      TOOL                 .FFS
+      UEFI_DRIVER          .DXE
+      UEFI_APPLICATION     .APP
+      USER_DEFINED         .FFS
       
- - @param componentType component type + + @param moduleType module type @return @throws BuildException - If component type is null + If module type is null **/ - public static String getSuffix(String componentType) throws BuildException{ - if (componentType == null) { - throw new BuildException("Component type is not specified."); + public static String getSuffix(String moduleType) throws BuildException { + if (moduleType == null) { + throw new BuildException("Module type is not specified."); } - String str = ".DXE"; - if (componentType.equalsIgnoreCase("APPLICATION")) { - str = ".APP"; - } else if (componentType.equalsIgnoreCase("SEC")) { - str = ".SEC"; - } else if (componentType.equalsIgnoreCase("PEI_CORE")) { - str = ".PEI"; - } else if (componentType.equalsIgnoreCase("PE32_PEIM")) { - str = ".PEI"; - } else if (componentType.equalsIgnoreCase("RELOCATABLE_PEIM")) { - str = ".PEI"; - } else if (componentType.equalsIgnoreCase("PIC_PEIM")) { - str = ".PEI"; - } else if (componentType.equalsIgnoreCase("COMBINED_PEIM_DRIVER")) { - str = ".PEI"; - } else if (componentType.equalsIgnoreCase("TE_PEIM")) { - str = ".PEI"; - } else if (componentType.equalsIgnoreCase("LOGO")) { - str = ".FFS"; - } - return str; - } - /** - Parse module surface are info described in FPD file and put them into map. - - @param sa module surface area info descibed in FPD file - @return map list with top level elements - **/ - private Map getPlatformOverrideInfo( - ModuleSADocument.ModuleSA sa) { - Map map = new HashMap(); - map.put("SourceFiles", sa.getSourceFiles()); - map.put("Includes", sa.getIncludes()); - map.put("Libraries", sa.getLibraries()); - map.put("Protocols", sa.getProtocols()); - map.put("Events", sa.getEvents()); - map.put("Hobs", sa.getHobs()); - map.put("PPIs", sa.getPPIs()); - map.put("Variables", sa.getVariables()); - map.put("BootModes", sa.getBootModes()); - map.put("SystemTables", sa.getSystemTables()); - map.put("DataHubs", sa.getDataHubs()); - map.put("Formsets", sa.getFormsets()); - map.put("Guids", sa.getGuids()); - map.put("Externs", sa.getExterns()); - map.put("BuildOptions", platformBuildOptions); - return map; - } + String[][] suffix = EdkDefinitions.ModuleTypeExtensions; - /** - Generate build.out.xml file. - - @throws BuildException - build.out.xml XML document create error - **/ - private void genBuildFile() throws BuildException { - DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance(); - try { - DocumentBuilder dombuilder = domfac.newDocumentBuilder(); - Document document = dombuilder.newDocument(); - Comment rootComment = document.createComment(info); - // - // create root element and its attributes - // - Element root = document.createElement("project"); - root.setAttribute("name", getProject().getProperty("PLATFORM")); - root.setAttribute("default", "main"); - root.setAttribute("basedir", "."); - // - // element for External ANT tasks - // - root.appendChild(document.createComment("Apply external ANT tasks")); - Element ele = document.createElement("taskdef"); - ele.setAttribute("resource", "GenBuild.tasks"); - root.appendChild(ele); - - ele = document.createElement("taskdef"); - ele.setAttribute("resource", "frameworktasks.tasks"); - root.appendChild(ele); - - ele = document.createElement("property"); - ele.setAttribute("environment", "env"); - root.appendChild(ele); - // - // Default Target - // - root.appendChild(document.createComment("Default target")); - ele = document.createElement("target"); - ele.setAttribute("name", "main"); - ele.setAttribute("depends", "modules, fvs"); - root.appendChild(ele); - // - // Modules Target - // - root.appendChild(document.createComment("Modules target")); - ele = document.createElement("target"); - ele.setAttribute("name", "modules"); - - Set set = outfiles.keySet(); - Iterator iter = set.iterator(); - while (iter.hasNext()) { - FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next(); - String baseName = moduleId.getBaseName(); - Element moduleEle = document.createElement("ant"); - moduleEle.setAttribute("antfile", GlobalData - .getModulePath(baseName) - + File.separatorChar + "build.xml"); - moduleEle.setAttribute("target", baseName); - // - // ARCH - // - Element property = document.createElement("property"); - property.setAttribute("name", "ARCH"); - property.setAttribute("value", moduleId.getArch()); - moduleEle.appendChild(property); - // - // PACKAGE_DIR - // - property = document.createElement("property"); - property.setAttribute("name", "PACKAGE_DIR"); - property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar - + GlobalData.getPackagePathForModule(baseName)); - moduleEle.appendChild(property); - // - // PACKAGE - // - property = document.createElement("property"); - property.setAttribute("name", "PACKAGE"); - property.setAttribute("value", GlobalData - .getPackageNameForModule(baseName)); - moduleEle.appendChild(property); - ele.appendChild(moduleEle); - } - root.appendChild(ele); - // - // FVS Target - // - root.appendChild(document.createComment("FVs target")); - ele = document.createElement("target"); - ele.setAttribute("name", "fvs"); - - String[] validFv = SurfaceAreaQuery.getFpdValidImageNames(); - for (int i = 0; i < validFv.length; i++) { - String inputFile = FV_OUTPUT_DIR + "" + File.separatorChar - + validFv[i].toUpperCase() + ".inf"; - Element fvEle = document.createElement("genfvimage"); - fvEle.setAttribute("infFile", inputFile); - ele.appendChild(fvEle); - Element moveEle = document.createElement("move"); - moveEle.setAttribute("file", validFv[i].toUpperCase() + ".fv"); - moveEle.setAttribute("todir", FV_OUTPUT_DIR); - ele.appendChild(moveEle); - } - root.appendChild(ele); - - boolean isUnified = false; - BuildOptionsDocument.BuildOptions buildOptions = (BuildOptionsDocument.BuildOptions)platformBuildOptions; - if (buildOptions.getOutputDirectory() != null){ - if (buildOptions.getOutputDirectory().getIntermediateDirectories() != null){ - if (buildOptions.getOutputDirectory().getIntermediateDirectories().toString().equalsIgnoreCase("UNIFIED")){ - isUnified = true; - } - } + for (int i = 0; i < suffix.length; i++) { + if (suffix[i][0].equalsIgnoreCase(moduleType)) { + return suffix[i][1]; } - // - // Clean Target - // - root.appendChild(document.createComment("Clean target")); - ele = document.createElement("target"); - ele.setAttribute("name", "clean"); - - if (isUnified) { - Element cleanEle = document.createElement("delete"); - cleanEle.setAttribute("includeemptydirs", "true"); - Element filesetEle = document.createElement("fileset"); - filesetEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}"); - filesetEle.setAttribute("includes", "**/OUTPUT/**"); - cleanEle.appendChild(filesetEle); - ele.appendChild(cleanEle); - } - else { - set = outfiles.keySet(); - iter = set.iterator(); - while (iter.hasNext()) { - FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next(); - String baseName = moduleId.getBaseName(); - - Element ifEle = document.createElement("if"); - Element availableEle = document.createElement("available"); - availableEle.setAttribute("file", GlobalData - .getModulePath(baseName) - + File.separatorChar + "build.xml"); - ifEle.appendChild(availableEle); - Element elseEle = document.createElement("then"); - - Element moduleEle = document.createElement("ant"); - moduleEle.setAttribute("antfile", GlobalData - .getModulePath(baseName) - + File.separatorChar + "build.xml"); - moduleEle.setAttribute("target", baseName + "_clean"); - // - // ARCH - // - Element property = document.createElement("property"); - property.setAttribute("name", "ARCH"); - property.setAttribute("value", moduleId.getArch()); - moduleEle.appendChild(property); - // - // PACKAGE_DIR - // - property = document.createElement("property"); - property.setAttribute("name", "PACKAGE_DIR"); - property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar - + GlobalData.getPackagePathForModule(baseName)); - moduleEle.appendChild(property); - // - // PACKAGE - // - property = document.createElement("property"); - property.setAttribute("name", "PACKAGE"); - property.setAttribute("value", GlobalData - .getPackageNameForModule(baseName)); - moduleEle.appendChild(property); - elseEle.appendChild(moduleEle); - ifEle.appendChild(elseEle); - ele.appendChild(ifEle); - } - } - root.appendChild(ele); - // - // Deep Clean Target - // - root.appendChild(document.createComment("Clean All target")); - ele = document.createElement("target"); - ele.setAttribute("name", "cleanall"); - - if (isUnified) { - Element cleanAllEle = document.createElement("delete"); - cleanAllEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}"); - ele.appendChild(cleanAllEle); - } - else { - set = outfiles.keySet(); - iter = set.iterator(); - while (iter.hasNext()) { - FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next(); - String baseName = moduleId.getBaseName(); - - Element ifEle = document.createElement("if"); - Element availableEle = document.createElement("available"); - availableEle.setAttribute("file", GlobalData - .getModulePath(baseName) - + File.separatorChar + "build.xml"); - ifEle.appendChild(availableEle); - Element elseEle = document.createElement("then"); - - Element moduleEle = document.createElement("ant"); - moduleEle.setAttribute("antfile", GlobalData - .getModulePath(baseName) - + File.separatorChar + "build.xml"); - moduleEle.setAttribute("target", baseName + "_cleanall"); - // - // ARCH - // - Element property = document.createElement("property"); - property.setAttribute("name", "ARCH"); - property.setAttribute("value", moduleId.getArch()); - moduleEle.appendChild(property); - // - // PACKAGE_DIR - // - property = document.createElement("property"); - property.setAttribute("name", "PACKAGE_DIR"); - property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar - + GlobalData.getPackagePathForModule(baseName)); - moduleEle.appendChild(property); - // - // PACKAGE - // - property = document.createElement("property"); - property.setAttribute("name", "PACKAGE"); - property.setAttribute("value", GlobalData - .getPackageNameForModule(baseName)); - moduleEle.appendChild(property); - elseEle.appendChild(moduleEle); - ifEle.appendChild(elseEle); - ele.appendChild(ifEle); - } - } - root.appendChild(ele); - - document.appendChild(rootComment); - document.appendChild(root); - // - // Prepare the DOM document for writing - // - Source source = new DOMSource(document); - // - // Prepare the output file - // - File file = new File(getProject().getProperty("PLATFORM_DIR") - + File.separatorChar + "build.out.xml"); - // - // generate all directory path - // - (new File(file.getParent())).mkdirs(); - Result result = new StreamResult(file); - // - // Write the DOM document to the file - // - Transformer xformer = TransformerFactory.newInstance() - .newTransformer(); - xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); - xformer.setOutputProperty(OutputKeys.INDENT, "yes"); - xformer.transform(source, result); - } catch (Exception ex) { - throw new BuildException("Generate build.out.xml failed. \n" + ex.getMessage()); } + // + // Default is '.FFS' + // + return ".FFS"; } - /** - Add a property. - - @param p property - **/ + Add a property. + + @param p property + **/ public void addProperty(Property p) { properties.addElement(p); } - /** - Get FPD file name. - - @return FPD file name. - **/ - public File getFpdFilename() { - return fpdFilename; + public void setFpdFile(File fpdFile) { + this.fpdFile = fpdFile; } - /** - Set FPD file name. - - @param fpdFilename FPD file name - **/ - public void setFpdFilename(File fpdFilename) { - this.fpdFilename = fpdFilename; + public void setType(String type) { + this.type = type; } - - public File getGuiddatabase() { - return guiddatabase; + + public String getAllArchForModule(ModuleIdentification moduleId) { + String archs = ""; + Iterator iter = outfiles.keySet().iterator(); + while (iter.hasNext()) { + FpdModuleIdentification fpdModuleId = iter.next(); + + if (fpdModuleId.getModule().equals(moduleId)) { + archs += fpdModuleId.getArch() + " "; + } + } + + return archs; } - - public void setGuiddatabase(File guiddatabase) { - this.guiddatabase = guiddatabase; + + private Set getModuleSequenceForFv(String fvName) throws EdkException { + Node node = saq.getFpdModuleSequence(fvName); + Set result = new LinkedHashSet(); + + if ( node == null) { + EdkLog.log(this, EdkLog.EDK_WARNING, "FV[" + fvName + "] does not specify module sequence in FPD. Assuming present sequence as default sequence in FV. "); + return null; + } else { + NodeList childNodes = node.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node childItem = childNodes.item(i); + if (childItem.getNodeType() == Node.ELEMENT_NODE) { + // + // Find child elements "IncludeModules" + // + if (childItem.getNodeName().compareTo("IncludeModules") == 0) { + // + // result will be updated + // + processNodes(childItem, result); + } else if (childItem.getNodeName().compareTo("FvName") == 0) { + + } else if (childItem.getNodeName().compareTo("InfFileName") == 0) { + + } else { + // + // Report Warning + // + EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised element " + childItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1']"); + } + } + } + } + + return result; } - - public void collectPCDInformation() { - String exceptionString = null; - CollectPCDAction collectAction = new CollectPCDAction (); + + private void processNodes(Node node, Set result) throws EdkException { // - // Collect all PCD information from FPD to MSA, and get help information from SPD. - // These all information will be stored into memory database for future usage such - // as autogen. + // Found out all elements "Module" // - try { - collectAction.perform (getProject().getProperty("WORKSPACE_DIR"), - fpdFilename.getPath(), - ActionMessage.MAX_MESSAGE_LEVEL - ); - } catch (Exception exp) { - exceptionString = exp.getMessage(); - if (exceptionString == null) { - exceptionString = "[Internal Error]Pcd tools catch a internel errors, Please report this bug into TianoCore or send email to Wang, scott or Lu, ken!"; + NodeList childNodes = node.getChildNodes(); + for (int j = 0; j < childNodes.getLength(); j++) { + Node childItem = childNodes.item(j); + if (childItem.getNodeType() == Node.ELEMENT_NODE) { + if (childItem.getNodeName().compareTo("Module") == 0) { + String moduleGuid = null; + String moduleVersion = null; + String packageGuid = null; + String packageVersion = null; + String arch = null; + + NamedNodeMap attr = childItem.getAttributes(); + for (int i = 0; i < attr.getLength(); i++) { + Node attrItem = attr.item(i); + if (attrItem.getNodeName().compareTo("ModuleGuid") == 0) { + moduleGuid = attrItem.getNodeValue(); + } else if (attrItem.getNodeName().compareTo("ModuleVersion") == 0) { + moduleVersion = attrItem.getNodeValue(); + } else if (attrItem.getNodeName().compareTo("PackageGuid") == 0) { + packageGuid = attrItem.getNodeValue(); + } else if (attrItem.getNodeName().compareTo("PackageVersion") == 0) { + packageVersion = attrItem.getNodeValue(); + } else if (attrItem.getNodeName().compareTo("Arch") == 0) { + arch = attrItem.getNodeValue(); + } else { + // + // Report warning + // + EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised attribute " + attrItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules.Module"); + } + } + + PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion); + GlobalData.refreshPackageIdentification(packageId); + + ModuleIdentification moduleId = new ModuleIdentification(moduleGuid, moduleVersion); + moduleId.setPackage(packageId); + GlobalData.refreshModuleIdentification(moduleId); + + if (arch == null) { + throw new EdkException("Attribute [Arch] is required for element FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules.Module. "); + } + + result.add(new FpdModuleIdentification(moduleId, arch)); + } else { + // + // Report Warning + // + EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised element " + childItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules"); + } } - throw new BuildException (String.format("Fail to do PCD preprocess from FPD file: %s", exceptionString)); } } }