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=8a90ea563dcc3179547402bdf422e8bb784914df;hb=f6390d375c84a8dd7adbc2c76381b6bd41e256d8;hpb=5acb4b67f2bc16ee77c78f627ca13c196a2d9122 diff --git a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java index 8a90ea563d..b496e32ed5 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java +++ b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java @@ -18,6 +18,7 @@ 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; @@ -30,21 +31,28 @@ 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.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.SurfaceAreaQuery; 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 Framework @@ -63,33 +71,25 @@ import org.tianocore.build.toolchain.ToolChainMap;

The method parseFpdFile is also prepared for single module build.

-

The usage is (take NT32 Platform for example):

- -
-  <FPDParser platformName="Nt32" />
-  
- @since GenBuild 1.0 **/ public class FpdParserTask extends Task { - private String platformName; - private File fpdFile = null; - private PlatformIdentification platformId; + PlatformIdentification platformId; 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>(); /// /// FpdParserTask can specify some ANT properties. @@ -98,7 +98,7 @@ public class FpdParserTask extends Task { SurfaceAreaQuery saq = null; - private boolean isUnified = true; + boolean isUnified = true; /** Public construct method. It is necessary for ANT task. @@ -122,18 +122,8 @@ public class FpdParserTask extends Task { Surface area is not valid. **/ public void execute() throws BuildException { - // - // If fpdFile is not specified, - // then try to get FPD file by platformName - // - if ( fpdFile == null) { - if (platformName == null) { - throw new BuildException("FpdParserTask parameter error. Please specify either the platform name or FPD file!"); - } - platformId = GlobalData.getPlatformByName(platformName); - fpdFile = platformId.getFpdFile(); - } - + this.setTaskName("FpdParser"); + // // Parse FPD file // @@ -144,6 +134,7 @@ public class FpdParserTask extends Task { // isUnified = OutputManager.getInstance().prepareBuildDir(getProject()); + String buildDir = getProject().getProperty("BUILD_DIR"); // // For every Target and ToolChain // @@ -154,7 +145,7 @@ public class FpdParserTask extends Task { // // Prepare FV_DIR // - String ffsCommonDir = getProject().getProperty("BUILD_DIR") + File.separatorChar + String ffsCommonDir = buildDir + File.separatorChar + targetList[i] + "_" + toolchainList[j]; File fvDir = new File(ffsCommonDir + File.separatorChar + "FV"); @@ -171,16 +162,16 @@ public class FpdParserTask extends Task { // // Gen build.xml // - PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq); + 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 // - Ant ant = new Ant(); ant.setProject(getProject()); - ant.setAntfile(platformId.getFpdFile().getParent() + File.separatorChar + platformId.getName() + "_build.xml"); + ant.setAntfile(platformBuildFile); ant.setTarget(type); ant.setInheritAll(true); ant.init(); @@ -195,7 +186,7 @@ public class FpdParserTask extends Task { @throws BuildException File write FV.inf files error. **/ - private void genFvInfFiles(String ffsCommonDir) throws BuildException { + void genFvInfFiles(String ffsCommonDir) throws BuildException { String[] validFv = saq.getFpdValidImageNames(); for (int i = 0; i < validFv.length; i++) { // @@ -209,6 +200,12 @@ public class FpdParserTask extends Task { 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 { @@ -277,13 +274,48 @@ public class FpdParserTask extends Task { } bw.newLine(); } - + // // Files // + Set moduleSeqSet = getModuleSequenceForFv(validFv[i]); + Set filesSet = fvs.get(validFv[i]); - if (filesSet != null) { - FpdModuleIdentification[] files = filesSet.toArray(new FpdModuleIdentification[filesSet.size()]); + + 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++) { @@ -295,8 +327,14 @@ public class FpdParserTask extends Task { bw.flush(); bw.close(); fw.close(); - } catch (Exception e) { - throw new BuildException("Generation of the FV file [" + fvFile.getPath() + "] 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; } } } @@ -307,9 +345,46 @@ public class FpdParserTask extends Task { @throws BuildException FPD file is not valid. **/ - public void parseFpdFile(File fpdFile) 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(); } /** @@ -318,7 +393,7 @@ public class FpdParserTask extends Task { @throws BuildException FPD file is not valid. **/ - private void parseFpdFile() throws BuildException { + void parseFpdFile() throws BuildException { try { XmlObject doc = XmlObject.Factory.parse(fpdFile); @@ -339,6 +414,13 @@ public class FpdParserTask extends Task { 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. @@ -373,15 +455,25 @@ public class FpdParserTask extends Task { // PlatformPcdPreprocessActionForBuilding ca = new PlatformPcdPreprocessActionForBuilding(); ca.perform(platformId.getFpdFile().getPath(), ActionMessage.NULL_MESSAGE_LEVEL); - } catch (Exception e) { - throw new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + e.getMessage()); + } 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. **/ - private void parseModuleSAFiles() throws EdkException{ + void parseModuleSAFiles() throws EdkException{ Map> moduleSAs = saq.getFpdModules(); // @@ -429,7 +521,7 @@ public class FpdParserTask extends Task { } } - private ToolChainMap parseModuleBuildOptions(boolean toolChainFamilyFlag) throws EdkException { + ToolChainMap parseModuleBuildOptions(boolean toolChainFamilyFlag) throws EdkException { String[][] options = saq.getModuleBuildOptions(toolChainFamilyFlag); if (options == null || options.length == 0) { return new ToolChainMap(); @@ -475,7 +567,7 @@ public class FpdParserTask extends Task { @param fvName current FV name @param moduleName current module identification **/ - private void updateFvs(String fvName, FpdModuleIdentification fpdModuleId) { + void updateFvs(String fvName, FpdModuleIdentification fpdModuleId) { if (fvName == null || fvName.trim().length() == 0) { fvName = "NULL"; } @@ -546,10 +638,6 @@ public class FpdParserTask extends Task { properties.addElement(p); } - public void setPlatformName(String platformName) { - this.platformName = platformName; - } - public void setFpdFile(File fpdFile) { this.fpdFile = fpdFile; } @@ -571,4 +659,99 @@ public class FpdParserTask extends Task { return archs; } + + 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; + } + + private void processNodes(Node node, Set result) throws EdkException { + // + // Found out all elements "Module" + // + 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"); + } + } + } + } }