From feccee87a78e68d575dbdf44b34ca0cb5a21ea8d Mon Sep 17 00:00:00 2001 From: lhauch Date: Thu, 5 Oct 2006 23:12:07 +0000 Subject: Restructuring for better separation of Tool packages. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1674 6f19259b-4bc3-4df7-8a09-765794883524 --- Tools/Java/Source/GenBuild/GenBuild.msa | 84 + Tools/Java/Source/GenBuild/GenBuild.tasks | 8 + Tools/Java/Source/GenBuild/build.xml | 54 + .../GenBuild/org/tianocore/build/FfsProcess.java | 422 ++++ .../GenBuild/org/tianocore/build/FileProcess.java | 263 +++ .../org/tianocore/build/FrameworkBuildTask.java | 448 ++++ .../GenBuild/org/tianocore/build/GenBuildTask.java | 840 ++++++++ .../org/tianocore/build/GenBuildThread.java | 242 +++ .../tianocore/build/ModuleBuildFileGenerator.java | 493 +++++ .../org/tianocore/build/autogen/AutoGen.java | 2188 ++++++++++++++++++++ .../tianocore/build/autogen/AutogenLibOrder.java | 317 +++ .../tianocore/build/autogen/CommonDefinition.java | 285 +++ .../build/exception/AutoGenException.java | 40 + .../build/exception/GenBuildException.java | 40 + .../build/exception/PcdAutogenException.java | 35 + .../PlatformPcdPreprocessBuildException.java | 36 + .../build/exception/XmlParseException.java | 35 + .../tianocore/build/fpd/FpdParserForThread.java | 409 ++++ .../org/tianocore/build/fpd/FpdParserTask.java | 756 +++++++ .../build/fpd/PlatformBuildFileGenerator.java | 619 ++++++ .../org/tianocore/build/global/DpFile.java | 130 ++ .../org/tianocore/build/global/DpFileList.java | 64 + .../org/tianocore/build/global/GenBuildLogger.java | 274 +++ .../org/tianocore/build/global/GlobalData.java | 958 +++++++++ .../org/tianocore/build/global/OnDependency.java | 145 ++ .../org/tianocore/build/global/OutputManager.java | 201 ++ .../tianocore/build/global/PropertyManager.java | 196 ++ .../GenBuild/org/tianocore/build/global/Spd.java | 279 +++ .../tianocore/build/global/SurfaceAreaQuery.java | 2007 ++++++++++++++++++ .../org/tianocore/build/global/VariableTask.java | 71 + .../build/id/FpdModuleIdentification.java | 130 ++ .../org/tianocore/build/id/Identification.java | 128 ++ .../tianocore/build/id/ModuleIdentification.java | 171 ++ .../tianocore/build/id/PackageIdentification.java | 118 ++ .../tianocore/build/id/PlatformIdentification.java | 113 + .../build/pcd/action/PCDAutoGenAction.java | 384 ++++ .../tianocore/build/pcd/action/PcdDatabase.java | 1740 ++++++++++++++++ .../PlatformPcdPreprocessActionForBuilding.java | 372 ++++ .../tianocore/build/toolchain/ConfigReader.java | 108 + .../build/toolchain/ToolChainAttribute.java | 52 + .../tianocore/build/toolchain/ToolChainConfig.java | 125 ++ .../build/toolchain/ToolChainElement.java | 54 + .../tianocore/build/toolchain/ToolChainInfo.java | 347 ++++ .../tianocore/build/toolchain/ToolChainKey.java | 278 +++ .../tianocore/build/toolchain/ToolChainMap.java | 326 +++ .../org/tianocore/build/tools/ModuleItem.java | 140 ++ .../org/tianocore/build/tools/PackageItem.java | 88 + 47 files changed, 16613 insertions(+) create mode 100644 Tools/Java/Source/GenBuild/GenBuild.msa create mode 100644 Tools/Java/Source/GenBuild/GenBuild.tasks create mode 100644 Tools/Java/Source/GenBuild/build.xml create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/FfsProcess.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/FileProcess.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/FrameworkBuildTask.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/GenBuildTask.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/GenBuildThread.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/ModuleBuildFileGenerator.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/exception/AutoGenException.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/exception/GenBuildException.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/exception/PcdAutogenException.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/exception/PlatformPcdPreprocessBuildException.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/exception/XmlParseException.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/global/DpFile.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/global/DpFileList.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/global/GenBuildLogger.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/global/GlobalData.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/global/OnDependency.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/global/OutputManager.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/global/PropertyManager.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/global/Spd.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/global/VariableTask.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/id/FpdModuleIdentification.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/id/Identification.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/id/ModuleIdentification.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/id/PackageIdentification.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/id/PlatformIdentification.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PcdDatabase.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PlatformPcdPreprocessActionForBuilding.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainAttribute.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainConfig.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainElement.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainInfo.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainKey.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainMap.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/tools/ModuleItem.java create mode 100644 Tools/Java/Source/GenBuild/org/tianocore/build/tools/PackageItem.java (limited to 'Tools/Java/Source/GenBuild') diff --git a/Tools/Java/Source/GenBuild/GenBuild.msa b/Tools/Java/Source/GenBuild/GenBuild.msa new file mode 100644 index 0000000000..d982cae2fc --- /dev/null +++ b/Tools/Java/Source/GenBuild/GenBuild.msa @@ -0,0 +1,84 @@ + + + + GenBuild + TOOL + 0FC76CF5-8ACF-49a7-82E9-EA5BE953CC48 + 2.0 + This is the EFI/Tiano Tool Resources Module + + This Module provides the EFI/Tiano Tools that are used to create EFI/Tiano + Modules and Platform Binary Files (PBF) + These tools require compilation only once if the Developer Workstation and + the Developer's choice of HOST tool chain are stable. If the developer + updates either the OS or the HOST tool chain, these tools should be rebuilt. + + Copyright 2005-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. + + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + NULL + + + build.xml + GenBuild.tasks + org/tianocore/build/autogen/AutoGen.java + org/tianocore/build/autogen/AutogenLibOrder.java + org/tianocore/build/autogen/CommonDefinition.java + org/tianocore/build/exception/AutoGenException.java + org/tianocore/build/exception/EdkException.java + org/tianocore/build/exception/GenBuildException.java + org/tianocore/build/exception/PcdAutogenException.java + org/tianocore/build/exception/TianoToolsException.java + org/tianocore/build/exception/XmlParseException.java + org/tianocore/build/FfsProcess.java + org/tianocore/build/FileProcess.java + org/tianocore/build/fpd/FpdParserTask.java + org/tianocore/build/fpd/PlatformBuildFileGenerator.java + org/tianocore/build/FrameworkBuildTask.java + org/tianocore/build/GenBuildTask.java + org/tianocore/build/global/DpFile.java + org/tianocore/build/global/DpFileList.java + org/tianocore/build/global/GenBuildLogger.java + org/tianocore/build/global/GlobalData.java + org/tianocore/build/global/OnDependency.java + org/tianocore/build/global/OutputManager.java + org/tianocore/build/global/Spd.java + org/tianocore/build/global/SurfaceAreaQuery.java + org/tianocore/build/global/VariableTask.java + org/tianocore/build/id/FpdModuleIdentification.java + org/tianocore/build/id/Identification.java + org/tianocore/build/id/ModuleIdentification.java + org/tianocore/build/id/PackageIdentification.java + org/tianocore/build/id/PlatformIdentification.java + org/tianocore/build/ModuleBuildFileGenerator.java + org/tianocore/build/OutputDirSetup.java + org/tianocore/build/pcd/action/CollectPCDAction.java + org/tianocore/build/pcd/action/PcdDatabase.java + org/tianocore/build/pcd/action/PCDAutoGenAction.java + org/tianocore/build/toolchain/ConfigReader.java + org/tianocore/build/toolchain/ToolChainAttribute.java + org/tianocore/build/toolchain/ToolChainConfig.java + org/tianocore/build/toolchain/ToolChainElement.java + org/tianocore/build/toolchain/ToolChainInfo.java + org/tianocore/build/toolchain/ToolChainKey.java + org/tianocore/build/toolchain/ToolChainMap.java + org/tianocore/build/toolchain/ToolChainTask.java + org/tianocore/build/tools/DefaultBuildFileGenerator.java + org/tianocore/build/tools/ModuleItem.java + org/tianocore/build/tools/PackageItem.java + + diff --git a/Tools/Java/Source/GenBuild/GenBuild.tasks b/Tools/Java/Source/GenBuild/GenBuild.tasks new file mode 100644 index 0000000000..d581323b8d --- /dev/null +++ b/Tools/Java/Source/GenBuild/GenBuild.tasks @@ -0,0 +1,8 @@ +FPDParser = org.tianocore.build.fpd.FpdParserTask +bl = org.tianocore.build.global.VariableTask +GenBuild = org.tianocore.build.GenBuildTask +FrameworkBuild = org.tianocore.build.FrameworkBuildTask +OnDependency = org.tianocore.build.global.OnDependency +sourcefiles = org.tianocore.build.global.DpFileList +targetfiles = org.tianocore.build.global.DpFileList +file = org.tianocore.build.global.DpFile diff --git a/Tools/Java/Source/GenBuild/build.xml b/Tools/Java/Source/GenBuild/build.xml new file mode 100644 index 0000000000..b61e2519c3 --- /dev/null +++ b/Tools/Java/Source/GenBuild/build.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/FfsProcess.java b/Tools/Java/Source/GenBuild/org/tianocore/build/FfsProcess.java new file mode 100644 index 0000000000..26b9390901 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/FfsProcess.java @@ -0,0 +1,422 @@ +/** @file + File is FfsProcess class which is used to get the corresponding FFS layout + information for driver module. + +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; + +import java.io.File; +import java.util.Vector; + +import javax.xml.namespace.QName; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.xmlbeans.XmlCursor; +import org.tianocore.BuildOptionsDocument; +import org.tianocore.build.global.GlobalData; +import org.tianocore.build.global.SurfaceAreaQuery; +import org.tianocore.build.id.FpdModuleIdentification; +import org.tianocore.common.definitions.EdkDefinitions; +import org.tianocore.common.logger.EdkLog; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** +

FfsProcess is a class to find the corresponding FFS layout.

+ +

The FFS Layout is like following:

+ +
+    <Ffs type="APPLICATION">
+      <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_APPLICATION" />
+      <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />
+      <Sections EncapsulationType="Compress">
+        <Sections EncapsulationType="Guid-Defined">
+          <Section SectionType="EFI_SECTION_PE32" /> 
+          <Section SectionType="EFI_SECTION_USER_INTERFACE" />
+          <Section SectionType="EFI_SECTION_VERSION" /> 
+        </Sections>
+      </Sections>
+    </Ffs>
+  
+ + @since GenBuild 1.0 +**/ +public class FfsProcess { + + private BuildOptionsDocument.BuildOptions.Ffs ffsXmlObject; + + /// + /// ANT script to call GenFfs + /// + private Element ffsNode = null; + + /// + /// Module base name + /// + private String basename; + + /// + /// Sections type: normal + /// + private static int MODE_NONE = 0; + + /// + /// Sections type: compress + /// + private static int MODE_COMPRESS = 1; + + /// + /// Sections type: guid-define + /// + private static int MODE_GUID_DEFINED = 2; + + /// + /// mapping from section type to section output file extension + /// + public static final String[][] sectionExt = EdkDefinitions.SectionTypeExtensions; + + /** + search in the type, if componentType is listed in type, return true; + otherwise return false. + + @param type a list supported component type separated by comma + @param componentType current module component type + @return whether componentType is one of type + **/ + private boolean isMatch(String type, String componentType) { + String[] items = type.split("[ \t]*,[ \t]*"); + for (int i = 0; i < items.length; i++) { + if (items[i].equalsIgnoreCase(componentType)) { + return true; + } + } + return false; + } + + /** + Find the corresponding FFS layout in FPD. + + @param buildType Current module's component type + @param project Ant project + @return whether find the corresponding FFS layout + @throws BuildException + If can't find FFS Layout in FPD. + **/ + public boolean initSections(String buildType, Project project, FpdModuleIdentification fpdModuleId) throws BuildException { + // + // Try to find Ffs layout from FPD file + // + SurfaceAreaQuery saq = new SurfaceAreaQuery(GlobalData.getFpdBuildOptionsMap()); + BuildOptionsDocument.BuildOptions.Ffs[] ffsArray = saq.getFpdFfs(); + for (int i = 0; i < ffsArray.length; i++) { + if (isMatch(ffsArray[i].getFfsKey(), buildType)) { + ffsXmlObject = ffsArray[i]; + return true; + } + } + + // + // If FfsFormatKey is not null, report exception and fail build + // Otherwise report warning message + // + if (buildType == null) { + EdkLog.log(EdkLog.EDK_WARNING, "Warning: this module doesn't specify a FfsFormatKey. "); + } else { + throw new BuildException("Can't find the FfsFormatKey [" + buildType + "] attribute in the FPD file!"); + } + + return false; + } + + /** + Recursive parse the FFS layout. Find out all section type here used. + + @param document BaseName_build.xml Xml document + @param basename Module's base name + @param guid Module's GUID + @param targetFilename Module's final file name (GUID-BaseName.APP) + @return List of section type + **/ + public String[] getGenSectionElements(Document document, String basename, String guid, String targetFilename) { + this.basename = basename; + if (ffsXmlObject == null) { + return new String[0]; + } + Vector sectionList = new Vector(); + XmlCursor cursor = null; + + cursor = ffsXmlObject.newCursor(); + + int mode = MODE_NONE; + Element genffsfileEle = document.createElement("genffsfile"); + genffsfileEle.setAttribute("outputDir", "${BIN_DIR}"); + genffsfileEle.setAttribute("moduleType", "${MODULE_TYPE}"); + genffsfileEle.setAttribute("BaseName", basename); + genffsfileEle.setAttribute("fileGuid", guid); + + if (cursor.toFirstChild()) { + do { + if (cursor.getName().getLocalPart().equalsIgnoreCase("Attribute")) { + String name = cursor.getAttributeText(new QName("Name")); + String value = cursor.getAttributeText(new QName("Value")); + genffsfileEle.setAttribute(changeAttributeName(name), value); + } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) { + cursor.push(); + dealSection(mode, document, genffsfileEle, cursor, sectionList); + cursor.pop(); + } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) { + cursor.push(); + dealSections(mode, document, genffsfileEle, cursor, sectionList); + cursor.pop(); + } + } while (cursor.toNextSibling()); + } + // + // Check dependency + // + Element outofdateEle = document.createElement("OnDependency"); + Element sourceEle = document.createElement("sourcefiles"); + String[] result = new String[sectionList.size()]; + for (int i = 0; i < sectionList.size(); i++) { + result[i] = (String) sectionList.get(i); + Element pathEle = document.createElement("file"); + pathEle.setAttribute("name", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + + getSectionExt(result[i])); + sourceEle.appendChild(pathEle); + } + outofdateEle.appendChild(sourceEle); + Element targetEle = document.createElement("targetfiles"); + Element fileEle = document.createElement("file"); + fileEle.setAttribute("name", "${BIN_DIR}" + File.separatorChar + targetFilename); + targetEle.appendChild(fileEle); + outofdateEle.appendChild(targetEle); + Element sequentialEle = document.createElement("sequential"); + sequentialEle.appendChild(genffsfileEle); + outofdateEle.appendChild(sequentialEle); + ffsNode = outofdateEle; + return result; + } + + /** + Change the attribute name. For example: + +
+          Before change: FFS_ATTRIB_CHECKSUM 
+          After  change: ffsATTRIBCHECKSUM
+      
+ + @param name Original attribute name + @return Changed attribute name + **/ + private String changeAttributeName(String name) { + String[] strs = name.split("_"); + String str = strs[0].toLowerCase(); + for (int j = 1; j < strs.length; j++) { + str += strs[j]; + } + return str; + } + + /** + Recursively deal with Sections. If sections does not specify a type, then omit it. + + @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED) + @param doc Xml Document + @param root Root Node + @param cursor Current FFS layout cursor + @param list List of section type here used + **/ + private void dealSections(int mode, Document doc, Element root, XmlCursor cursor, Vector list) { + String type = cursor.getAttributeText(new QName("EncapsulationType")); + String toolName = cursor.getAttributeText(new QName("ToolName")); + String sectType = cursor.getAttributeText(new QName("SectionType")); + if (type == null && sectType == null) { + if (cursor.toFirstChild()) { + do { + if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) { + cursor.push(); + dealSection(mode, doc, root, cursor, list); + cursor.pop(); + } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) { + cursor.push(); + dealSections(mode, doc, root, cursor, list); + cursor.pop(); + } + } while (cursor.toNextSibling()); + } + return; + } + Element ele; + Element toolEle = null; + if (type.equalsIgnoreCase("COMPRESS") && (toolName == null || toolName.equalsIgnoreCase(""))) { + mode = MODE_COMPRESS; + // + // + // + ele = doc.createElement("gensection"); + ele.setAttribute("sectionType", "EFI_SECTION_COMPRESSION"); + + } else { + mode = MODE_GUID_DEFINED; + // + // + // + ele = doc.createElement("gensection"); + if (type != null) { + if (type.equalsIgnoreCase("COMPRESS")) { + ele.setAttribute("sectionType", "EFI_SECTION_COMPRESSION"); + }else { + ele.setAttribute("sectiontype", "EFI_SECTION_GUID_DEFINED"); + } + + } else { + ele.setAttribute("sectiontype", sectType); + } + // + // + // + toolEle = doc.createElement("tool"); + if (toolName == null || toolName.equalsIgnoreCase("")) { + toolEle.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin" + + File.separatorChar + "GenCRC32Section"); + }else{ + File toolExe = new File(toolName); + // + // If element exist, add sub element under . + // + if (toolExe.isAbsolute()) { + toolEle.setAttribute("toolName", toolName); + } else { + toolEle.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin" + + File.separatorChar + toolName); + } + } + + toolEle.setAttribute("outputPath", "${DEST_DIR_OUTPUT}"); + ele.appendChild(toolEle); + } + if (cursor.toFirstChild()) { + do { + if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) { + cursor.push(); + if (toolEle == null) { + dealSection(mode, doc, ele, cursor, list); + } else { + dealSection(mode, doc, toolEle, cursor, list); + } + + cursor.pop(); + } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) { + cursor.push(); + if (toolEle == null) { + dealSections(mode, doc, ele, cursor, list); + } else { + dealSections(mode, doc, toolEle, cursor, list); + } + + cursor.pop(); + } + } while (cursor.toNextSibling()); + } + root.appendChild(ele); + } + + /** + Recursively deal with section. + + @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED) + @param doc Xml Document + @param root Root Node + @param cursor Current FFS layout cursor + @param list List of section type here used + **/ + private void dealSection(int mode, Document doc, Element root, XmlCursor cursor, Vector list) { + String type = cursor.getAttributeText(new QName("SectionType")); + + // + // Judge if file is specified? Yes, just use the file, else call Build Macro + // If fileName is null, means without FileNames specify in FPD file + // + String fileName = null; + cursor.push(); + if (cursor.toFirstChild()) { + do { + if (cursor.getName().getLocalPart().equalsIgnoreCase("Filenames")) { + cursor.push(); + if (cursor.toFirstChild()) { + do { + if (cursor.getName().getLocalPart().equalsIgnoreCase("Filename")) { + fileName = cursor.getTextValue(); + } + } while (cursor.toNextSibling()); + } + cursor.pop(); + } + } while (cursor.toNextSibling()); + } + + cursor.pop(); + + if (fileName == null) { + list.addElement(type); + } + if (mode == MODE_GUID_DEFINED) { + // + // + // + Element ele = doc.createElement("input"); + if (fileName == null) { + ele.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type)); + } else { + ele.setAttribute("file", "${PLATFORM_DIR}" + File.separatorChar + fileName); + } + root.appendChild(ele); + } else { + // + // + // + Element ele = doc.createElement("sectFile"); + if (fileName == null) { + ele.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type)); + } else { + ele.setAttribute("fileName", "${PLATFORM_DIR}" + File.separatorChar + fileName); + } + root.appendChild(ele); + } + } + + /** + Get the corresponding section file suffix. + + @param type Section type + @return Corresponding section file extension + **/ + private String getSectionExt(String type) { + for (int i = 0; i < sectionExt.length; i++) { + if (sectionExt[i][0].equalsIgnoreCase(type)) { + return sectionExt[i][1]; + } + } + return ".sec"; + } + + /** + Return the ANT script to call GenFfs Tool. + + @return ANT script to call GenFfs Tool + **/ + public Element getFfsNode() { + return ffsNode; + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/FileProcess.java b/Tools/Java/Source/GenBuild/org/tianocore/build/FileProcess.java new file mode 100644 index 0000000000..09ccd1f94c --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/FileProcess.java @@ -0,0 +1,263 @@ +/** @file + File is FileProcess class which is used to generate ANT script to build + source files. + +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; + +import java.io.File; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** +

FileProcess is class to generate ANT script to build source + files.

+ +

If file does not specify file type, FileProcess will judge + by its extension. Following is the current supported extensions.

+ +
   
+ Source File Suffix     File Type       Description
+    .h                   CHeader      C header file
+    .c                   CCode        C source file
+    .inc                 ASMHeader    Assembly header file
+    .asm                 ASM          Assembly source file, usually for IA32 and X64 Arch and MSFT tool chain
+    .S                   ASM          Assembly source file, usually for IPF Arch
+    .s                   ASM          Assembly source file, usually for IA32 and X64 Arch and GCC tool chain
+    .uni                 UNI          Unicode file
+    .vfr                 VFR          Visual Forms Representation File
+    .fv                  FV           Firmware Volume
+    .SEC                 FFS          Firmware File System file
+    .PEI                 FFS          Firmware File System file
+    .DXE                 FFS          Firmware File System file
+    .APP                 FFS          Firmware File System file
+    .FVI                 FFS          Firmware File System file
+    .FFS                 FFS          Firmware File System file
+    .bmp                 BMP          Graphic File
+    .i                   PPCode       IPF PreProcessor Code
+  
+ + @since GenBuild 1.0 +**/ +public class FileProcess { + /// + /// The mapping information about source suffix, result suffix, file type. + /// + public final String[][] fileTypes = { {".h", "", "CHeader" }, + {".c", "", "CCode" }, + {".inc", "", "ASMHeader" }, + {".asm", "", "ASM" }, + {".S", "", "ASM" }, + {".s", "", "ASM" }, + {".uni", "", "UNI" }, + {".vfr", "", "VFR" }, + {".Vfr", "", "VFR" }, + {".dxs", "", "DPX"}, + {".fv", "", "FV" }, + {".efi", "", "EFI" }, + {".SEC", "", "FFS" }, + {".PEI", "", "FFS" }, + {".DXE", "", "FFS" }, + {".APP", "", "FFS" }, + {".FYI", "", "FFS" }, + {".FFS", "", "FFS" }, + {".bmp", "", "BMP" }, + {".i", "", "PPCode"}}; + /// + /// Current ANT context. + /// + private Project project; + + /// + /// Current module's include pathes + /// + private String[] includes; + + /// + /// Xml Document. + /// + private Document document; + + /// + /// The flag to ensure all unicode files build before others. + /// + private boolean unicodeFirst = true; + + /// + /// The flag present whether current module contains Unicode files or not. + /// + private boolean unicodeExist = false; + + /** + Initialize the project, includes, sourceFiles, document members. + + @param project ANT project + @param includes Module include pathes + @param sourceFiles Modules source files + @param document XML document + **/ + public void init(Project project, String[] includes, Document document) { + this.document = document; + this.includes = includes; + this.project = project; + } + + /** + Parse file without file type. + + @param filename Source file name + @param root Root node + @param unicodeFirst whether build Unicode file firstly or not + **/ + public synchronized void parseFile(String filename, Node root, boolean unicodeFirst) { + this.unicodeFirst = unicodeFirst; + parseFile(filename, root); + } + + /** + Get whether current module contains Unicode files or not. + + @return Whether current module contains Unicode files or not + **/ + public boolean isUnicodeExist() { + return unicodeExist; + } + + /** + Parse file. + + @param filename Source file name + @param filetype Source file type + @param root Root node + @param unicodeFirst whether build Unicode file firstly or not + **/ + public synchronized void parseFile(String filename, String filetype, Node root, boolean unicodeFirst) { + this.unicodeFirst = unicodeFirst; + parseFile(filename, filetype, root); + } + + /** + Find out source file's type. + + @param filename Source file name + @param root Root node + **/ + public synchronized void parseFile(String filename, Node root) throws BuildException { + for (int i = 0; i < fileTypes.length; i++) { + if (filename.endsWith(fileTypes[i][0])) { + parseFile(filename, fileTypes[i][2], root); + return ; + } + } + } + + /** + Parse file. If flag unicodeFirst is true, then build all + unicode files firstly. + +

Note that AutoGen.c is processed specially. It's output path is always + ${DEST_DIR_OUTPUT}, others are ${DEST_DIR_OUTPUT} + and relative to module path.

+ + @param filename Source file name + @param filetype Source file type + @param root Root node + **/ + public synchronized void parseFile(String filename, String filetype, Node root) { + if (unicodeFirst) { + if ( ! filetype.equalsIgnoreCase("UNI")){ + return ; + } + unicodeExist= true; + } else { + if (filetype.equalsIgnoreCase("UNI")){ + return ; + } + } + + // + // If file is C or ASM header file, skip it + // + if (filetype.equalsIgnoreCase("CHeader") || filetype.equalsIgnoreCase("ASMHeader")) { + return; + } + + // + // If file is pre-processor file, skip it + // + if (filetype.equalsIgnoreCase("PPCode")) { + return; + } + + // + // If define CC_EXT in tools_def.txt file, the source file with + // different suffix is skipped + // + String toolsDefExtName = project.getProperty(filetype + "_EXT"); + if (toolsDefExtName != null) { + String[] exts = toolsDefExtName.split(" "); + for (int i = 0; i < exts.length; i++) { + if ( ! filename.endsWith(exts[i])) { + return ; + } + } + } + + String module_path = project.getProperty("MODULE_DIR"); + File moduleFile = new File(module_path); + File sourceFile = new File(filename); + + // + // If source file is AutoGen.c, then Filepath is . + // + String sourceFilepath = ""; + String sourceFilename = ""; + String sourceFileext = ""; + if (sourceFile.getPath().endsWith("AutoGen.c")) { + sourceFilepath = "."; + sourceFilename = "AutoGen"; + sourceFileext = ".c"; + filetype = "AUTOGEN"; + } else { + // sourceFile. + String str = sourceFile.getPath().substring(moduleFile.getPath().length() + 1); + int index = str.lastIndexOf(File.separatorChar); + sourceFilepath = "."; + if (index > 0) { + sourceFilepath = str.substring(0, index); + str = str.substring(index + 1); + } + sourceFilename = str; + index = str.lastIndexOf('.'); + if (index > 0) { + sourceFilename = str.substring(0, index); + sourceFileext = str.substring(index); + } + } + // + Element ele = document.createElement("Build_" + filetype); + ele.setAttribute("FILEPATH", sourceFilepath); + ele.setAttribute("FILENAME", sourceFilename); + ele.setAttribute("FILEEXT", sourceFileext.substring(1)); + Element includesEle = document.createElement("EXTRA.INC"); + for (int i = 0; i < includes.length; i++) { + Element includeEle = document.createElement("includepath"); + includeEle.setAttribute("path", project.replaceProperties(includes[i])); + includesEle.appendChild(includeEle); + } + ele.appendChild(includesEle); + root.appendChild(ele); + } +} \ No newline at end of file diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/FrameworkBuildTask.java b/Tools/Java/Source/GenBuild/org/tianocore/build/FrameworkBuildTask.java new file mode 100644 index 0000000000..440510b522 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/FrameworkBuildTask.java @@ -0,0 +1,448 @@ +/** @file FrameworkBuildTask.java + + The file is ANT task to find MSA or FPD file and build them. + + 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; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.tianocore.build.exception.AutoGenException; +import org.tianocore.build.exception.GenBuildException; +import org.tianocore.build.exception.PcdAutogenException; +import org.tianocore.build.exception.PlatformPcdPreprocessBuildException; +import org.tianocore.build.fpd.FpdParserForThread; +import org.tianocore.build.fpd.FpdParserTask; +import org.tianocore.build.global.GenBuildLogger; +import org.tianocore.build.global.GlobalData; +import org.tianocore.build.toolchain.ConfigReader; +import org.tianocore.build.toolchain.ToolChainInfo; +import org.tianocore.common.definitions.ToolDefinitions; +import org.tianocore.common.exception.EdkException; +import org.tianocore.common.logger.EdkLog; + +/** +

+ FrameworkBuildTask is an Ant task. The main function is finding + and processing a FPD or MSA file, then building a platform or stand-alone + module. + +

+ The task search current directory and find out all MSA and FPD files by file + extension. Base on ACTIVE_PLATFORM policy, decide to build a platform or a + stand-alone module. The ACTIVE_PLATFORM policy is: + +

+  1. More than one MSA files, report error; 
+  2. Only one MSA file, but ACTIVE_PLATFORM is not specified, report error;
+  3. Only one MSA file, and ACTIVE_PLATFORM is also specified, build this module;
+  4. No MSA file, and ACTIVE_PLATFORM is specified, build the active platform;
+  5. No MSA file, no ACTIVE_PLATFORM, and no FPD file, report error;
+  6. No MSA file, no ACTIVE_PLATFORM, and only one FPD file, build the platform;
+  7. No MSA file, no ACTIVE_PLATFORM, and more than one FPD files, list all platform
+  and let user choose one. 
+  
+ +

+ Framework build task also parse target file [${WORKSPACE_DIR}/Tools/Conf/target.txt]. + And load all system environment variables to Ant properties. + +

+ The usage for this task is : + +

+  <FrameworkBuild type="cleanall" />
+  
+ + @since GenBuild 1.0 +**/ +public class FrameworkBuildTask extends Task{ + + private Set buildFiles = new LinkedHashSet(); + + private Set fpdFiles = new LinkedHashSet(); + + private Set msaFiles = new LinkedHashSet(); + + // + // This is only for none-multi-thread build to reduce overriding message + // + public static Hashtable originalProperties = new Hashtable(); + + String toolsDefFilename = ToolDefinitions.DEFAULT_TOOLS_DEF_FILE_PATH; + + String targetFilename = ToolDefinitions.TARGET_FILE_PATH; + + String dbFilename = ToolDefinitions.FRAMEWORK_DATABASE_FILE_PATH; + + String activePlatform = null; + + /// + /// The flag to present current is multi-thread enabled + /// + public static boolean multithread = false; + + /// + /// The concurrent thread number + /// + public static int MAX_CONCURRENT_THREAD_NUMBER = 2; + + /// + /// there are three type: all (build), clean and cleanall + /// + private String type = "all"; + + public void execute() throws BuildException { + // + // set Logger + // + GenBuildLogger logger = new GenBuildLogger(getProject()); + EdkLog.setLogLevel(getProject().getProperty("env.LOGLEVEL")); + EdkLog.setLogger(logger); + + try { + processFrameworkBuild(); + } catch (PcdAutogenException e) { + // + // Add more logic process here + // + throw new BuildException(e.getMessage()); + } catch (AutoGenException e) { + // + // Add more logic process here + // + throw new BuildException(e.getMessage()); + } catch (PlatformPcdPreprocessBuildException e) { + // + // Add more logic process here + // + throw new BuildException(e.getMessage()); + } catch (GenBuildException e) { + // + // Add more logic process here + // + throw new BuildException(e.getMessage()); + } catch (EdkException e) { + // + // Add more logic process here + // + throw new BuildException(e.getMessage()); + } + } + + private void processFrameworkBuild() throws EdkException, GenBuildException, AutoGenException, PcdAutogenException, PlatformPcdPreprocessBuildException { + // + // Seach build.xml -> .FPD -> .MSA file + // + try { + // + // Gen Current Working Directory + // + File dummyFile = new File("."); + File cwd = dummyFile.getCanonicalFile(); + File[] files = cwd.listFiles(); + for (int i = 0; i < files.length; i++) { + if (files[i].isFile()) { + if (files[i].getName().equalsIgnoreCase("build.xml")) { + // + // First, search build.xml, if found, ANT call it + // + buildFiles.add(files[i]); + + } else if (files[i].getName().endsWith(ToolDefinitions.FPD_EXTENSION)) { + // + // Second, search FPD file, if found, build it + // + fpdFiles.add(files[i]); + } else if (files[i].getName().endsWith(ToolDefinitions.MSA_EXTENSION)) { + // + // Third, search MSA file, if found, build it + // + msaFiles.add(files[i]); + } + } + } + } catch (IOException ex) { + BuildException buildException = new BuildException("Scanning current directory error. \n" + ex.getMessage()); + buildException.setStackTrace(ex.getStackTrace()); + throw buildException; + } + + // + // Deal with all environment variable (Add them to properties) + // + backupSystemProperties(); + + // + // Read target.txt file + // + readTargetFile(); + + // + // Global Data initialization + // + File workspacePath = new File(getProject().getProperty("WORKSPACE")); + getProject().setProperty("WORKSPACE_DIR", workspacePath.getPath().replaceAll("(\\\\)", "/")); + GlobalData.initInfo(dbFilename, workspacePath.getPath(), toolsDefFilename); + + // + // If find MSA file and ACTIVE_PLATFORM is set, build the module; + // else fail build. + // If without MSA file, and ACTIVE_PLATFORM is set, build the ACTIVE_PLATFORM. + // If ACTIVE_PLATFORM is not set, and only find one FPD file, build the platform; + // If find more than one FPD files, let user select one. + // + File buildFile = null; + if (msaFiles.size() > 1) { + throw new BuildException("Having more than one MSA file in a directory is not allowed!"); + } else if (msaFiles.size() == 1 && activePlatform == null) { + throw new BuildException("If trying to build a single module, please set ACTIVE_PLATFORM in file [" + targetFilename + "]. "); + } else if (msaFiles.size() == 1 && activePlatform != null) { + // + // Build the single module + // + buildFile = msaFiles.toArray(new File[1])[0]; + } else if (activePlatform != null) { + buildFile = new File(GlobalData.getWorkspacePath() + File.separatorChar + activePlatform); + } else if (fpdFiles.size() == 1) { + buildFile = fpdFiles.toArray(new File[1])[0]; + } else if (fpdFiles.size() > 1) { + buildFile = intercommuniteWithUser(); + } + // + // If there is no build files or FPD files or MSA files, stop build + // + else { + throw new BuildException("Can't find any FPD or MSA files in the current directory. "); + } + + // + // Build every FPD files (PLATFORM build) + // + if (buildFile.getName().endsWith(ToolDefinitions.FPD_EXTENSION)) { + EdkLog.log(this, "Processing the FPD file [" + buildFile.getPath() + "] ..>> "); + // + // Iff for platform build will enable the multi-thread if set in target.txt + // + if (multithread && type.equalsIgnoreCase("all")) { + EdkLog.log(this, "Multi-thread build is enabled. "); + FpdParserForThread fpdParserForThread = new FpdParserForThread(); + fpdParserForThread.setType(type); + fpdParserForThread.setProject(getProject()); + fpdParserForThread.setFpdFile(buildFile); + fpdParserForThread.perform(); + return ; + } + + FpdParserTask fpdParserTask = new FpdParserTask(); + fpdParserTask.setType(type); + fpdParserTask.setProject(getProject()); + fpdParserTask.setFpdFile(buildFile); + fpdParserTask.perform(); + + // + // If cleanall delete the Platform_build.xml + // + if (type.compareTo("cleanall") == 0) { + File platformBuildFile = + new File(getProject().getProperty("BUILD_DIR") + + File.separatorChar + + getProject().getProperty("PLATFORM") + + "_build.xml"); + platformBuildFile.deleteOnExit(); + } + } + + // + // Build every MSA files (SINGLE MODULE BUILD) + // + else if (buildFile.getName().endsWith(ToolDefinitions.MSA_EXTENSION)) { + if (multithread) { + EdkLog.log(this, EdkLog.EDK_WARNING, "Multi-Thead do not take effect on Stand-Alone (Single) module build. "); + multithread = false; + } + File tmpFile = new File(GlobalData.getWorkspacePath() + File.separatorChar + activePlatform); + EdkLog.log(this, "Using the FPD file [" + tmpFile.getPath() + "] for the active platform. "); + EdkLog.log(this, "Processing the MSA file [" + buildFile.getPath() + "] ..>> "); + GenBuildTask genBuildTask = new GenBuildTask(); + genBuildTask.setSingleModuleBuild(true); + genBuildTask.setType(type); + getProject().setProperty("PLATFORM_FILE", activePlatform); + if( !multithread) { + originalProperties.put("PLATFORM_FILE", activePlatform); + } + genBuildTask.setProject(getProject()); + genBuildTask.setMsaFile(buildFile); + genBuildTask.perform(); + } + } + + /** + Transfer system environment variables to ANT properties. If system variable + already exiests in ANT properties, skip it. + + **/ + private void backupSystemProperties() { + Map sysProperties = System.getenv(); + Iterator iter = sysProperties.keySet().iterator(); + while (iter.hasNext()) { + String name = iter.next(); + + // + // If system environment variable is not in ANT properties, add it + // + if (getProject().getProperty(name) == null) { + getProject().setProperty(name, sysProperties.get(name)); + } + } + + Hashtable allProperties = getProject().getProperties(); + Iterator piter = allProperties.keySet().iterator(); + while (piter.hasNext()) { + String name = (String)piter.next(); + originalProperties.put(new String(name), new String((String)allProperties.get(name))); + } + } + + private File intercommuniteWithUser(){ + File file = null; + if (fpdFiles.size() > 1) { + File[] allFiles = new File[fpdFiles.size()]; + int index = 0; + Iterator iter = fpdFiles.iterator(); + while (iter.hasNext()) { + allFiles[index] = iter.next(); + index++; + } + + EdkLog.log(this, "Finding " + allFiles.length + " FPD files: "); + for (int i = 0; i < allFiles.length; i++) { + System.out.println("[" + (i + 1) + "]: " + allFiles[i].getName()); + } + + boolean flag = true; + EdkLog.log(this, "Please select one of the following FPD files to build:[1] "); + do{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + try { + String str = br.readLine(); + if (str.trim().length() == 0) { + file = allFiles[0]; + flag = false; + continue ; + } + int indexSelect = Integer.parseInt(str); + if (indexSelect <=0 || indexSelect > allFiles.length) { + EdkLog.log(this, "Please enter a number between [1.." + allFiles.length + "]:[1] "); + continue ; + } else { + file = allFiles[indexSelect - 1]; + flag = false; + continue ; + } + } catch (Exception e) { + EdkLog.log(this, "Please enter a valid number:[1] "); + flag = true; + } + } while (flag); + } else if (fpdFiles.size() == 1) { + file = fpdFiles.toArray(new File[1])[0]; + } + return file; + } + + + public void setType(String type) { + if (type.equalsIgnoreCase("clean") || type.equalsIgnoreCase("cleanall")) { + this.type = type.toLowerCase(); + } else { + this.type = "all"; + } + } + + private void readTargetFile() throws EdkException{ + String targetFile = getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + targetFilename; + + String[][] targetFileInfo = ConfigReader.parse(targetFile); + + // + // Get ToolChain Info from target.txt + // + ToolChainInfo envToolChainInfo = new ToolChainInfo(); + String str = getValue(ToolDefinitions.TARGET_KEY_TARGET, targetFileInfo); + if (str == null || str.trim().equals("")) { + envToolChainInfo.addTargets("*"); + } else { + envToolChainInfo.addTargets(str); + } + str = getValue(ToolDefinitions.TARGET_KEY_TOOLCHAIN, targetFileInfo); + if (str == null || str.trim().equals("")) { + envToolChainInfo.addTagnames("*"); + } else { + envToolChainInfo.addTagnames(str); + } + str = getValue(ToolDefinitions.TARGET_KEY_ARCH, targetFileInfo); + if (str == null || str.trim().equals("")) { + envToolChainInfo.addArchs("*"); + } else { + envToolChainInfo.addArchs(str); + } + GlobalData.setToolChainEnvInfo(envToolChainInfo); + + str = getValue(ToolDefinitions.TARGET_KEY_TOOLS_DEF, targetFileInfo); + if (str != null && str.trim().length() > 0) { + toolsDefFilename = str; + } + + str = getValue(ToolDefinitions.TARGET_KEY_ACTIVE_PLATFORM, targetFileInfo); + if (str != null && ! str.trim().equals("")) { + if ( ! str.endsWith(".fpd")) { + throw new BuildException("FPD file's extension must be \"" + ToolDefinitions.FPD_EXTENSION + "\"!"); + } + activePlatform = str; + } + + str = getValue(ToolDefinitions.TARGET_KEY_MULTIPLE_THREAD, targetFileInfo); + if (str != null && str.trim().equalsIgnoreCase("Enable")) { + multithread = true; + } + + str = getValue(ToolDefinitions.TARGET_KEY_MAX_CONCURRENT_THREAD_NUMBER, targetFileInfo); + if (str != null ) { + try { + int threadNum = Integer.parseInt(str); + if (threadNum > 0) { + MAX_CONCURRENT_THREAD_NUMBER = threadNum; + } + } catch (Exception ex) { + } + } + } + + private String getValue(String key, String[][] map) { + for (int i = 0; i < map[0].length; i++){ + if (key.equalsIgnoreCase(map[0][i])) { + return map[1][i]; + } + } + return null; + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/GenBuildTask.java b/Tools/Java/Source/GenBuild/org/tianocore/build/GenBuildTask.java new file mode 100644 index 0000000000..99767ab4f2 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/GenBuildTask.java @@ -0,0 +1,840 @@ +/** @file + This file is ANT task GenBuild. + + The file is used to parse a specified Module, and generate its build time + ANT script build.xml, then call the the ANT script to build the module. + +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; + +import java.io.File; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Ant; +import org.apache.tools.ant.taskdefs.Property; +import org.apache.xmlbeans.XmlObject; + +import org.tianocore.common.definitions.ToolDefinitions; +import org.tianocore.common.exception.EdkException; +import org.tianocore.common.logger.EdkLog; +import org.tianocore.build.autogen.AutoGen; +import org.tianocore.build.exception.AutoGenException; +import org.tianocore.build.exception.GenBuildException; +import org.tianocore.build.exception.PcdAutogenException; +import org.tianocore.build.exception.PlatformPcdPreprocessBuildException; +import org.tianocore.build.fpd.FpdParserTask; +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.tools.ModuleItem; + +/** +

+ GenBuildTask is an ANT task that can be used in ANT build + system. + +

The main function of this task is to parse module's surface area (MSA), + then generate the corresponding BaseName_build.xml (the real ANT + build script) and call this to build the module. The whole process including: + +

+  1. generate AutoGen.c and AutoGen.h; 
+  2. build all dependent library instances;
+  3. build all source files inlcude AutoGen.c; 
+  4. generate sections;
+  5. generate FFS file if it is driver module while LIB file if it is Library module.
+  
+ + +

+ The usage is (take module HelloWorld for example): +

+ +
+    <GenBuild 
+       msaFile="${PACKAGE_DIR}/Application/HelloWorld/HelloWorld.msa"
+       type="cleanall" />
+  
+ +

+ This task calls AutoGen to generate AutoGen.c and + AutoGen.h. +

+ +

+ This task will also set properties for current module, such as PACKAGE, + PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR + (relative to Workspace), MODULE or BASE_NAME, GUID, VERSION, MODULE_DIR, + MODULE_RELATIVE_DIR (relative to Package), CONFIG_DIR, BIN_DIR, + DEST_DIR_DEBUG, DEST_DIR_OUTPUT, TARGET, ARCH, TOOLCHAIN, TOOLCHAIN_FAMILY, + SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH, all compiler command related + properties (CC, CC_FLAGS, CC_DPATH, CC_SPATH, CC_FAMILY, CC_EXT). +

+ + @since GenBuild 1.0 +**/ +public class GenBuildTask extends Ant { + + /// + /// Module surface area file. + /// + File msaFile; + + public ModuleIdentification parentId; + + private String type = "all"; + + /// + /// Module's Identification. + /// + private ModuleIdentification moduleId; + + private Vector properties = new Vector(); + + private boolean isSingleModuleBuild = false; + + private SurfaceAreaQuery saq = null; + + /** + Public construct method. It is necessary for ANT task. + **/ + public GenBuildTask() { + } + + /** + + @throws BuildException + From module build, exception from module surface area invalid. + **/ + public void execute() throws BuildException { + this.setTaskName("GenBuild"); + try { + processGenBuild(); + } catch (PcdAutogenException e) { + // + // Add more logic process here + // + throw new BuildException(e.getMessage()); + } catch (AutoGenException e) { + // + // Add more logic process here + // + throw new BuildException(e.getMessage()); + } catch (PlatformPcdPreprocessBuildException e) { + // + // Add more logic process here + // + throw new BuildException(e.getMessage()); + } catch (GenBuildException e) { + // + // Add more logic process here + // + throw new BuildException(e.getMessage()); + } catch (EdkException e) { + // + // Add more logic process here + // + throw new BuildException(e.getMessage()); + } + } + + private void processGenBuild() throws EdkException, BuildException, GenBuildException, AutoGenException, PcdAutogenException, PlatformPcdPreprocessBuildException { + if (!FrameworkBuildTask.multithread) { + cleanupProperties(); + } + + // + // Enable all specified properties + // + Iterator iter = properties.iterator(); + while (iter.hasNext()) { + Property item = iter.next(); + getProject().setProperty(item.getName(), item.getValue()); + } + + // + // GenBuild should specify either msaFile or moduleGuid & packageGuid + // + if (msaFile == null ) { + String moduleGuid = getProject().getProperty("MODULE_GUID"); + String moduleVersion = getProject().getProperty("MODULE_VERSION"); + String packageGuid = getProject().getProperty("PACKAGE_GUID"); + String packageVersion = getProject().getProperty("PACKAGE_VERSION"); + // + // If one of module Guid or package Guid is not specified, report error + // + if (moduleGuid == null || packageGuid == null) { + throw new BuildException("GenBuild parameter error."); + } + + PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion); + GlobalData.refreshPackageIdentification(packageId); + moduleId = new ModuleIdentification(moduleGuid, moduleVersion); + moduleId.setPackage(packageId); + GlobalData.refreshModuleIdentification(moduleId); + Map doc = GlobalData.getNativeMsa(moduleId); + saq = new SurfaceAreaQuery(doc); + } else { + Map doc = GlobalData.getNativeMsa(msaFile); + saq = new SurfaceAreaQuery(doc); + moduleId = saq.getMsaHeader(); + moduleId.setMsaFile(msaFile); + } + + String[] producedLibraryClasses = saq.getLibraryClasses("ALWAYS_PRODUCED",null); + if (producedLibraryClasses.length == 0) { + moduleId.setLibrary(false); + } else { + moduleId.setLibrary(true); + } + + // + // Judge whether it is single module build or not + // + if (isSingleModuleBuild) { + // + // Single Module build + // + prepareSingleModuleBuild(); + } + + // + // If single module : get arch from pass down, otherwise intersection MSA + // supported ARCHs and tools def + // + Set archListSupByToolChain = new LinkedHashSet(); + String[] archs = GlobalData.getToolChainInfo().getArchs(); + + for (int i = 0; i < archs.length; i ++) { + archListSupByToolChain.add(archs[i]); + } + + Set archSet = new LinkedHashSet(); + + if ( getProject().getProperty("ARCH") != null) { + String[] fpdArchList = getProject().getProperty("ARCH").split(" "); + + for (int i = 0; i < fpdArchList.length; i++) { + if (archListSupByToolChain.contains(fpdArchList[i])) { + archSet.add(fpdArchList[i]); + } + } + } else { + archSet = archListSupByToolChain; + } + + String[] archList = archSet.toArray(new String[archSet.size()]); + + // + // Judge if arch is all supported by current module. If not, throw Exception. + // + List moduleSupportedArchs = saq.getModuleSupportedArchs(); + if (moduleSupportedArchs != null) { + for (int k = 0; k < archList.length; k++) { + if ( ! moduleSupportedArchs.contains(archList[k])) { + throw new BuildException("Specified architecture [" + archList[k] + "] is not supported by " + moduleId + ". The module " + moduleId + " only supports [" + moduleSupportedArchs + "] architectures."); + } + } + } + + for (int k = 0; k < archList.length; k++) { + + getProject().setProperty("ARCH", archList[k]); + + FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]); + + // + // Whether the module is built before + // + if (moduleId.isLibrary() == false && GlobalData.hasFpdModuleSA(fpdModuleId) == false) { + EdkLog.log(this, EdkLog.EDK_WARNING, "Warning: " + moduleId + " for " + archList[k] + " was not found in current platform FPD file!\n"); + continue; + } else if (GlobalData.isModuleBuilt(fpdModuleId)) { + break; + } else { + GlobalData.registerBuiltModule(fpdModuleId); + } + + // + // For Every TOOLCHAIN, TARGET + // + String[] targetList = GlobalData.getToolChainInfo().getTargets(); + for (int i = 0; i < targetList.length; i ++){ + // + // Prepare for target related common properties + // TARGET + // + getProject().setProperty("TARGET", targetList[i]); + String[] toolchainList = GlobalData.getToolChainInfo().getTagnames(); + for(int j = 0; j < toolchainList.length; j ++){ + // + // check if any tool is defined for current target + toolchain + arch + // don't do anything if no tools found + // + if (GlobalData.isCommandSet(targetList[i], toolchainList[j], archList[k]) == false) { + EdkLog.log(this, EdkLog.EDK_WARNING, "Warning: No build issued. No tools were found for [target=" + targetList[i] + " toolchain=" + toolchainList[j] + " arch=" + archList[k] + "]\n"); + continue; + } + + // + // Prepare for toolchain related common properties + // TOOLCHAIN + // + getProject().setProperty("TOOLCHAIN", toolchainList[j]); + + EdkLog.log(this, "Build " + moduleId + " start >>>"); + EdkLog.log(this, "Target: " + targetList[i] + " Tagname: " + toolchainList[j] + " Arch: " + archList[k]); + saq.push(GlobalData.getDoc(fpdModuleId)); + + // + // Prepare for all other common properties + // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR + // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE + // MODULE_DIR, MODULE_RELATIVE_DIR + // SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH + // + setModuleCommonProperties(archList[k]); + + // + // OutputManage prepare for + // BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR + // + OutputManager.getInstance().update(getProject()); + + if (type.equalsIgnoreCase("all") || type.equalsIgnoreCase("build")) { + applyBuild(targetList[i], toolchainList[j], fpdModuleId); + } else if (type.equalsIgnoreCase("clean")) { + applyClean(fpdModuleId); + } else if (type.equalsIgnoreCase("cleanall")) { + applyCleanall(fpdModuleId); + } + } + } + } + } + + /** + This method is used to prepare Platform-related information. + +

In Single Module Build mode, platform-related information is not ready. + The method read the system environment variable ACTIVE_PLATFORM + and search in the Framework Database. Note that platform name in the Framework + Database must be unique.

+ + **/ + private void prepareSingleModuleBuild() throws EdkException { + // + // Find out the package which the module belongs to + // + PackageIdentification packageId = GlobalData.getPackageForModule(moduleId); + GlobalData.refreshPackageIdentification(packageId); + moduleId.setPackage(packageId); + GlobalData.refreshModuleIdentification(moduleId); + + // + // Read ACTIVE_PLATFORM's FPD file + // + String filename = getProject().getProperty("PLATFORM_FILE"); + + if (filename == null){ + throw new BuildException("Please set ACTIVE_PLATFORM in the file: Tools/Conf/target.txt if you want to build a single module!"); + } + + PlatformIdentification platformId = GlobalData.getPlatform(filename); + + // + // Read FPD file (Call FpdParserTask's method) + // + FpdParserTask fpdParser = new FpdParserTask(); + fpdParser.setProject(getProject()); + fpdParser.parseFpdFile(platformId.getFpdFile()); + getProject().setProperty("ARCH", fpdParser.getAllArchForModule(moduleId)); + } + + private void cleanupProperties() { + Project newProject = new Project(); + + Hashtable passdownProperties = FrameworkBuildTask.originalProperties; + Iterator iter = passdownProperties.keySet().iterator(); + while (iter.hasNext()) { + String item = iter.next(); + newProject.setProperty(item, passdownProperties.get(item)); + } + + newProject.setInputHandler(getProject().getInputHandler()); + + Iterator listenerIter = getProject().getBuildListeners().iterator(); + while (listenerIter.hasNext()) { + newProject.addBuildListener((BuildListener) listenerIter.next()); + } + + getProject().initSubProject(newProject); + + setProject(newProject); + } + + /** + Set Module-Related information to properties. + + @param arch current build ARCH + **/ + private void setModuleCommonProperties(String arch) { + // + // Prepare for all other common properties + // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR + // + PackageIdentification packageId = moduleId.getPackage(); + getProject().setProperty("PACKAGE", packageId.getName()); + getProject().setProperty("PACKAGE_GUID", packageId.getGuid()); + getProject().setProperty("PACKAGE_VERSION", packageId.getVersion()); + getProject().setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/")); + getProject().setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/")); + + // + // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE + // MODULE_DIR, MODULE_RELATIVE_DIR + // + getProject().setProperty("MODULE", moduleId.getName()); + String baseName = saq.getModuleOutputFileBasename(); + if (baseName == null) { + getProject().setProperty("BASE_NAME", moduleId.getName()); + } else { + getProject().setProperty("BASE_NAME", baseName); + } + getProject().setProperty("GUID", moduleId.getGuid()); + getProject().setProperty("FILE_GUID", moduleId.getGuid()); + getProject().setProperty("VERSION", moduleId.getVersion()); + getProject().setProperty("MODULE_TYPE", moduleId.getModuleType()); + getProject().setProperty("MODULE_DIR", moduleId.getMsaFile().getParent().replaceAll("(\\\\)", "/")); + getProject().setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/")); + + // + // SUBSYSTEM + // + String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"}, + { "SEC", "EFI_BOOT_SERVICE_DRIVER" }, + { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" }, + { "PEIM", "EFI_BOOT_SERVICE_DRIVER" }, + { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" }, + { "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, + { "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" }, + { "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, + { "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, + { "TOOL", "EFI_BOOT_SERVICE_DRIVER" }, + { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, + { "UEFI_APPLICATION", "EFI_APPLICATION" }, + { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} }; + + String subsystem = "EFI_BOOT_SERVICE_DRIVER"; + for (int i = 0; i < subsystemMap.length; i++) { + if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) { + subsystem = subsystemMap[i][1]; + break ; + } + } + getProject().setProperty("SUBSYSTEM", subsystem); + + // + // ENTRYPOINT + // + if (arch.equalsIgnoreCase("EBC")) { + getProject().setProperty("ENTRYPOINT", "EfiStart"); + } else { + getProject().setProperty("ENTRYPOINT", "_ModuleEntryPoint"); + } + + getProject().setProperty("OBJECTS", ""); + } + + private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException { + String[] cmd = GlobalData.getToolChainInfo().getCommands(); + for ( int m = 0; m < cmd.length; m++) { + // + // Set cmd, like CC, DLINK + // + String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null}; + key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_PATH; + String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId); + key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME; + String cmdName = GlobalData.getCommandSetting(key, fpdModuleId); + File cmdFile = new File(cmdPath + File.separatorChar + cmdName); + getProject().setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/")); + + // + // set CC_FLAGS + // + key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS; + String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId); + if (cmdFlags != null) + { +// Set addset = new LinkedHashSet(); +// Set subset = new LinkedHashSet(); +// putFlagsToSet(addset, cmdFlags); +// getProject().setProperty(cmd[m] + "_FLAGS", getProject().replaceProperties(getFlags(addset, subset))); + getProject().setProperty(cmd[m] + "_FLAGS", cmdFlags); + } + else + { + getProject().setProperty(cmd[m] + "_FLAGS", ""); + } + + + // + // Set CC_EXT + // + key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_EXT; + String extName = GlobalData.getCommandSetting(key, fpdModuleId); + if ( extName != null && ! extName.equalsIgnoreCase("")) { + getProject().setProperty(cmd[m] + "_EXT", extName); + } else { + getProject().setProperty(cmd[m] + "_EXT", ""); + } + + // + // set CC_FAMILY + // + key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY; + String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId); + if (toolChainFamily != null) { + getProject().setProperty(cmd[m] + "_FAMILY", toolChainFamily); + } + + // + // set CC_SPATH + // + key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_SPATH; + String spath = GlobalData.getCommandSetting(key, fpdModuleId); + if (spath != null) { + getProject().setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/")); + } else { + getProject().setProperty(cmd[m] + "_SPATH", ""); + } + + // + // set CC_DPATH + // + key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_DPATH; + String dpath = GlobalData.getCommandSetting(key, fpdModuleId); + if (dpath != null) { + getProject().setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/")); + } else { + getProject().setProperty(cmd[m] + "_DPATH", ""); + } + } + } + + public void setMsaFile(File msaFile) { + this.msaFile = msaFile; + } + + /** + Method is for ANT to initialize MSA file. + + @param msaFilename MSA file name + **/ + public void setMsaFile(String msaFilename) { + String moduleDir = getProject().getProperty("MODULE_DIR"); + + // + // If is Single Module Build, then use the Base Dir defined in build.xml + // + if (moduleDir == null) { + moduleDir = getProject().getBaseDir().getPath(); + } + msaFile = new File(moduleDir + File.separatorChar + msaFilename); + } + + public void addConfiguredModuleItem(ModuleItem moduleItem) { + PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion()); + ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion()); + moduleId.setPackage(packageId); + this.moduleId = moduleId; + } + + /** + Add a property. + + @param p property + **/ + public void addProperty(Property p) { + properties.addElement(p); + } + + public void setType(String type) { + this.type = type; + } + + private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws EdkException { + // + // Call AutoGen to generate AutoGen.c and AutoGen.h + // + AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch(), saq, parentId); + autogen.genAutogen(); + + // + // Get compiler flags + // + try { + getCompilerFlags(buildTarget, buildTagname, fpdModuleId); + } + catch (EdkException ee) { + throw new BuildException(ee.getMessage()); + } + + // + // Prepare LIBS + // + ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch()); + String propertyLibs = ""; + for (int i = 0; i < libinstances.length; i++) { + propertyLibs += getProject().getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib" + " "; + } + getProject().setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/")); + + // + // Get all includepath and set to INCLUDE_PATHS + // + String[] includes = prepareIncludePaths(fpdModuleId); + + // + // if it is CUSTOM_BUILD + // then call the exist BaseName_build.xml directly. + // + if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) { + EdkLog.log(this, "Call user-defined " + moduleId.getName() + "_build.xml"); + + String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml"; + antCall(antFilename, null); + + return ; + } + + // + // Generate ${BASE_NAME}_build.xml + // TBD + // + String ffsKeyword = saq.getModuleFfsKeyword(); + ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId, includes, saq); + String buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml"; + fileGenerator.genBuildFile(buildFilename); + + // + // Ant call ${BASE_NAME}_build.xml + // + String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml"; + antCall(antFilename, null); + } + + private void applyClean(FpdModuleIdentification fpdModuleId){ + // + // if it is CUSTOM_BUILD + // then call the exist BaseName_build.xml directly. + // + if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) { + EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml"); + + String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml"; + antCall(antFilename, "clean"); + + return ; + } + + String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml"; + antCall(antFilename, "clean"); + } + + private void applyCleanall(FpdModuleIdentification fpdModuleId){ + // + // if it is CUSTOM_BUILD + // then call the exist BaseName_build.xml directly. + // + if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) { + EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml"); + + String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml"; + antCall(antFilename, "cleanall"); + + return ; + } + + String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml"; + antCall(antFilename, "cleanall"); + } + + private void antCall(String antFilename, String target) { + Ant ant = new Ant(); + ant.setProject(getProject()); + ant.setAntfile(antFilename); + if (target != null) { + ant.setTarget(target); + } + ant.setInheritAll(true); + ant.init(); + ant.execute(); + } + + + /** + Separate the string and instore in set. + +

String is separated by Java Regulation Expression + "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+".

+ +

For example:

+ +
+        "/nologo", "/W3", "/WX"
+        "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
+      
+ + @param set store the separated string + @param str string to separate + **/ + private void putFlagsToSet(Set set, String str) { + if (str == null || str.length() == 0) { + return; + } + + Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+"); + Matcher matcher = myPattern.matcher(str + " "); + while (matcher.find()) { + String item = str.substring(matcher.start(1), matcher.end(1)); + set.add(item); + } + } + + /** + Generate the final flags string will be used by compile command. + + @param add the add flags set + @param sub the sub flags set + @return final flags after add set substract sub set + **/ + private String getFlags(Set add, Set sub) { + String result = ""; + add.removeAll(sub); + Iterator iter = add.iterator(); + while (iter.hasNext()) { + String str = (String) iter.next(); + result += str.substring(1, str.length() - 1) + " "; + } + return result; + } + + public void setSingleModuleBuild(boolean isSingleModuleBuild) { + this.isSingleModuleBuild = isSingleModuleBuild; + } + + private String[] prepareIncludePaths(FpdModuleIdentification fpdModuleId) throws EdkException{ + // + // Prepare the includes: PackageDependencies and Output debug direactory + // + Set includes = new LinkedHashSet(); + String arch = fpdModuleId.getArch(); + + // + // WORKSPACE + // + includes.add("${WORKSPACE_DIR}" + File.separatorChar); + + // + // Module iteself + // + includes.add("${MODULE_DIR}"); + includes.add("${MODULE_DIR}" + File.separatorChar + archDir(arch)); + + // + // Packages in PackageDenpendencies + // + PackageIdentification[] packageDependencies = saq.getDependencePkg(fpdModuleId.getArch()); + for (int i = 0; i < packageDependencies.length; i++) { + GlobalData.refreshPackageIdentification(packageDependencies[i]); + File packageFile = packageDependencies[i].getSpdFile(); + includes.add(packageFile.getParent() + File.separatorChar + "Include"); + includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch)); + } + + // + // All Dependency Library Instance's PackageDependencies + // + ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch()); + for (int i = 0; i < libinstances.length; i++) { + saq.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch())); + PackageIdentification[] libraryPackageDependencies = saq.getDependencePkg(fpdModuleId.getArch()); + for (int j = 0; j < libraryPackageDependencies.length; j++) { + GlobalData.refreshPackageIdentification(libraryPackageDependencies[j]); + File packageFile = libraryPackageDependencies[j].getSpdFile(); + includes.add(packageFile.getParent() + File.separatorChar + "Include"); + includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch)); + } + saq.pop(); + } + + + // + // The package which the module belongs to + // TBD + includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include"); + includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include" + File.separatorChar + archDir(arch)); + + // + // Debug files output directory + // + includes.add("${DEST_DIR_DEBUG}"); + + // + // set to INCLUDE_PATHS property + // + Iterator iter = includes.iterator(); + StringBuffer includePaths = new StringBuffer(); + while (iter.hasNext()) { + includePaths.append(iter.next()); + includePaths.append("; "); + } + getProject().setProperty("INCLUDE_PATHS", getProject().replaceProperties(includePaths.toString()).replaceAll("(\\\\)", "/")); + + return includes.toArray(new String[includes.size()]); + } + + /** + Return the name of the directory that corresponds to the architecture. + This is a translation from the XML Schema tag to a directory that + corresponds to our directory name coding convention. + + **/ + private String archDir(String arch) { + return arch.replaceFirst("X64", "x64") + .replaceFirst("IPF", "Ipf") + .replaceFirst("IA32", "Ia32") + .replaceFirst("ARM", "Arm") + .replaceFirst("EBC", "Ebc"); + } + + + public void setExternalProperties(Vector v) { + this.properties = v; + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/GenBuildThread.java b/Tools/Java/Source/GenBuild/org/tianocore/build/GenBuildThread.java new file mode 100644 index 0000000000..738a448f3a --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/GenBuildThread.java @@ -0,0 +1,242 @@ +/** @file + This file is for single module thread definition. + +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; + +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.Vector; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Property; +import org.tianocore.build.GenBuildTask; +import org.tianocore.build.fpd.FpdParserForThread; +import org.tianocore.build.global.GenBuildLogger; +import org.tianocore.build.id.FpdModuleIdentification; +import org.tianocore.build.id.ModuleIdentification; +import org.tianocore.common.logger.EdkLog; + +/** + Add more comment here. + + @since GenBuild 1.0 +**/ +public class GenBuildThread implements Runnable { + + private ModuleIdentification parentModuleId = null; + + private ModuleIdentification moduleId = null; + + private Set dependencies = new LinkedHashSet(); + + private int status = FpdParserForThread.STATUS_DEPENDENCY_NOT_READY; + + private Project project = null; + + public Object semaphore = new Object(); + + private String arch = null; + + private boolean highPriority = false; + + private Thread thread; + + public GenBuildThread(ModuleIdentification moduleId, String arch) { + this.moduleId = moduleId; + this.arch = arch; + thread = new Thread(FpdParserForThread.tg, this, moduleId + ":" + arch); + } + + public boolean start() { + if (highPriority) { + thread.setPriority(Thread.MAX_PRIORITY); + } + + status = FpdParserForThread.STATUS_START_RUN; + + thread.start(); + + return true; + } + + public void run() { + + FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch); + + try { + // + // Prepare pass down properties + // ARCH, MODULE_GUID, MODULE_VERSION, PACKAGE_GUID, PACKAGE_VERSION, PLATFORM_FILE + // + Vector properties = new Vector(); + Property property = new Property(); + property.setName("ARCH"); + property.setValue(arch); + properties.add(property); + + property = new Property(); + property.setName("MODULE_GUID"); + property.setValue(moduleId.getGuid()); + properties.add(property); + + property = new Property(); + property.setName("MODULE_VERSION"); + if (moduleId.getVersion() == null) { + property.setValue(""); + } else { + property.setValue(moduleId.getVersion()); + } + properties.add(property); + + property = new Property(); + property.setName("PACKAGE_GUID"); + property.setValue(moduleId.getPackage().getGuid()); + properties.add(property); + + property = new Property(); + property.setName("PACKAGE_VERSION"); + if (moduleId.getPackage().getVersion() == null) { + property.setValue(""); + } else { + property.setValue(moduleId.getPackage().getVersion()); + } + properties.add(property); + + // + // Build the Module + // + GenBuildTask genBuildTask = new GenBuildTask(); + + Project newProject = new Project(); + + Hashtable passdownProperties = project.getProperties(); + Iterator iter = passdownProperties.keySet().iterator(); + while (iter.hasNext()) { + String item = (String) iter.next(); + newProject.setProperty(item, (String) passdownProperties.get(item)); + } + + newProject.setInputHandler(project.getInputHandler()); + + Iterator listenerIter = project.getBuildListeners().iterator(); + GenBuildLogger newLogger = null; + while (listenerIter.hasNext()) { + BuildListener item = (BuildListener)listenerIter.next(); + if (item instanceof GenBuildLogger) { + newLogger = (GenBuildLogger)((GenBuildLogger)item).clone(); + newLogger.setId(fpdModuleId); + newProject.addBuildListener(newLogger); + } else { + newProject.addBuildListener(item); + } + } + + project.initSubProject(newProject); + + genBuildTask.setProject(newProject); + + genBuildTask.setExternalProperties(properties); + + genBuildTask.parentId = parentModuleId; + + genBuildTask.perform(); + } catch (BuildException be) { + + EdkLog.log("GenBuild", EdkLog.EDK_ALWAYS, fpdModuleId + " build error. \n" + be.getMessage()); + + if (FpdParserForThread.errorModule == null) { + FpdParserForThread.errorModule = fpdModuleId; + } + + synchronized (FpdParserForThread.deamonSemaphore) { + FpdParserForThread.subCount(); + FpdParserForThread.deamonSemaphore.notifyAll(); + } + + return ; + } + + status = FpdParserForThread.STATUS_END_RUN; + + EdkLog.log("GenBuild", EdkLog.EDK_ALWAYS, fpdModuleId + " build finished. "); + + // + // + // + synchronized (FpdParserForThread.deamonSemaphore) { + FpdParserForThread.subCount(); + FpdParserForThread.deamonSemaphore.notifyAll(); + } + } + + public void setArch(String arch) { + this.arch = arch; + } + + public void setDependencies(Set dependencies) { + this.dependencies = dependencies; + } + + public void setModuleId(ModuleIdentification moduleId) { + this.moduleId = moduleId; + } + + public void setParentModuleId(ModuleIdentification parentModuleId) { + this.parentModuleId = parentModuleId; + } + + public void setProject(Project project) { + this.project = project; + } + + public void setHighPriority(boolean highPriority) { + this.highPriority = highPriority; + } + + + public Set getDependencies() { + return dependencies; + } + + public ModuleIdentification getModuleId() { + return moduleId; + } + + public int getStatus() { + // + // Add code here to judge dependency + // + if (status == FpdParserForThread.STATUS_DEPENDENCY_NOT_READY) { + Iterator iter = dependencies.iterator(); + boolean flag = true; + while (iter.hasNext()) { + FpdModuleIdentification item = iter.next(); + if (FpdParserForThread.allThreads.get(item).getStatus() == 1) { + flag = false; + break ; + } + } + if (flag) { + status = FpdParserForThread.STATUS_DEPENDENCY_READY; + } + } + return status; + } + + public void setStatus(int status) { + this.status = status; + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/ModuleBuildFileGenerator.java b/Tools/Java/Source/GenBuild/org/tianocore/build/ModuleBuildFileGenerator.java new file mode 100644 index 0000000000..c02bc1fce8 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/ModuleBuildFileGenerator.java @@ -0,0 +1,493 @@ +/** @file + + 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; + +import java.io.File; +import java.util.LinkedHashMap; +import java.util.Map; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +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.Project; +import org.tianocore.build.exception.GenBuildException; +import org.tianocore.build.fpd.FpdParserTask; +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.common.exception.EdkException; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +public class ModuleBuildFileGenerator { + + /// + /// Pass: TARGET, TOOLCHAIN, ARCH + /// PACKAGE, PACKAGE_GUID, PACKAGE_VERSION + /// + String[] inheritProperties = {"ARCH", "MODULE_GUID", "MODULE_VERSION", "PACKAGE_GUID", "PACKAGE_VERSION"}; + + /// + /// The information at the header of build.xml. + /// + private String info = "DO NOT EDIT \n" + + "This file is auto-generated by the build utility\n" + + "\n" + + "Abstract:\n" + + "Auto-generated ANT build file for build EFI Modules and Platforms\n"; + + private FpdModuleIdentification fpdModuleId; + + private Project project; + + private String ffsKeyword; + + private String[] includes; + + private SurfaceAreaQuery saq = null; + + public ModuleBuildFileGenerator(Project project, String ffsKeyword, FpdModuleIdentification fpdModuleId, String[] includes, SurfaceAreaQuery saq) { + this.project = project; + this.fpdModuleId = fpdModuleId; + this.ffsKeyword = ffsKeyword; + this.includes = includes; + this.saq = saq; + } + + /** + The whole BaseName_build.xml is composed of seven part. +
    +
  • ANT properties;
  • +
  • Dependent module (dependent library instances in most case);
  • +
  • Source files;
  • +
  • Sections if module is not library;
  • +
  • Output (different for library module and driver module);
  • +
  • Clean;
  • +
  • Clean all.
  • +
+ + @throws BuildException + Error throws during BaseName_build.xml generating. + **/ + public void genBuildFile(String buildFilename) throws GenBuildException, EdkException { + FfsProcess fp = new FfsProcess(); + 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", fpdModuleId.getModule().getName()); + root.setAttribute("default", "all"); + root.setAttribute("basedir", "."); + + // + // element for External ANT tasks + // + root.appendChild(document.createComment("Apply external ANT tasks")); + Element ele = document.createElement("taskdef"); + ele.setAttribute("resource", "frameworktasks.tasks"); + root.appendChild(ele); + ele = document.createElement("taskdef"); + ele.setAttribute("resource", "cpptasks.tasks"); + root.appendChild(ele); + ele = document.createElement("typedef"); + ele.setAttribute("resource", "cpptasks.types"); + root.appendChild(ele); + ele = document.createElement("taskdef"); + ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml"); + root.appendChild(ele); + + // + // Generate the default target, + // which depends on init, sections and output target + // + root.appendChild(document.createComment("Default target")); + ele = document.createElement("target"); + ele.setAttribute("name", "all"); + ele.setAttribute("depends", "libraries, sourcefiles, sections, output"); + root.appendChild(ele); + + // + // compile all source files + // + root.appendChild(document.createComment("Compile all dependency Library instances.")); + ele = document.createElement("target"); + ele.setAttribute("name", "libraries"); + + // + // Parse all sourfiles but files specified in sections + // + if (!FrameworkBuildTask.multithread) { + applyLibraryInstance(document, ele); + } + root.appendChild(ele); + + // + // compile all source files + // + root.appendChild(document.createComment("sourcefiles target")); + ele = document.createElement("target"); + ele.setAttribute("name", "sourcefiles"); + + // + // Parse all sourfiles but files specified in sections + // + applyCompileElement(document, ele); + root.appendChild(ele); + + // + // generate the init target + // main purpose is create all nessary pathes + // generate the sections target + // + root.appendChild(document.createComment("sections target")); + ele = document.createElement("target"); + ele.setAttribute("name", "sections"); + applySectionsElement(document, ele, fp); + root.appendChild(ele); + + // + // generate the output target + // + root.appendChild(document.createComment("output target")); + ele = document.createElement("target"); + ele.setAttribute("name", "output"); + applyOutputElement(document, ele, fp); + root.appendChild(ele); + + + // + // generate the clean target + // + root.appendChild(document.createComment("clean target")); + ele = document.createElement("target"); + ele.setAttribute("name", "clean"); + applyCleanElement(document, ele); + root.appendChild(ele); + + // + // generate the Clean All target + // + root.appendChild(document.createComment("Clean All target")); + ele = document.createElement("target"); + ele.setAttribute("name", "cleanall"); + applyDeepcleanElement(document, ele); + root.appendChild(ele); + + // + // add the root element to the document + // + 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(buildFilename); + + // + // generate all directory path + // + (new File(file.getParent())).mkdirs(); + FileOutputStream outputStream = new FileOutputStream(file); + Result result = new StreamResult(new OutputStreamWriter(outputStream)); + + // + // 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 (ParserConfigurationException ex) { + GenBuildException e = new GenBuildException("Generating the module [" + fpdModuleId.getModule().getName() + "] build.xml file failed!.\n" + ex.getMessage()); + e.setStackTrace(ex.getStackTrace()); + throw e; + } catch (FileNotFoundException ex) { + GenBuildException e = new GenBuildException("Generating the module [" + fpdModuleId.getModule().getName() + "] build.xml file failed!.\n" + ex.getMessage()); + e.setStackTrace(ex.getStackTrace()); + throw e; + } catch (TransformerConfigurationException ex) { + GenBuildException e = new GenBuildException("Generating the module [" + fpdModuleId.getModule().getName() + "] build.xml file failed!.\n" + ex.getMessage()); + e.setStackTrace(ex.getStackTrace()); + throw e; + } catch (TransformerException ex) { + GenBuildException e = new GenBuildException("Generating the module [" + fpdModuleId.getModule().getName() + "] build.xml file failed!.\n" + ex.getMessage()); + e.setStackTrace(ex.getStackTrace()); + throw e; + } + } + + /** + Generate the clean elements for BaseName_build.xml. + + @param document current BaseName_build.xml XML document + @param root Root element for current + **/ + private void applyCleanElement(Document document, Node root) { + // + // + // + // + // + Element deleteEle = document.createElement("delete"); + deleteEle.setAttribute("includeemptydirs", "true"); + Element filesetEle = document.createElement("fileset"); + filesetEle.setAttribute("dir", "${DEST_DIR_OUTPUT}"); + filesetEle.setAttribute("includes", "**/*"); + filesetEle.setAttribute("excludes", "*.xml"); + deleteEle.appendChild(filesetEle); + root.appendChild(deleteEle); + } + + /** + Generate the cleanall elements for BaseName_build.xml. + + @param document current BaseName_build.xml XML document + @param root Root element for current + **/ + private void applyDeepcleanElement(Document document, Node root) { + // + // + // + // + // + Element deleteEle = document.createElement("delete"); + deleteEle.setAttribute("includeemptydirs", "true"); + Element filesetEle = document.createElement("fileset"); + filesetEle.setAttribute("dir", "${DEST_DIR_OUTPUT}"); + filesetEle.setAttribute("includes", "**/*"); + filesetEle.setAttribute("excludes", "*.xml"); + deleteEle.appendChild(filesetEle); + root.appendChild(deleteEle); + + // + // + // + // + // + deleteEle = document.createElement("delete"); + deleteEle.setAttribute("includeemptydirs", "true"); + filesetEle = document.createElement("fileset"); + filesetEle.setAttribute("dir", "${DEST_DIR_DEBUG}"); + filesetEle.setAttribute("includes", "**/*"); + deleteEle.appendChild(filesetEle); + root.appendChild(deleteEle); + } + + /** + Generate the dependent library instances elements for BaseName_build.xml. + + @param document current BaseName_build.xml XML document + @param root Root element for current + **/ + private void applyLibraryInstance(Document document, Node root) throws EdkException { + ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch()); + for (int i = 0; i < libinstances.length; i++) { + // + // Put package file path to module identification + // + PackageIdentification packageId = libinstances[i].getPackage(); + + // + // Generate ANT script to build library instances + // + Element ele = document.createElement("GenBuild"); + ele.setAttribute("type", "build"); + + // + // Prepare pass down information + // + Map passDownMap = new LinkedHashMap(); + for (int j = 0; j < inheritProperties.length; j ++){ + passDownMap.put(inheritProperties[j], "${" + inheritProperties[j] + "}"); + } + + passDownMap.put("MODULE_GUID", libinstances[i].getGuid()); + passDownMap.put("MODULE_VERSION", libinstances[i].getVersion()); + + passDownMap.put("PACKAGE_GUID", packageId.getGuid()); + passDownMap.put("PACKAGE_VERSION", packageId.getVersion()); + + for (int j = 0; j < inheritProperties.length; j ++){ + Element property = document.createElement("property"); + property.setAttribute("name", inheritProperties[j]); + property.setAttribute("value", passDownMap.get(inheritProperties[j])); + ele.appendChild(property); + } + + root.appendChild(ele); + } + } + + /** + Generate the build source files elements for BaseName_build.xml. + + @param document current BaseName_build.xml XML document + @param root Root element for current + **/ + private void applyCompileElement(Document document, Node root) { + // + // sourceFiles[][0] is FileType, [][1] is File name relative to Module_Dir + // + String[][] sourceFiles = saq.getSourceFiles(fpdModuleId.getArch()); + + FileProcess fileProcess = new FileProcess(); + fileProcess.init(project, includes, document); + + // + // Initialize some properties by user + // + Element initEle = document.createElement("Build_Init"); + root.appendChild(initEle); + + String moduleDir = project.getProperty("MODULE_DIR"); + // + // Parse all Unicode files + // + for (int i = 0; i < sourceFiles.length; i++) { + // + // Go through all source files. Add MODULE_DIR to preffix + // + File sourceFile = new File(moduleDir + File.separatorChar + sourceFiles[i][1]); + sourceFiles[i][1] = sourceFile.getPath(); + String filetype = sourceFiles[i][0]; + if (filetype != null) { + fileProcess.parseFile(sourceFiles[i][1], filetype, root, true); + } else { + fileProcess.parseFile(sourceFiles[i][1], root, true); + } + } + + // + // If exist Unicode file + // + if (fileProcess.isUnicodeExist()) { + Element ele = document.createElement("Build_Unicode_Database"); + ele.setAttribute("FILEPATH", "."); + ele.setAttribute("FILENAME", "${BASE_NAME}"); + Element includesEle = document.createElement("EXTRA.INC"); + for (int i = 0; i < includes.length; i++) { + Element includeEle = document.createElement("includepath"); + includeEle.setAttribute("path", includes[i]); + includesEle.appendChild(includeEle); + } + ele.appendChild(includesEle); + root.appendChild(ele); + } + + // + // Parse AutoGen.c & AutoGen.h + // + if ( ! fpdModuleId.getModule().getName().equalsIgnoreCase("Shell")) { + fileProcess.parseFile(project.getProperty("DEST_DIR_DEBUG") + File.separatorChar + "AutoGen.c", root, false); + } + + // + // Parse all source files but Unicode files + // + for (int i = 0; i < sourceFiles.length; i++) { + String filetype = sourceFiles[i][0]; + if (filetype != null) { + fileProcess.parseFile(sourceFiles[i][1], filetype, root, false); + } else { + fileProcess.parseFile(sourceFiles[i][1], root, false); + } + } + + // + // Initialize SOURCE_FILES for dependcy check use + // + String str = ""; + for (int i = 0; i < sourceFiles.length; i++) { + str += " " + sourceFiles[i][1]; + } + project.setProperty("SOURCE_FILES", str.replaceAll("(\\\\)", "/")); + } + + /** + Generate the section elements for BaseName_build.xml. Library module will + skip this process. + + @param document current BaseName_build.xml XML document + @param root Root element for current + **/ + private void applySectionsElement(Document document, Node root, FfsProcess fp) { + if (fpdModuleId.getModule().isLibrary()) { + return ; + } + if (fp.initSections(ffsKeyword, project, fpdModuleId)) { + String targetFilename = fpdModuleId.getModule().getGuid() + "-" + "${BASE_NAME}" + FpdParserTask.getSuffix(fpdModuleId.getModule().getModuleType()); + String[] list = fp.getGenSectionElements(document, "${BASE_NAME}", fpdModuleId.getModule().getGuid(), targetFilename); + + for (int i = 0; i < list.length; i++) { + Element ele = document.createElement(list[i]); + ele.setAttribute("FILEPATH", "."); + ele.setAttribute("FILENAME", "${BASE_NAME}"); + root.appendChild(ele); + } + } + } + + /** + Generate the output elements for BaseName_build.xml. If module is library, + call the LIB command, else call the GenFfs command. + + @param document current BaseName_build.xml XML document + @param root Root element for current + **/ + private void applyOutputElement(Document document, Node root, FfsProcess fp) { + if (fpdModuleId.getModule().isLibrary()) { + // + // call Lib command + // + Element cc = document.createElement("Build_Library"); + cc.setAttribute("FILENAME", fpdModuleId.getModule().getName()); + root.appendChild(cc); + } + // + // if it is a module but library + // + else { + if (fp.getFfsNode() != null) { + root.appendChild(fp.getFfsNode()); + } + } + } + +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java b/Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java new file mode 100644 index 0000000000..0d757b923b --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java @@ -0,0 +1,2188 @@ +/** @file + AutoGen class. + + This class is to generate Autogen.h and Autogen.c according to module surface area + or library surface area. + + 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.autogen; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.tools.ant.BuildException; +import org.apache.xmlbeans.XmlObject; +import org.tianocore.build.exception.AutoGenException; +import org.tianocore.build.global.GlobalData; +import org.tianocore.build.global.SurfaceAreaQuery; +import org.tianocore.build.id.ModuleIdentification; +import org.tianocore.build.id.PackageIdentification; +import org.tianocore.build.pcd.action.PCDAutoGenAction; +import org.tianocore.common.definitions.ToolDefinitions; +import org.tianocore.common.definitions.EdkDefinitions; +import org.tianocore.common.exception.EdkException; +import org.tianocore.common.logger.EdkLog; + +/** + This class is to generate Autogen.h and Autogen.c according to module surface + area or library surface area. +**/ +public class AutoGen { + /// + /// The output path of Autogen.h and Autogen.c + /// + private String outputPath; + + /// + /// The name of FV directory + /// + private String fvDir; + + /// + /// The base name of module or library. + /// + private ModuleIdentification moduleId; + + /// + /// The build architecture + /// + private String arch; + + /// + /// PcdAutogen instance which is used to manage how to generate the PCD + /// information. + /// + private PCDAutoGenAction myPcdAutogen; + + /// + /// the one of type : NOT_PCD_DRIVER, PEI_PCD_DRIVER, DXE_PCD_DRIVER + /// + private CommonDefinition.PCD_DRIVER_TYPE pcdDriverType; + + /// + /// The protocl list which records in module or library surface area and + /// it's dependence on library instance surface area. + /// + private Set mProtocolList = new HashSet(); + + /// + /// The Ppi list which recorded in module or library surface area and its + /// dependency on library instance surface area. + /// + private Set mPpiList = new HashSet(); + + /// + /// The Guid list which recoreded in module or library surface area and it's + /// dependence on library instance surface area. + /// + private Set mGuidList = new HashSet(); + + /// + /// The dependence package list which recoreded in module or library surface + /// area and it's dependence on library instance surface area. + /// + private List mDepPkgList = new LinkedList(); + + /// + /// For non library module, add its library instance's construct and destructor to + /// list. String[0] recode LibConstructor name, String[1] recode Lib instance + /// module type. + /// + private List libConstructList = new ArrayList(); + private List libDestructList = new ArrayList(); + + /// + /// List to store SetVirtalAddressMapCallBack, ExitBootServiceCallBack + /// + private List setVirtalAddList = new ArrayList(); + private List exitBootServiceList = new ArrayList(); + + private SurfaceAreaQuery saq = null; + + private ModuleIdentification parentId = null; + + /** + Construct function + + This function mainly initialize some member variable. + + @param fvDir + Absolute path of FV directory. + @param outputPath + Output path of AutoGen file. + @param moduleId + Module identification. + @param arch + Target architecture. + **/ + public AutoGen(String fvDir, String outputPath, ModuleIdentification moduleId, String arch, SurfaceAreaQuery saq, ModuleIdentification parentId) { + this.outputPath = outputPath; + this.moduleId = moduleId; + this.arch = arch; + this.fvDir = fvDir; + this.saq = saq; + this.parentId = parentId; + } + + /** + saveFile function + + This function save the content in stringBuffer to file. + + @param fileName + The name of file. + @param fileBuffer + The content of AutoGen file in buffer. + @return boolean + "true" successful + "false" failed + **/ + private boolean saveFile(String fileName, StringBuffer fileBuffer) { + + File autoGenH = new File(fileName); + + // + // if the file exists, compare their content + // + if (autoGenH.exists()) { + char[] oldFileBuffer = new char[(int) autoGenH.length()]; + try { + FileReader fIn = new FileReader(autoGenH); + fIn.read(oldFileBuffer, 0, (int) autoGenH.length()); + fIn.close(); + } catch (IOException e) { + EdkLog.log(EdkLog.EDK_INFO, this.moduleId.getName() + + "'s " + + fileName + + " is exist, but can't be open!!"); + return false; + } + + // + // if we got the same file, don't re-generate it to prevent + // sources depending on it from re-building + // + if (fileBuffer.toString().compareTo(new String(oldFileBuffer)) == 0) { + return true; + } + } + + try { + FileWriter fOut = new FileWriter(autoGenH); + fOut.write(fileBuffer.toString()); + fOut.flush(); + fOut.close(); + } catch (IOException e) { + EdkLog.log(EdkLog.EDK_INFO, this.moduleId.getName() + + "'s " + + fileName + + " can't be create!!"); + return false; + } + return true; + } + + /** + genAutogen function + + This function call libGenAutoGen or moduleGenAutogen function, which + dependence on generate library autogen or module autogen. + + @throws BuildException + Failed to creat AutoGen.c & AutoGen.h. + **/ + public void genAutogen() throws EdkException { + try { + // + // If outputPath do not exist, create it. + // + File path = new File(outputPath); + path.mkdirs(); + } catch (Exception e) { + throw new AutoGenException( + "Failed to create " + + outputPath + " directory"); + } + + // + // Check current is library or not, then call the corresponding + // function. + // + if (this.moduleId.isLibrary()) { + libGenAutogen(); + } else { + moduleGenAutogen(); + } + } + + /** + moduleGenAutogen function + + This function generates AutoGen.c & AutoGen.h for module. + + @throws BuildException + Faile to create module AutoGen.c & AutoGen.h. + **/ + void moduleGenAutogen() throws EdkException { + collectLibInstanceInfo(); + moduleGenAutogenC(); + moduleGenAutogenH(); + } + + /** + libGenAutogen function + + This function generates AutoGen.c & AutoGen.h for library. + + @throws BuildException + Faile to create library AutoGen.c & AutoGen.h + **/ + void libGenAutogen() throws EdkException { + libGenAutogenC(); + libGenAutogenH(); + } + + /** + moduleGenAutogenH + + This function generates AutoGen.h for module. + + @throws BuildException + Failed to generate AutoGen.h. + **/ + void moduleGenAutogenH() throws EdkException { + + Set libClassIncludeH; + String moduleType; + // List headerFileList; + List headerFileList; + Iterator item; + StringBuffer fileBuffer = new StringBuffer(8192); + + // + // Write Autogen.h header notation + // + fileBuffer.append(CommonDefinition.AUTOGENHNOTATION); + + // + // Add #ifndef ${BaseName}_AUTOGENH + // #def ${BseeName}_AUTOGENH + // + fileBuffer.append(CommonDefinition.IFNDEF + + CommonDefinition.AUTOGENH + + this.moduleId.getGuid().replaceAll("-", "_") + + ToolDefinitions.LINE_SEPARATOR); + fileBuffer.append(CommonDefinition.DEFINE + + CommonDefinition.AUTOGENH + + this.moduleId.getGuid().replaceAll("-", "_") + + ToolDefinitions.LINE_SEPARATOR + + ToolDefinitions.LINE_SEPARATOR); + + // + // Write the specification version and release version at the begine + // of autogen.h file. + // Note: the specification version and release version should + // be got from module surface area instead of hard code by it's + // moduleType. + // + moduleType = saq.getModuleType(); + + // + // Add "extern int __make_me_compile_correctly;" at begin of + // AutoGen.h. + // + fileBuffer.append(CommonDefinition.AUTOGENHBEGIN); + + // + // Put EFI_SPECIFICATION_VERSION, and EDK_RELEASE_VERSION. + // + String[] specList = saq.getExternSpecificaiton(); + for (int i = 0; i < specList.length; i++) { + fileBuffer.append(CommonDefinition.DEFINE + specList[i] + + "\r\n"); + } + // + // Write consumed package's mdouleInfo related .h file to autogen.h + // + // PackageIdentification[] consumedPkgIdList = SurfaceAreaQuery + // .getDependencePkg(this.arch); + PackageIdentification[] consumedPkgIdList = saq.getDependencePkg(this.arch); + if (consumedPkgIdList != null) { + headerFileList = depPkgToAutogenH(consumedPkgIdList, moduleType); + item = headerFileList.iterator(); + while (item.hasNext()) { + fileBuffer.append(item.next().toString()); + } + } + + // + // Write library class's related *.h file to autogen.h. + // + String[] libClassList = saq.getLibraryClasses(CommonDefinition.ALWAYSCONSUMED,this.arch); + if (libClassList != null) { + libClassIncludeH = LibraryClassToAutogenH(libClassList); + item = libClassIncludeH.iterator(); + while (item.hasNext()) { + fileBuffer.append(item.next().toString()); + } + } + + libClassList = saq.getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, this.arch); + if (libClassList != null) { + libClassIncludeH = LibraryClassToAutogenH(libClassList); + item = libClassIncludeH.iterator(); + while (item.hasNext()) { + fileBuffer.append(item.next().toString()); + } + } + fileBuffer.append("\r\n"); + + // + // If is TianoR8FlashMap, copy {Fv_DIR}/FlashMap.h to + // {DEST_DIR_DRBUG}/FlashMap.h + // + if (saq.isHaveTianoR8FlashMap()) { + fileBuffer.append(CommonDefinition.INCLUDE); + fileBuffer.append(" <"); + fileBuffer.append(CommonDefinition.TIANOR8PLASHMAPH + ">\r\n"); + copyFlashMapHToDebugDir(); + } + + // Write PCD autogen information to AutoGen.h. + // + if (this.myPcdAutogen != null) { + fileBuffer.append("\r\n"); + fileBuffer.append(this.myPcdAutogen.getHAutoGenString()); + } + + // + // Append the #endif at AutoGen.h + // + fileBuffer.append("#endif\r\n"); + + // + // Save string buffer content in AutoGen.h. + // + if (!saveFile(outputPath + File.separatorChar + "AutoGen.h", fileBuffer)) { + throw new AutoGenException("Failed to generate AutoGen.h !!!"); + } + } + + /** + moduleGenAutogenC + + This function generates AutoGen.c for module. + + @throws BuildException + Failed to generate AutoGen.c. + **/ + void moduleGenAutogenC() throws EdkException { + + StringBuffer fileBuffer = new StringBuffer(8192); + // + // Write Autogen.c header notation + // + fileBuffer.append(CommonDefinition.AUTOGENCNOTATION); + + // + // Write #include at beginning of AutoGen.c + // + fileBuffer.append(CommonDefinition.INCLUDEAUTOGENH); + + // + // Get the native MSA file infomation. Since before call autogen, + // the MSA native information were overrided. So before + // process it should be set the DOC as the Native MSA info. + // + Map doc = GlobalData.getNativeMsa(this.moduleId); + saq.push(doc); + // + // Write + // DriverBinding/ComponentName/DriverConfiguration/DriverDialog + // to AutoGen.c + // + + ExternsDriverBindingToAutoGenC(fileBuffer); + + // + // Write DriverExitBootServicesEvent/DriverSetVirtualAddressMapEvent + // to Autogen.c + // + ExternCallBackToAutoGenC(fileBuffer); + + // + // Write EntryPoint to autgoGen.c + // + String[] entryPointList = saq.getModuleEntryPointArray(); + String[] unloadImageList = saq.getModuleUnloadImageArray(); + EntryPointToAutoGen(CommonDefinition.remDupString(entryPointList), + CommonDefinition.remDupString(unloadImageList), + fileBuffer); + + pcdDriverType = saq.getPcdDriverType(); + + // + // Restore the DOC which include the FPD module info. + // + saq.pop(); + + // + // Write Guid to autogen.c + // + String guid = CommonDefinition.formatGuidName(saq.getModuleGuid()); + if (this.moduleId.getModuleType().equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) { + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = {"); + } else { + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiCallerIdGuid = {"); + } + + if (guid == null) { + throw new AutoGenException("Guid value must set!\n"); + } + + // + // Formate Guid as ANSI c form.Example: + // {0xd2b2b828, 0x826, 0x48a7,{0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, + // 0xf0}} + // + + fileBuffer.append(guid); + fileBuffer.append("};\r\n"); + + // + // Generate library instance consumed protocol, guid, ppi, pcd list. + // Save those to this.protocolList, this.ppiList, this.pcdList, + // this.guidList. Write Consumed library constructor and desconstuct to + // autogen.c + // + LibInstanceToAutogenC(fileBuffer); + + // + // Get module dependent Package identification. + // + PackageIdentification[] packages = saq.getDependencePkg(this.arch); + for (int i = 0; i < packages.length; i++) { + if (!this.mDepPkgList.contains(packages[i])) { + this.mDepPkgList.add(packages[i]); + } + + } + + // + // Write consumed ppi, guid, protocol to autogen.c + // + ProtocolGuidToAutogenC(fileBuffer); + PpiGuidToAutogenC(fileBuffer); + GuidGuidToAutogenC(fileBuffer); + + // + // Call pcd autogen. + // + this.myPcdAutogen = new PCDAutoGenAction(moduleId, + arch, + false, + null, + pcdDriverType, + parentId); + + this.myPcdAutogen.execute(); + if (this.myPcdAutogen != null) { + fileBuffer.append("\r\n"); + fileBuffer.append(this.myPcdAutogen.getCAutoGenString()); + } + + if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) { + throw new AutoGenException("Failed to generate AutoGen.c !!!"); + } + + } + + /** + libGenAutogenH + + This function generates AutoGen.h for library. + + @throws BuildException + Failed to generate AutoGen.c. + **/ + void libGenAutogenH() throws EdkException { + + Set libClassIncludeH; + String moduleType; + List headerFileList; + Iterator item; + StringBuffer fileBuffer = new StringBuffer(10240); + + // + // Write Autogen.h header notation + // + fileBuffer.append(CommonDefinition.AUTOGENHNOTATION); + + // + // Add #ifndef ${BaseName}_AUTOGENH + // #def ${BseeName}_AUTOGENH + // + fileBuffer.append(CommonDefinition.IFNDEF + + CommonDefinition.AUTOGENH + + this.moduleId.getGuid().replaceAll("-", "_") + + ToolDefinitions.LINE_SEPARATOR); + fileBuffer.append(CommonDefinition.DEFINE + + CommonDefinition.AUTOGENH + + this.moduleId.getGuid().replaceAll("-", "_") + + ToolDefinitions.LINE_SEPARATOR + + ToolDefinitions.LINE_SEPARATOR); + + // + // Write EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION + // to autogen.h file. + // Note: the specification version and release version should + // be get from module surface area instead of hard code. + // + fileBuffer.append(CommonDefinition.AUTOGENHBEGIN); + String[] specList = saq.getExternSpecificaiton(); + for (int i = 0; i < specList.length; i++) { + fileBuffer.append(CommonDefinition.DEFINE + specList[i] + + "\r\n"); + } + // fileBuffer.append(CommonDefinition.autoGenHLine1); + // fileBuffer.append(CommonDefinition.autoGenHLine2); + + // + // Write consumed package's mdouleInfo related *.h file to autogen.h. + // + moduleType = saq.getModuleType(); + PackageIdentification[] cosumedPkglist = saq + .getDependencePkg(this.arch); + headerFileList = depPkgToAutogenH(cosumedPkglist, moduleType); + item = headerFileList.iterator(); + while (item.hasNext()) { + fileBuffer.append(item.next().toString()); + } + // + // Write library class's related *.h file to autogen.h + // + String[] libClassList = saq + .getLibraryClasses(CommonDefinition.ALWAYSCONSUMED, this.arch); + if (libClassList != null) { + libClassIncludeH = LibraryClassToAutogenH(libClassList); + item = libClassIncludeH.iterator(); + while (item.hasNext()) { + fileBuffer.append(item.next().toString()); + } + } + + libClassList = saq + .getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, this.arch); + if (libClassList != null) { + libClassIncludeH = LibraryClassToAutogenH(libClassList); + item = libClassIncludeH.iterator(); + while (item.hasNext()) { + fileBuffer.append(item.next().toString()); + } + } + fileBuffer.append(ToolDefinitions.LINE_SEPARATOR); + + // + // If is TianoR8FlashMap, copy {Fv_DIR}/FlashMap.h to + // {DEST_DIR_DRBUG}/FlashMap.h + // + if (saq.isHaveTianoR8FlashMap()) { + fileBuffer.append(CommonDefinition.INCLUDE); + fileBuffer.append(" <"); + fileBuffer.append(CommonDefinition.TIANOR8PLASHMAPH + ">\r\n"); + copyFlashMapHToDebugDir(); + } + + // + // Write PCD information to library AutoGen.h. + // + if (this.myPcdAutogen != null) { + fileBuffer.append("\r\n"); + fileBuffer.append(this.myPcdAutogen.getHAutoGenString()); + } + + // + // Append the #endif at AutoGen.h + // + fileBuffer.append("#endif\r\n"); + + // + // Save content of string buffer to AutoGen.h file. + // + if (!saveFile(outputPath + File.separatorChar + "AutoGen.h", fileBuffer)) { + throw new AutoGenException("Failed to generate AutoGen.h !!!"); + } + } + + /** + libGenAutogenC + + This function generates AutoGen.h for library. + + @throws BuildException + Failed to generate AutoGen.c. + **/ + void libGenAutogenC() throws EdkException { + StringBuffer fileBuffer = new StringBuffer(10240); + + // + // Write Autogen.c header notation + // + fileBuffer.append(CommonDefinition.AUTOGENCNOTATION); + + fileBuffer.append(ToolDefinitions.LINE_SEPARATOR); + fileBuffer.append(ToolDefinitions.LINE_SEPARATOR); + + // + // Call pcd autogen. + // + this.myPcdAutogen = new PCDAutoGenAction(moduleId, + arch, + true, + saq.getModulePcdEntryNameArray(), + pcdDriverType, + parentId); + this.myPcdAutogen.execute(); + if (this.myPcdAutogen != null) { + fileBuffer.append(ToolDefinitions.LINE_SEPARATOR); + fileBuffer.append(this.myPcdAutogen.getCAutoGenString()); + } + + if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) { + throw new AutoGenException("Failed to generate AutoGen.c !!!"); + } + } + + /** + LibraryClassToAutogenH + + This function returns *.h files declared by library classes which are + consumed or produced by current build module or library. + + @param libClassList + List of library class which consumed or produce by current + build module or library. + @return includeStrList List of *.h file. + **/ + Set LibraryClassToAutogenH(String[] libClassList) + throws EdkException { + Set includeStrList = new LinkedHashSet(); + String includeName[]; + String str = ""; + + // + // Get include file from GlobalData's SPDTable according to + // library class name. + // + for (int i = 0; i < libClassList.length; i++) { + includeName = GlobalData.getLibraryClassHeaderFiles( + saq.getDependencePkg(this.arch), + libClassList[i]); + if (includeName == null) { + throw new AutoGenException("Can not find library class [" + + libClassList[i] + "] declaration in any SPD package. "); + } + for (int j = 0; j < includeName.length; j++) { + String includeNameStr = includeName[j]; + if (includeNameStr != null) { + str = CommonDefinition.INCLUDE + " " + "<"; + str = str + includeNameStr + ">\r\n"; + includeStrList.add(str); + includeNameStr = null; + } + } + } + return includeStrList; + } + + /** + IncludesToAutogenH + + This function add include file in AutoGen.h file. + + @param packageNameList + List of module depended package. + @param moduleType + Module type. + @return + **/ + List depPkgToAutogenH(PackageIdentification[] packageNameList, + String moduleType) throws AutoGenException { + + List includeStrList = new LinkedList(); + String pkgHeader; + String includeStr = ""; + + // + // Get include file from moduleInfo file + // + for (int i = 0; i < packageNameList.length; i++) { + pkgHeader = GlobalData.getPackageHeaderFiles(packageNameList[i], + moduleType); + if (pkgHeader == null) { + throw new AutoGenException("Can not find package [" + + packageNameList[i] + + "] declaration in any SPD package. "); + } else if (!pkgHeader.equalsIgnoreCase("")) { + includeStr = CommonDefinition.INCLUDE + " <" + pkgHeader + + ">\r\n"; + includeStrList.add(includeStr); + } + } + + return includeStrList; + } + + /** + EntryPointToAutoGen + + This function convert & + information in mas to AutoGen.c + + @param entryPointList + List of entry point. + @param fileBuffer + String buffer fo AutoGen.c. + @throws Exception + **/ + void EntryPointToAutoGen(String[] entryPointList, String[] unloadImageList, StringBuffer fileBuffer) + throws EdkException { + + String typeStr = saq.getModuleType(); + int unloadImageCount = 0; + int entryPointCount = 0; + + // + // The parameters and return value of entryPoint is difference + // for difference module type. + // + switch (CommonDefinition.getModuleType(typeStr)) { + + case CommonDefinition.ModuleTypePeiCore: + if (entryPointList == null ||entryPointList.length != 1 ) { + throw new AutoGenException( + "Module type = 'PEI_CORE', can have only one module entry point!"); + } else { + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append(entryPointList[0]); + fileBuffer.append(" (\r\n"); + fileBuffer + .append(" IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,\r\n"); + fileBuffer + .append(" IN VOID *OldCoreData\r\n"); + fileBuffer.append(" );\r\n\r\n"); + + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessModuleEntryPointList (\r\n"); + fileBuffer + .append(" IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,\r\n"); + fileBuffer + .append(" IN VOID *OldCoreData\r\n"); + fileBuffer.append(" )\r\n\r\n"); + fileBuffer.append("{\r\n"); + fileBuffer.append(" return "); + fileBuffer.append(entryPointList[0]); + fileBuffer.append(" (PeiStartupDescriptor, OldCoreData);\r\n"); + fileBuffer.append("}\r\n\r\n"); + } + break; + + case CommonDefinition.ModuleTypeDxeCore: + fileBuffer.append("const UINT32 _gUefiDriverRevision = 0;\r\n"); + if (entryPointList == null || entryPointList.length != 1) { + throw new AutoGenException( + "Module type = 'DXE_CORE', can have only one module entry point!"); + } else { + + fileBuffer.append("VOID\r\n"); + fileBuffer.append(entryPointList[0]); + fileBuffer.append(" (\n"); + fileBuffer.append(" IN VOID *HobStart\r\n"); + fileBuffer.append(" );\r\n\r\n"); + + fileBuffer.append("VOID\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessModuleEntryPointList (\r\n"); + fileBuffer.append(" IN VOID *HobStart\r\n"); + fileBuffer.append(" )\r\n\r\n"); + fileBuffer.append("{\r\n"); + fileBuffer.append(" "); + fileBuffer.append(entryPointList[0]); + fileBuffer.append(" (HobStart);\r\n"); + fileBuffer.append("}\r\n\r\n"); + } + break; + + case CommonDefinition.ModuleTypePeim: + entryPointCount = 0; + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;\r\n"); + if (entryPointList == null || entryPointList.length == 0) { + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessModuleEntryPointList (\r\n"); + fileBuffer.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n"); + fileBuffer.append(" IN EFI_PEI_SERVICES **PeiServices\r\n"); + fileBuffer.append(" )\r\n\r\n"); + fileBuffer.append("{\r\n"); + fileBuffer.append(" return EFI_SUCCESS;\r\n"); + fileBuffer.append("}\r\n\r\n"); + break; + } + for (int i = 0; i < entryPointList.length; i++) { + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append(entryPointList[i]); + fileBuffer.append(" (\r\n"); + fileBuffer + .append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n"); + fileBuffer + .append(" IN EFI_PEI_SERVICES **PeiServices\r\n"); + fileBuffer.append(" );\r\n"); + entryPointCount++; + + } + + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessModuleEntryPointList (\r\n"); + fileBuffer.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n"); + fileBuffer.append(" IN EFI_PEI_SERVICES **PeiServices\r\n"); + fileBuffer.append(" )\r\n\r\n"); + fileBuffer.append("{\r\n"); + if (entryPointCount == 1) { + fileBuffer.append(" return "); + fileBuffer.append(entryPointList[0]); + fileBuffer.append(" (FfsHeader, PeiServices);\r\n"); + } else { + fileBuffer.append(" EFI_STATUS Status;\r\n"); + fileBuffer.append(" EFI_STATUS CombinedStatus;\r\n\r\n"); + fileBuffer.append(" CombinedStatus = EFI_LOAD_ERROR;\r\n\r\n"); + for (int i = 0; i < entryPointList.length; i++) { + if (!entryPointList[i].equals("")) { + fileBuffer.append(" Status = "); + fileBuffer.append(entryPointList[i]); + fileBuffer.append(" (FfsHeader, PeiServices);\r\n"); + fileBuffer + .append(" if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {\r\n"); + fileBuffer.append(" CombinedStatus = Status;\r\n"); + fileBuffer.append(" }\r\n\r\n"); + } else { + break; + } + } + fileBuffer.append(" return CombinedStatus;\r\n"); + } + fileBuffer.append("}\r\n\r\n"); + break; + + case CommonDefinition.ModuleTypeDxeSmmDriver: + entryPointCount = 0; + // + // If entryPoint is null, create an empty ProcessModuleEntryPointList + // function. + // + if (entryPointList == null || entryPointList.length == 0) { + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = "); + fileBuffer.append(Integer.toString(entryPointCount)); + fileBuffer.append(";\r\n"); + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessModuleEntryPointList (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n"); + fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n"); + fileBuffer.append(" )\r\n\r\n"); + fileBuffer.append("{\r\n"); + fileBuffer.append(" return EFI_SUCCESS;\r\n"); + fileBuffer.append("}\r\n\r\n"); + + } else { + for (int i = 0; i < entryPointList.length; i++) { + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append(entryPointList[i]); + fileBuffer.append(" (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n"); + fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n"); + fileBuffer.append(" );\r\n"); + entryPointCount++; + } + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = "); + fileBuffer.append(Integer.toString(entryPointCount)); + fileBuffer.append(";\r\n"); + fileBuffer + .append("static BASE_LIBRARY_JUMP_BUFFER mJumpContext;\r\n"); + fileBuffer + .append("static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n\r\n"); + + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessModuleEntryPointList (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n"); + fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n"); + fileBuffer.append(" )\r\n\r\n"); + fileBuffer.append("{\r\n"); + + + for (int i = 0; i < entryPointList.length; i++) { + fileBuffer + .append(" if (SetJump (&mJumpContext) == 0) {\r\n"); + fileBuffer.append(" ExitDriver ("); + fileBuffer.append(entryPointList[i]); + fileBuffer.append(" (ImageHandle, SystemTable));\r\n"); + fileBuffer.append(" ASSERT (FALSE);\r\n"); + fileBuffer.append(" }\r\n"); + + } + fileBuffer.append(" return mDriverEntryPointStatus;\r\n"); + fileBuffer.append("}\r\n\r\n"); + + fileBuffer.append("VOID\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ExitDriver (\r\n"); + fileBuffer.append(" IN EFI_STATUS Status\n"); + fileBuffer.append(" )\r\n\r\n"); + fileBuffer.append("{\r\n"); + fileBuffer + .append(" if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n"); + fileBuffer.append(" mDriverEntryPointStatus = Status;\r\n"); + fileBuffer.append(" }\r\n"); + fileBuffer.append(" LongJump (&mJumpContext, (UINTN)-1);\r\n"); + fileBuffer.append(" ASSERT (FALSE);\r\n"); + fileBuffer.append("}\r\n\r\n"); + + } + + + // + // Add "ModuleUnloadImage" for DxeSmmDriver module type; + // + //entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray(); + //entryPointList = CommonDefinition.remDupString(entryPointList); + //entryPointCount = 0; + + unloadImageCount = 0; + if (unloadImageList != null) { + for (int i = 0; i < unloadImageList.length; i++) { + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append(unloadImageList[i]); + fileBuffer.append(" (\r\n"); + fileBuffer + .append(" IN EFI_HANDLE ImageHandle\r\n"); + fileBuffer.append(" );\r\n"); + unloadImageCount++; + } + } + + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = "); + fileBuffer.append(Integer.toString(unloadImageCount)); + fileBuffer.append(";\r\n\r\n"); + + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessModuleUnloadList (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle\r\n"); + fileBuffer.append(" )\r\n"); + fileBuffer.append("{\r\n"); + + if (unloadImageCount == 0) { + fileBuffer.append(" return EFI_SUCCESS;\r\n"); + } else if (unloadImageCount == 1) { + fileBuffer.append(" return "); + fileBuffer.append(unloadImageList[0]); + fileBuffer.append("(ImageHandle);\r\n"); + } else { + fileBuffer.append(" EFI_STATUS Status;\r\n\r\n"); + fileBuffer.append(" Status = EFI_SUCCESS;\r\n\r\n"); + for (int i = 0; i < unloadImageList.length; i++) { + if (i == 0) { + fileBuffer.append(" Status = "); + fileBuffer.append(unloadImageList[i]); + fileBuffer.append("(ImageHandle);\r\n"); + } else { + fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n"); + fileBuffer.append(" "); + fileBuffer.append(unloadImageList[i]); + fileBuffer.append("(ImageHandle);\r\n"); + fileBuffer.append(" } else {\r\n"); + fileBuffer.append(" Status = "); + fileBuffer.append(unloadImageList[i]); + fileBuffer.append("(ImageHandle);\r\n"); + fileBuffer.append(" }\r\n"); + } + } + fileBuffer.append(" return Status;\r\n"); + } + fileBuffer.append("}\r\n\r\n"); + break; + + case CommonDefinition.ModuleTypeDxeRuntimeDriver: + case CommonDefinition.ModuleTypeDxeDriver: + case CommonDefinition.ModuleTypeDxeSalDriver: + case CommonDefinition.ModuleTypeUefiDriver: + case CommonDefinition.ModuleTypeUefiApplication: + entryPointCount = 0; + fileBuffer.append("const UINT32 _gUefiDriverRevision = 0;\r\n"); + // + // If entry point is null, create a empty ProcessModuleEntryPointList function. + // + if (entryPointList == null || entryPointList.length == 0) { + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = 0;\r\n"); + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessModuleEntryPointList (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n"); + fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n"); + fileBuffer.append(" )\r\n\r\n"); + fileBuffer.append("{\r\n"); + fileBuffer.append(" return EFI_SUCCESS;\r\n"); + fileBuffer.append("}\r\n"); + + } else { + for (int i = 0; i < entryPointList.length; i++) { + + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append(entryPointList[i]); + fileBuffer.append(" (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n"); + fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n"); + fileBuffer.append(" );\r\n"); + entryPointCount++; + } + + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = "); + fileBuffer.append(Integer.toString(entryPointCount)); + fileBuffer.append(";\r\n"); + if (entryPointCount > 1) { + fileBuffer + .append("static BASE_LIBRARY_JUMP_BUFFER mJumpContext;\r\n"); + fileBuffer + .append("static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n"); + } + fileBuffer.append("\n"); + + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessModuleEntryPointList (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n"); + fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n"); + fileBuffer.append(" )\r\n\r\n"); + fileBuffer.append("{\r\n"); + + if (entryPointCount == 1) { + fileBuffer.append(" return ("); + fileBuffer.append(entryPointList[0]); + fileBuffer.append(" (ImageHandle, SystemTable));\r\n"); + } else { + for (int i = 0; i < entryPointList.length; i++) { + if (!entryPointList[i].equals("")) { + fileBuffer + .append(" if (SetJump (&mJumpContext) == 0) {\r\n"); + fileBuffer.append(" ExitDriver ("); + fileBuffer.append(entryPointList[i]); + fileBuffer.append(" (ImageHandle, SystemTable));\r\n"); + fileBuffer.append(" ASSERT (FALSE);\r\n"); + fileBuffer.append(" }\r\n"); + } else { + break; + } + } + fileBuffer.append(" return mDriverEntryPointStatus;\r\n"); + } + fileBuffer.append("}\r\n\r\n"); + + fileBuffer.append("VOID\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ExitDriver (\r\n"); + fileBuffer.append(" IN EFI_STATUS Status\r\n"); + fileBuffer.append(" )\r\n\r\n"); + fileBuffer.append("{\r\n"); + if (entryPointCount <= 1) { + fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n"); + fileBuffer + .append(" ProcessLibraryDestructorList (gImageHandle, gST);\r\n"); + fileBuffer.append(" }\r\n"); + fileBuffer + .append(" gBS->Exit (gImageHandle, Status, 0, NULL);\r\n"); + } else { + fileBuffer + .append(" if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n"); + fileBuffer.append(" mDriverEntryPointStatus = Status;\r\n"); + fileBuffer.append(" }\r\n"); + fileBuffer.append(" LongJump (&mJumpContext, (UINTN)-1);\r\n"); + fileBuffer.append(" ASSERT (FALSE);\r\n"); + } + fileBuffer.append("}\r\n\r\n"); + + } + + // + // Add ModuleUnloadImage for DxeDriver and UefiDriver module type. + // + //entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray(); + // + // Remover duplicate unload entry point. + // + //entryPointList = CommonDefinition.remDupString(entryPointList); + //entryPointCount = 0; + unloadImageCount = 0; + if (unloadImageList != null) { + for (int i = 0; i < unloadImageList.length; i++) { + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(unloadImageList[i]); + fileBuffer.append(" (\r\n"); + fileBuffer + .append(" IN EFI_HANDLE ImageHandle\r\n"); + fileBuffer.append(" );\r\n"); + unloadImageCount++; + } + } + + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = "); + fileBuffer.append(Integer.toString(unloadImageCount)); + fileBuffer.append(";\r\n\r\n"); + + fileBuffer.append("EFI_STATUS\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessModuleUnloadList (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle\r\n"); + fileBuffer.append(" )\r\n"); + fileBuffer.append("{\r\n"); + + if (unloadImageCount == 0) { + fileBuffer.append(" return EFI_SUCCESS;\r\n"); + } else if (unloadImageCount == 1) { + fileBuffer.append(" return "); + fileBuffer.append(unloadImageList[0]); + fileBuffer.append("(ImageHandle);\r\n"); + } else { + fileBuffer.append(" EFI_STATUS Status;\r\n\r\n"); + fileBuffer.append(" Status = EFI_SUCCESS;\r\n\r\n"); + for (int i = 0; i < unloadImageList.length; i++) { + if (i == 0) { + fileBuffer.append(" Status = "); + fileBuffer.append(unloadImageList[i]); + fileBuffer.append("(ImageHandle);\r\n"); + } else { + fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n"); + fileBuffer.append(" "); + fileBuffer.append(unloadImageList[i]); + fileBuffer.append("(ImageHandle);\r\n"); + fileBuffer.append(" } else {\r\n"); + fileBuffer.append(" Status = "); + fileBuffer.append(unloadImageList[i]); + fileBuffer.append("(ImageHandle);\r\n"); + fileBuffer.append(" }\r\n"); + } + } + fileBuffer.append(" return Status;\r\n"); + } + fileBuffer.append("}\r\n\r\n"); + break; + } + } + + /** + PpiGuidToAutogenc + + This function gets GUIDs from SPD file accrodeing to information + and write those GUIDs to AutoGen.c. + + @param fileBuffer + String Buffer for Autogen.c file. + @throws BuildException + Guid must set value! + **/ + void PpiGuidToAutogenC(StringBuffer fileBuffer) throws AutoGenException { + String[] cNameGuid = null; + + // + // Get the all PPI adn PPI Notify from MSA file, + // then add those PPI ,and PPI Notify name to list. + // + + String[] ppiList = saq.getPpiArray(this.arch); + for (int i = 0; i < ppiList.length; i++) { + this.mPpiList.add(ppiList[i]); + } + + String[] ppiNotifyList = saq.getPpiNotifyArray(this.arch); + for (int i = 0; i < ppiNotifyList.length; i++) { + this.mPpiList.add(ppiNotifyList[i]); + } + + // + // Find CNAME and GUID from dependence SPD file and write to Autogen.c + // + Iterator ppiIterator = this.mPpiList.iterator(); + String ppiKeyWord = null; + while (ppiIterator.hasNext()) { + ppiKeyWord = ppiIterator.next().toString(); + cNameGuid = GlobalData.getPpiGuid(this.mDepPkgList, ppiKeyWord); + if (cNameGuid != null) { + fileBuffer + .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID "); + fileBuffer.append(cNameGuid[0]); + fileBuffer.append(" = { "); + fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1])); + fileBuffer.append(" } ;"); + } else { + // + // If can't find Ppi GUID declaration in every package + // + throw new AutoGenException("Can not find Ppi GUID [" + + ppiKeyWord + "] declaration in any SPD package!"); + } + } + } + + /** + ProtocolGuidToAutogenc + + This function gets GUIDs from SPD file accrodeing to + information and write those GUIDs to AutoGen.c. + + @param fileBuffer + String Buffer for Autogen.c file. + @throws BuildException + Protocol name must set. + **/ + void ProtocolGuidToAutogenC(StringBuffer fileBuffer) throws EdkException { + String[] cNameGuid = null; + + String[] protocolList = saq.getProtocolArray(this.arch); + + // + // Add result to Autogen global list. + // + for (int i = 0; i < protocolList.length; i++) { + this.mProtocolList.add(protocolList[i]); + } + + String[] protocolNotifyList = saq + .getProtocolNotifyArray(this.arch); + + for (int i = 0; i < protocolNotifyList.length; i++) { + this.mProtocolList.add(protocolNotifyList[i]); + } + + // + // Get the NAME and GUID from dependence SPD and write to Autogen.c + // + Iterator protocolIterator = this.mProtocolList.iterator(); + String protocolKeyWord = null; + + + while (protocolIterator.hasNext()) { + protocolKeyWord = protocolIterator.next().toString(); + cNameGuid = GlobalData.getProtocolGuid(this.mDepPkgList, protocolKeyWord); + if (cNameGuid != null) { + fileBuffer + .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID "); + fileBuffer.append(cNameGuid[0]); + fileBuffer.append(" = { "); + fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1])); + fileBuffer.append(" } ;"); + } else { + // + // If can't find protocol GUID declaration in every package + // + throw new AutoGenException("Can not find protocol Guid [" + + protocolKeyWord + "] declaration in any SPD package!"); + } + } + } + + /** + GuidGuidToAutogenc + + This function gets GUIDs from SPD file accrodeing to information + and write those GUIDs to AutoGen.c. + + @param fileBuffer + String Buffer for Autogen.c file. + + **/ + void GuidGuidToAutogenC(StringBuffer fileBuffer) throws AutoGenException { + String[] cNameGuid = null; + String guidKeyWord = null; + + String[] guidList = saq.getGuidEntryArray(this.arch); + + for (int i = 0; i < guidList.length; i++) { + this.mGuidList.add(guidList[i]); + } + + + Iterator guidIterator = this.mGuidList.iterator(); + while (guidIterator.hasNext()) { + guidKeyWord = guidIterator.next().toString(); + cNameGuid = GlobalData.getGuid(this.mDepPkgList, guidKeyWord); + + if (cNameGuid != null) { + fileBuffer + .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID "); + fileBuffer.append(cNameGuid[0]); + fileBuffer.append(" = { "); + fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1])); + fileBuffer.append("} ;"); + } else { + // + // If can't find GUID declaration in every package + // + throw new AutoGenException("Can not find Guid [" + guidKeyWord + + "] declaration in any SPD package. "); + } + + } + } + + /** + LibInstanceToAutogenC + + This function adds dependent library instance to autogen.c,which + includeing library's constructor, destructor, and library dependent ppi, + protocol, guid, pcd information. + + @param fileBuffer + String buffer for AutoGen.c + @throws BuildException + **/ + void LibInstanceToAutogenC(StringBuffer fileBuffer) throws EdkException { + String moduleType = this.moduleId.getModuleType(); + // + // Add library constructor to AutoGen.c + // + LibConstructorToAutogenC(libConstructList, moduleType, + fileBuffer/* autogenC */); + // + // Add library destructor to AutoGen.c + // + LibDestructorToAutogenC(libDestructList, moduleType, fileBuffer/* autogenC */); + } + + /** + LibConstructorToAutogenc + + This function writes library constructor list to AutoGen.c. The library + constructor's parameter and return value depend on module type. + + @param libInstanceList + List of library construct name. + @param moduleType + Module type. + @param fileBuffer + String buffer for AutoGen.c + @throws Exception + **/ + void LibConstructorToAutogenC(List libInstanceList, + String moduleType, StringBuffer fileBuffer) throws EdkException { + boolean isFirst = true; + + // + // The library constructor's parameter and return value depend on + // module type. + // + for (int i = 0; i < libInstanceList.size(); i++) { + if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) { + fileBuffer.append("RETURN_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append(" (\r\n"); + fileBuffer.append(" VOID\r\n"); + fileBuffer.append(" );\r\n"); + } else { + switch (CommonDefinition.getModuleType(moduleType)) { + case CommonDefinition.ModuleTypeBase: + fileBuffer.append("RETURN_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append(" (\r\n"); + fileBuffer.append(" VOID\r\n"); + fileBuffer.append(" );\r\n"); + break; + + case CommonDefinition.ModuleTypePeiCore: + case CommonDefinition.ModuleTypePeim: + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append(" (\r\n"); + fileBuffer + .append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n"); + fileBuffer + .append(" IN EFI_PEI_SERVICES **PeiServices\r\n"); + fileBuffer.append(" );\r\n"); + break; + + case CommonDefinition.ModuleTypeDxeCore: + case CommonDefinition.ModuleTypeDxeDriver: + case CommonDefinition.ModuleTypeDxeRuntimeDriver: + case CommonDefinition.ModuleTypeDxeSmmDriver: + case CommonDefinition.ModuleTypeDxeSalDriver: + case CommonDefinition.ModuleTypeUefiDriver: + case CommonDefinition.ModuleTypeUefiApplication: + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append(" (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n"); + fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n"); + fileBuffer.append(" );\r\n"); + break; + + } + } + } + + // + // Add ProcessLibraryConstructorList in AutoGen.c + // + fileBuffer.append("VOID\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessLibraryConstructorList (\r\n"); + switch (CommonDefinition.getModuleType(moduleType)) { + case CommonDefinition.ModuleTypeBase: + fileBuffer.append(" VOID\r\n"); + break; + + case CommonDefinition.ModuleTypePeiCore: + case CommonDefinition.ModuleTypePeim: + fileBuffer.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n"); + fileBuffer + .append(" IN EFI_PEI_SERVICES **PeiServices\r\n"); + break; + + case CommonDefinition.ModuleTypeDxeCore: + case CommonDefinition.ModuleTypeDxeDriver: + case CommonDefinition.ModuleTypeDxeRuntimeDriver: + case CommonDefinition.ModuleTypeDxeSmmDriver: + case CommonDefinition.ModuleTypeDxeSalDriver: + case CommonDefinition.ModuleTypeUefiDriver: + case CommonDefinition.ModuleTypeUefiApplication: + fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n"); + fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n"); + break; + } + + fileBuffer.append(" )\r\n"); + fileBuffer.append("{\r\n"); + // + // If no constructor function, return EFI_SUCCESS. + // + //if (libInstanceList.size() == 0){ + // fileBuffer.append(" return EFI_SUCCESS;\r\n"); + //} + for (int i = 0; i < libInstanceList.size(); i++) { + if (isFirst) { + fileBuffer.append(" EFI_STATUS Status;\r\n"); + fileBuffer.append(" Status = EFI_SUCCESS;\r\n"); + fileBuffer.append("\r\n"); + isFirst = false; + } + if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) { + fileBuffer.append(" Status = "); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append("();\r\n"); + } else { + switch (CommonDefinition.getModuleType(moduleType)) { + case CommonDefinition.ModuleTypeBase: + fileBuffer.append(" Status = "); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append("();\r\n"); + break; + case CommonDefinition.ModuleTypePeiCore: + case CommonDefinition.ModuleTypePeim: + fileBuffer.append(" Status = "); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append(" (FfsHeader, PeiServices);\r\n"); + break; + case CommonDefinition.ModuleTypeDxeCore: + case CommonDefinition.ModuleTypeDxeDriver: + case CommonDefinition.ModuleTypeDxeRuntimeDriver: + case CommonDefinition.ModuleTypeDxeSmmDriver: + case CommonDefinition.ModuleTypeDxeSalDriver: + case CommonDefinition.ModuleTypeUefiDriver: + case CommonDefinition.ModuleTypeUefiApplication: + fileBuffer.append(" Status = "); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append(" (ImageHandle, SystemTable);\r\n"); + break; + default: + EdkLog.log(EdkLog.EDK_INFO,"Autogen doesn't know how to deal with module type - " + moduleType + "!"); + } + + } + fileBuffer.append(" ASSERT_EFI_ERROR (Status);\r\n"); + } + fileBuffer.append("}\r\n"); + } + + /** + LibDestructorToAutogenc + + This function writes library destructor list to AutoGen.c. The library + destructor's parameter and return value depend on module type. + + @param libInstanceList + List of library destructor name. + @param moduleType + Module type. + @param fileBuffer + String buffer for AutoGen.c + @throws Exception + **/ + void LibDestructorToAutogenC(List libInstanceList, + String moduleType, StringBuffer fileBuffer) throws EdkException { + boolean isFirst = true; + for (int i = 0; i < libInstanceList.size(); i++) { + if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) { + fileBuffer.append("RETURN_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append(" (\r\n"); + fileBuffer.append(" VOID\r\n"); + fileBuffer.append(" );\r\n"); + } else { + switch (CommonDefinition.getModuleType(moduleType)) { + case CommonDefinition.ModuleTypeBase: + fileBuffer.append("RETURN_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append(" (\r\n"); + fileBuffer.append(" VOID\r\n"); + fileBuffer.append(" );\r\n"); + break; + case CommonDefinition.ModuleTypePeiCore: + case CommonDefinition.ModuleTypePeim: + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append(" (\r\n"); + fileBuffer + .append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n"); + fileBuffer + .append(" IN EFI_PEI_SERVICES **PeiServices\r\n"); + fileBuffer.append(" );\r\n"); + break; + case CommonDefinition.ModuleTypeDxeCore: + case CommonDefinition.ModuleTypeDxeDriver: + case CommonDefinition.ModuleTypeDxeRuntimeDriver: + case CommonDefinition.ModuleTypeDxeSmmDriver: + case CommonDefinition.ModuleTypeDxeSalDriver: + case CommonDefinition.ModuleTypeUefiDriver: + case CommonDefinition.ModuleTypeUefiApplication: + fileBuffer.append("EFI_STATUS\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append(" (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n"); + fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n"); + fileBuffer.append(" );\r\n"); + break; + } + } + } + + // + // Write ProcessLibraryDestructor list to autogen.c + // + switch (CommonDefinition.getModuleType(moduleType)) { + case CommonDefinition.ModuleTypeBase: + case CommonDefinition.ModuleTypePeiCore: + case CommonDefinition.ModuleTypePeim: + break; + case CommonDefinition.ModuleTypeDxeCore: + case CommonDefinition.ModuleTypeDxeDriver: + case CommonDefinition.ModuleTypeDxeRuntimeDriver: + case CommonDefinition.ModuleTypeDxeSmmDriver: + case CommonDefinition.ModuleTypeDxeSalDriver: + case CommonDefinition.ModuleTypeUefiDriver: + case CommonDefinition.ModuleTypeUefiApplication: + fileBuffer.append("VOID\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append("ProcessLibraryDestructorList (\r\n"); + fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n"); + fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n"); + fileBuffer.append(" )\r\n"); + fileBuffer.append("{\r\n"); + // + // If no library destructor function, return EFI_SUCCESS. + // + + for (int i = 0; i < libInstanceList.size(); i++) { + if (isFirst) { + fileBuffer.append(" EFI_STATUS Status;\r\n"); + fileBuffer.append(" Status = EFI_SUCCESS;\r\n"); + fileBuffer.append("\r\n"); + isFirst = false; + } + if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) { + fileBuffer.append(" Status = "); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append("();\r\n"); + fileBuffer.append(" VOID\r\n"); + } else { + fileBuffer.append(" Status = "); + fileBuffer.append(libInstanceList.get(i)[0]); + fileBuffer.append("(ImageHandle, SystemTable);\r\n"); + fileBuffer.append(" ASSERT_EFI_ERROR (Status);\r\n"); + } + } + fileBuffer.append("}\r\n"); + break; + } + } + + /** + ExternsDriverBindingToAutoGenC + + This function is to write DRIVER_BINDING, COMPONENT_NAME, + DRIVER_CONFIGURATION, DRIVER_DIAGNOSTIC in AutoGen.c. + + @param fileBuffer + String buffer for AutoGen.c + **/ + void ExternsDriverBindingToAutoGenC(StringBuffer fileBuffer) + throws EdkException { + + // + // Get the arry of extern. The driverBindingGroup is a 2 dimension array. + // The second dimension is include following element: DriverBinding, + // ComponentName, DriverConfiguration, DriverDiag; + // + String[][] driverBindingGroup = this.saq.getExternProtocolGroup(); + + // + // inital BitMask; + // + int BitMask = 0; + + // + // Write driver binding protocol extern to autogen.c + // + for (int i = 0; i < driverBindingGroup.length; i++) { + if (driverBindingGroup[i][0] != null) { + fileBuffer.append("extern EFI_DRIVER_BINDING_PROTOCOL "); + fileBuffer.append(driverBindingGroup[i][0]); + fileBuffer.append(";\r\n"); + } + } + + // + // Write component name protocol extern to autogen.c + // + for (int i = 0; i < driverBindingGroup.length; i++) { + if (driverBindingGroup[i][1]!= null) { + if (driverBindingGroup[i][0] != null) { + BitMask |= 0x01; + fileBuffer.append("extern EFI_COMPONENT_NAME_PROTOCOL "); + fileBuffer.append(driverBindingGroup[i][1]); + fileBuffer.append(";\r\n"); + } else { + throw new AutoGenException("DriverBinding can't be empty!!"); + } + } + } + + // + // Write driver configration protocol extern to autogen.c + // + for (int i = 0; i < driverBindingGroup.length; i++) { + if (driverBindingGroup[i][2] != null) { + if (driverBindingGroup[i][0] != null) { + BitMask |= 0x02; + fileBuffer.append("extern EFI_DRIVER_CONFIGURATION_PROTOCOL "); + fileBuffer.append(driverBindingGroup[i][2]); + fileBuffer.append(";\r\n"); + } else { + throw new AutoGenException("DriverBinding can't be empty!!"); + } + } + } + + // + // Write driver dignastic protocol extern to autogen.c + // + for (int i = 0; i < driverBindingGroup.length; i++) { + if (driverBindingGroup[i][3] != null) { + if (driverBindingGroup[i][0] != null) { + BitMask |= 0x04; + fileBuffer.append("extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL "); + fileBuffer.append(driverBindingGroup[i][3]); + fileBuffer.append(";\r\n"); + } else { + throw new AutoGenException("DriverBinding can't be empty!!"); + } + } + } + + // + // Write driver module protocol bitmask. + // + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverModelProtocolBitmask = "); + fileBuffer.append(Integer.toString(BitMask)); + fileBuffer.append(";\r\n"); + + // + // Write driver module protocol list entry + // + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINTN _gDriverModelProtocolListEntries = "); + + fileBuffer.append(Integer.toString(driverBindingGroup.length)); + fileBuffer.append(";\r\n"); + + // + // Write drive module protocol list to autogen.c + // + if (driverBindingGroup.length > 0) { + fileBuffer + .append("GLOBAL_REMOVE_IF_UNREFERENCED const EFI_DRIVER_MODEL_PROTOCOL_LIST _gDriverModelProtocolList[] = {"); + } + + + for (int i = 0; i < driverBindingGroup.length; i++) { + if (i != 0) { + fileBuffer.append(","); + } + + fileBuffer.append("\r\n {\r\n"); + fileBuffer.append(" &"); + fileBuffer.append(driverBindingGroup[i][0]); + fileBuffer.append(", \r\n"); + + + if (driverBindingGroup[i][1] != null) { + fileBuffer.append(" &"); + fileBuffer.append(driverBindingGroup[i][1]); + fileBuffer.append(", \r\n"); + } else { + fileBuffer.append(" NULL, \r\n"); + } + + if (driverBindingGroup[i][2] != null) { + fileBuffer.append(" &"); + fileBuffer.append(driverBindingGroup[i][2]); + fileBuffer.append(", \r\n"); + } else { + fileBuffer.append(" NULL, \r\n"); + } + + if (driverBindingGroup[i][3] != null) { + fileBuffer.append(" &"); + fileBuffer.append(driverBindingGroup[i][3]); + fileBuffer.append(", \r\n"); + } else { + fileBuffer.append(" NULL, \r\n"); + } + fileBuffer.append(" }"); + } + + if (driverBindingGroup.length > 0) { + fileBuffer.append("\r\n};\r\n"); + } + } + + /** + ExternCallBackToAutoGenC + + This function adds and + infomation to AutoGen.c + + @param fileBuffer + String buffer for AutoGen.c + @throws BuildException + **/ + void ExternCallBackToAutoGenC(StringBuffer fileBuffer) + throws EdkException { + // + // Collect module's and + // and add to setVirtualAddList + // exitBootServiceList. + // + String[] setVirtuals = saq.getSetVirtualAddressMapCallBackArray(); + String[] exitBoots = saq.getExitBootServicesCallBackArray(); + if (setVirtuals != null) { + for (int j = 0; j < setVirtuals.length; j++) { + this.setVirtalAddList.add(setVirtuals[j]); + } + } + if (exitBoots != null) { + for (int k = 0; k < exitBoots.length; k++) { + this.exitBootServiceList.add(exitBoots[k]); + } + } + // + // Add c code in autogen.c which relate to + // and + // + String moduleType = this.moduleId.getModuleType(); + switch (CommonDefinition.getModuleType(moduleType)) { + case CommonDefinition.ModuleTypeDxeDriver: + case CommonDefinition.ModuleTypeDxeRuntimeDriver: + case CommonDefinition.ModuleTypeDxeSalDriver: + case CommonDefinition.ModuleTypeUefiDriver: + case CommonDefinition.ModuleTypeUefiApplication: + // + // If moduleType is one of above, call setVirtualAddressToAutogenC, + // and setExitBootServiceToAutogenC. + // + setVirtualAddressToAutogenC(fileBuffer); + setExitBootServiceToAutogenC(fileBuffer); + break; + default: + break; + } + } + + /** + copyFlashMapHToDebugDir + + This function is to copy the falshmap.h to debug directory and change + its name to TianoR8FlashMap.h + + @param + @return + **/ + private void copyFlashMapHToDebugDir() throws AutoGenException{ + + File inFile = new File(fvDir + File.separatorChar + CommonDefinition.FLASHMAPH); + int size = (int)inFile.length(); + byte[] buffer = new byte[size]; + File outFile = new File (this.outputPath + File.separatorChar + CommonDefinition.TIANOR8PLASHMAPH); + // + // If TianoR8FlashMap.h existed and the flashMap.h don't change, + // do nothing. + // + if ((!outFile.exists()) ||(inFile.lastModified() - outFile.lastModified()) >= 0) { + if (inFile.exists()) { + try{ + FileInputStream fis = new FileInputStream (inFile); + fis.read(buffer); + FileOutputStream fos = new FileOutputStream(outFile); + fos.write(buffer); + fis.close(); + fos.close(); + } catch (IOException e){ + throw new AutoGenException("The file, flashMap.h can't be open!"); + } + + } else { + throw new AutoGenException("The file, flashMap.h doesn't exist!"); + } + } + } + + /** + This function first order the library instances, then collect + library instance 's PPI, Protocol, GUID, + SetVirtalAddressMapCallBack, ExitBootServiceCallBack, and + Destructor, Constructor. + + @param + @return + **/ + private void collectLibInstanceInfo() throws EdkException{ + int index; + + String libConstructName = null; + String libDestructName = null; + String libModuleType = null; + String[] setVirtuals = null; + String[] exitBoots = null; + + ModuleIdentification[] libraryIdList = saq.getLibraryInstance(this.arch); + + if (libraryIdList != null) { + // + // Reorder library instance sequence. + // + AutogenLibOrder libOrder = new AutogenLibOrder(libraryIdList, + this.arch); + List orderList = libOrder + .orderLibInstance(); + + if (orderList != null) { + // + // Process library instance one by one. + // + for (int i = 0; i < orderList.size(); i++) { + + // + // Get library instance basename. + // + ModuleIdentification libInstanceId = orderList.get(i); + + // + // Get override map + // + + Map libDoc = GlobalData.getDoc(libInstanceId, this.arch); + saq.push(libDoc); + // + // Get , , list of this library + // instance. + // + String[] ppiList = saq.getPpiArray(this.arch); + String[] ppiNotifyList = saq.getPpiNotifyArray(this.arch); + String[] protocolList = saq.getProtocolArray(this.arch); + String[] protocolNotifyList = saq.getProtocolNotifyArray(this.arch); + String[] guidList = saq.getGuidEntryArray(this.arch); + PackageIdentification[] pkgList = saq.getDependencePkg(this.arch); + + // + // Add those ppi, protocol, guid in global ppi, + // protocol, guid + // list. + // + for (index = 0; index < ppiList.length; index++) { + this.mPpiList.add(ppiList[index]); + } + + for (index = 0; index < ppiNotifyList.length; index++) { + this.mPpiList.add(ppiNotifyList[index]); + } + + for (index = 0; index < protocolList.length; index++) { + this.mProtocolList.add(protocolList[index]); + } + + for (index = 0; index < protocolNotifyList.length; index++) { + this.mProtocolList.add(protocolNotifyList[index]); + } + + for (index = 0; index < guidList.length; index++) { + this.mGuidList.add(guidList[index]); + } + for (index = 0; index < pkgList.length; index++) { + if (!this.mDepPkgList.contains(pkgList[index])) { + this.mDepPkgList.add(pkgList[index]); + } + } + + // + // If not yet parse this library instance's constructor + // element,parse it. + // + libConstructName = saq.getLibConstructorName(); + libDestructName = saq.getLibDestructorName(); + libModuleType = saq.getModuleType(); + + // + // Collect SetVirtualAddressMapCallBack and + // ExitBootServiceCallBack. + // + setVirtuals = saq.getSetVirtualAddressMapCallBackArray(); + exitBoots = saq.getExitBootServicesCallBackArray(); + if (setVirtuals != null) { + for (int j = 0; j < setVirtuals.length; j++) { + this.setVirtalAddList.add(setVirtuals[j]); + } + } + if (exitBoots != null) { + for (int k = 0; k < exitBoots.length; k++) { + this.exitBootServiceList.add(exitBoots[k]); + } + } + saq.pop(); + // + // Add dependent library instance constructor function. + // + if (libConstructName != null) { + this.libConstructList.add(new String[] {libConstructName, libModuleType}); + } + // + // Add dependent library instance destructor fuction. + // + if (libDestructName != null) { + this.libDestructList.add(new String[] {libDestructName, libModuleType}); + } + } + } + + } + } + private void setVirtualAddressToAutogenC(StringBuffer fileBuffer){ + // + // Entry point lib for these module types needs to know the count + // of entryPoint. + // + fileBuffer + .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const UINTN _gDriverSetVirtualAddressMapEventCount = "); + + // + // If the list is not valid or has no entries set count to zero else + // set count to the number of valid entries + // + int Count = 0; + int i = 0; + if (this.setVirtalAddList != null) { + for (i = 0; i < this.setVirtalAddList.size(); i++) { + if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) { + break; + } + } + Count = i; + } + + fileBuffer.append(Integer.toString(Count)); + fileBuffer.append(";\r\n\r\n"); + if (this.setVirtalAddList == null || this.setVirtalAddList.size() == 0) { + // + // No data so make a NULL list + // + fileBuffer + .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {\r\n"); + fileBuffer.append(" NULL\r\n"); + fileBuffer.append("};\r\n\r\n"); + } else { + // + // Write SetVirtualAddressMap function definition. + // + for (i = 0; i < this.setVirtalAddList.size(); i++) { + if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) { + break; + } + fileBuffer.append("VOID\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(this.setVirtalAddList.get(i)); + fileBuffer.append(" (\r\n"); + fileBuffer.append(" IN EFI_EVENT Event,\r\n"); + fileBuffer.append(" IN VOID *Context\r\n"); + fileBuffer.append(" );\r\n\r\n"); + } + + // + // Write SetVirtualAddressMap entry point array. + // + fileBuffer + .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {"); + for (i = 0; i < this.setVirtalAddList.size(); i++) { + if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) { + break; + } + + if (i == 0) { + fileBuffer.append("\r\n "); + } else { + fileBuffer.append(",\r\n "); + } + + fileBuffer.append(this.setVirtalAddList.get(i)); + } + // + // add the NULL at the end of _gDriverSetVirtualAddressMapEvent list. + // + fileBuffer.append(",\r\n NULL"); + fileBuffer.append("\r\n};\r\n\r\n"); + } + } + + + private void setExitBootServiceToAutogenC(StringBuffer fileBuffer){ + // + // Entry point lib for these module types needs to know the count. + // + fileBuffer + .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const UINTN _gDriverExitBootServicesEventCount = "); + + // + // If the list is not valid or has no entries set count to zero else + // set count to the number of valid entries. + // + int Count = 0; + int i = 0; + if (this.exitBootServiceList != null) { + for (i = 0; i < this.exitBootServiceList.size(); i++) { + if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) { + break; + } + } + Count = i; + } + fileBuffer.append(Integer.toString(Count)); + fileBuffer.append(";\r\n\r\n"); + + if (this.exitBootServiceList == null || this.exitBootServiceList.size() == 0) { + // + // No data so make a NULL list. + // + fileBuffer + .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {\r\n"); + fileBuffer.append(" NULL\r\n"); + fileBuffer.append("};\r\n\r\n"); + } else { + // + // Write DriverExitBootServices function definition. + // + for (i = 0; i < this.exitBootServiceList.size(); i++) { + if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) { + break; + } + + fileBuffer.append("VOID\r\n"); + fileBuffer.append("EFIAPI\r\n"); + fileBuffer.append(this.exitBootServiceList.get(i)); + fileBuffer.append(" (\r\n"); + fileBuffer.append(" IN EFI_EVENT Event,\r\n"); + fileBuffer.append(" IN VOID *Context\r\n"); + fileBuffer.append(" );\r\n\r\n"); + } + + // + // Write DriverExitBootServices entry point array. + // + fileBuffer + .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {"); + for (i = 0; i < this.exitBootServiceList.size(); i++) { + if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) { + break; + } + + if (i == 0) { + fileBuffer.append("\r\n "); + } else { + fileBuffer.append(",\r\n "); + } + fileBuffer.append(this.exitBootServiceList.get(i)); + } + + fileBuffer.append(",\r\n NULL"); + fileBuffer.append("\r\n};\r\n\r\n"); + } + + } + +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java b/Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java new file mode 100644 index 0000000000..bddea90aab --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java @@ -0,0 +1,317 @@ +/**@file + AutogenLibOrder class. + + This class is to reorder library instance sequence according to library + dependence. + + 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.autogen; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.xmlbeans.XmlObject; +import org.tianocore.build.exception.AutoGenException; +import org.tianocore.build.global.GlobalData; +import org.tianocore.build.global.SurfaceAreaQuery; +import org.tianocore.build.id.ModuleIdentification; +import org.tianocore.common.exception.EdkException; + +/** + This class This class is to reorder library instance sequence according to + library dependence. +**/ +public class AutogenLibOrder { + /// + /// The map of library class and its library instance. + /// + private Map libClassMap = new HashMap(); + + /// + /// The map of library instance and its implemet libraryClass. + /// + private Map libInstanceMap = new HashMap(); + + /// + /// List of library instance. It is String[3] list, String[0] is libraryName, + /// String[1] is libraryConstructor name, String[2] is libDestructor name. + /// + private List libInstanceList = new ArrayList(); + + /** + Constructor function + + This function mainly initialize some member variable. + + @param libraryList List of the library instance. + @throws Exception + **/ + AutogenLibOrder(ModuleIdentification[] libraryList, String arch) throws EdkException { + LibraryInstanceNode libInstanceNode; + String[] libClassDeclList = null; + String[] libClassConsmList = null; + + for (int i = 0; i < libraryList.length; i++) { + // + // Add libraryInstance in to libInstanceList. + // + Map libDoc = GlobalData.getDoc(libraryList[i], arch); + SurfaceAreaQuery saq = new SurfaceAreaQuery(libDoc); + libInstanceNode = new LibraryInstanceNode (libraryList[i],saq.getLibConstructorName(), saq.getLibDestructorName()); + libInstanceList.add(libInstanceNode); + + // + // Add library instance and consumed library class list to + // libInstanceMap. + // + libClassConsmList = saq.getLibraryClasses(CommonDefinition.ALWAYSCONSUMED, arch); + if (libClassConsmList != null) { + String[] classStr = new String[libClassConsmList.length]; + for (int k = 0; k < libClassConsmList.length; k++) { + classStr[k] = libClassConsmList[k]; + } + if (this.libInstanceMap.containsKey(libraryList[i])) { + throw new AutoGenException( + libraryList[i].getName() + + "-- this library instance already exists, please check the library instance list!"); + } else { + this.libInstanceMap.put(libraryList[i], classStr); + } + } + + // + // Add library class and library instance map. + // + libClassDeclList = saq.getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, arch); + if (libClassDeclList != null) { + for (int j = 0; j < libClassDeclList.length; j++) { + if (this.libClassMap.containsKey(libClassDeclList[j])) { + System.out.println(libClassDeclList[j] + + " class is already implement by " + + this.libClassMap.get(libClassDeclList[j])); + throw new AutoGenException("Library Class: " + libClassDeclList + + " already has a library instance!"); + } else { + this.libClassMap.put(libClassDeclList[j], libraryList[i]); + } + } + } + } + + // + // Check is the library instance list meet the require; + // + //for (int s = 0; s < this.libInstanceList.size(); s++) { + // String[] libClass = this.libInstanceMap.get(this.libInstanceList + // .get(s)); + // if (libClass != null) { + // for (int t = 0; t < libClass.length; t++) { + // if (this.libClassMap.get(libClass[t]) == null) { + // + // Note: There exist a kind of module which depend on + // library class with no instance or whose instance will + // never be linked into the module. + // For this satuation, the module has the description of + // library class in MSA file but no description of + // corresponding library instance in MBD file. There + // will be a warnig message given here after a standard + // log way has been decided. + // + // } + // } + // } + //} + } + + /** + orderLibInstance + + This function reorder the library instance according the library class + dependency. + + @return List which content the ordered library instance. + **/ + List orderLibInstance() { + List orderList = new ArrayList(); + // + // Stack of node which track the library instance name ant its visiting + // flag. + // + List stackList = new ArrayList(); + int stackSize = 0; + ModuleIdentification libInstanceId = null; + if (libInstanceList.size() < 0) { + return null; + } + + // + // Reorder the library instance. + // + for (int i = 0; i < libInstanceList.size(); i++) { + // + // If library instance is already in the order list skip it. + // + if (isInLibInstance(orderList, libInstanceList.get(i).libId)) { + continue; + } + + Node node = new Node(libInstanceList.get(i).libId, false); + // + // Use stack to reorder library instance. + // Push node to stack. + // + stackList.add(node); + while (stackList.size() > 0) { + stackSize = stackList.size() - 1; + // + // Pop the first node in stack. If the node flag has been visited + // add this node to orderlist and remove it from stack. + // + if (stackList.get(stackSize).isVisit) { + if (!isInLibInstance(orderList, + stackList.get(stackSize).nodeId)) { + orderList.add(stackList.get(stackSize).nodeId); + stackList.remove(stackSize); + } + + } else { + // + // Get the node value and set visit flag as true. + // + stackList.get(stackList.size() - 1).isVisit = true; + String[] libClassList = this.libInstanceMap.get(stackList + .get(stackSize).nodeId); + // + // Push the node dependence library instance to the stack. + // + if (libClassList != null) { + for (int j = 0; j < libClassList.length; j++) { + libInstanceId = this.libClassMap.get(libClassList[j]); + if (libInstanceId != null + && !isInLibInstance(orderList, libInstanceId)) { + // + // If and only if the currently library instance + // is not in stack and it have constructor or + // destructor function, push this library + // instacne in stack. + // + if (!isInStackList(stackList, this.libClassMap + .get(libClassList[j])) && isHaveConsDestructor(libInstanceId)) { + stackList.add(new Node(this.libClassMap + .get(libClassList[j]), false)); + } + } + } + } + } + } + } + return orderList; + } + + /** + isInLibInstance + + This function check does the library instance already in the list. + + @param list List of the library instance. + @param instanceName Name of library instance. + @return "true" the library instance in list | + "false" the library instance is not in list. + **/ + private boolean isInLibInstance(List list, ModuleIdentification instanceId) { + for (int i = 0; i < list.size(); i++) { + + if (instanceId.equals(list.get(i))) { + return true; + } + } + return false; + } + + /** + isInStackList + + This function check if the node already in the stack. + + @param list Stack. + @param nodeName Name of node. + @return "true" if node have in stack | + "false" if node don't in stack. + **/ + private boolean isInStackList(List list, ModuleIdentification instanceId) { + for (int i = 0; i < list.size(); i++) { + if (instanceId.equals(list.get(i).nodeId)) { + return true; + } + } + return false; + } + + /** + isHaveConsDestructor + + This function check if the library have constructor or destructor + function. + + @param libName Name of library + @return "true" if library have constructor or desconstructor | + "false" if library don't have constructor + and desconstructor. + **/ + private boolean isHaveConsDestructor (ModuleIdentification libNode){ + for (int i = 0; i < libInstanceList.size(); i++){ + if (libInstanceList.get(i).libId.equals(libNode)){ + if (libInstanceList.get(i).constructorName != null || libInstanceList.get(i).deconstructorName != null){ + return true; + } + } + } + return false; + } +} + +/** + Node + + This class is used as stack node. + + **/ +class Node { + ModuleIdentification nodeId; + + boolean isVisit; + + Node(ModuleIdentification nodeId, boolean isVisit) { + this.nodeId = nodeId; + this.isVisit = false; + } +} +/** + LibraryInstance Node + + This class is used to store LibrayInstance and it's deconstructor and constructor +**/ + +class LibraryInstanceNode { + ModuleIdentification libId; + String deconstructorName; + String constructorName; + + LibraryInstanceNode (ModuleIdentification libId, String deconstructor, String constructor){ + this.libId = libId; + this.deconstructorName = deconstructor; + this.constructorName = constructor; + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java b/Tools/Java/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java new file mode 100644 index 0000000000..cb750ffd47 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java @@ -0,0 +1,285 @@ +/** @file + CommonDefinition class. + + This class is to define some common marcos and funcions, which used by AutoGen. + + 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.autogen; + +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; +import org.tianocore.common.definitions.EdkDefinitions; +import org.tianocore.common.definitions.ToolDefinitions; +/** + CommonDefinition + + This class is to define some common marcos, which used by AutoGen. + +**/ +public class CommonDefinition { + + /// + /// final static string + /// + public final static String LIBRARY = "LIBRARY"; + + public final static String AUTOGENHBEGIN = "extern int __make_me_compile_correctly;" + + ToolDefinitions.LINE_SEPARATOR; + + public final static String INCLUDE = "#include"; + + //public final static String DEBUGPROPERYMASK = "const UINT8 _gDebugPropertyMask " + // + "= DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED" + // + " | DEBUG_PROPERTY_DEBUG_PRINT_ENABLED" + // + " | DEBUG_PROPERTY_DEBUG_CODE_ENABLED;" + // + ToolDefinitions.LINE_SEPARATOR; + + //public final static String DEFAULERROLEVEL = "const UINTN _gModuleDefaultErrorLevel" + // + " = EFI_D_ERROR | EFI_D_LOAD;" + // + ToolDefinitions.LINE_SEPARATOR; + + + public final static String INCLUDEAUTOGENH = INCLUDE + + " " + + ToolDefinitions.LINE_SEPARATOR; + + public final static String DEFINE = "#define "; + + public final static String GEFI = "gEfi"; + + public final static String PRTOCOLGUID = "ProtocolGuid"; + + public final static String PPIGUID = "PpiGuid"; + + public final static String GUID = "Guid"; + + public final static String TIANOR8PLASHMAPH = "TianoR8FlashMap.h"; + + public final static String FLASHMAPH = "FlashMap.h"; + + public final static String IFNDEF = "#ifndef "; + + public final static String AUTOGENH = "_AUTOGENH_"; + + + /// + /// AutoGen.h and AutoGen.c file's header + /// + public final static String AUTOGENHNOTATION = "/**" + + ToolDefinitions.LINE_SEPARATOR + + " DO NOT EDIT" + + ToolDefinitions.LINE_SEPARATOR + + " FILE auto-generated by GenBuild tasks" + + ToolDefinitions.LINE_SEPARATOR + + " Module name:" + + ToolDefinitions.LINE_SEPARATOR + + " AutoGen.h" + + ToolDefinitions.LINE_SEPARATOR + + " Abstract:" + + " Auto-generated AutoGen.h for building module or library." + + ToolDefinitions.LINE_SEPARATOR + + "**/" + + ToolDefinitions.LINE_SEPARATOR + + ToolDefinitions.LINE_SEPARATOR; + + public final static String AUTOGENCNOTATION = "/**" + + ToolDefinitions.LINE_SEPARATOR + + " DO NOT EDIT" + + ToolDefinitions.LINE_SEPARATOR + + " FILE auto-generated by GenBuild tasks" + + ToolDefinitions.LINE_SEPARATOR + + " Module name:" + + ToolDefinitions.LINE_SEPARATOR + + " AutoGen.c" + + ToolDefinitions.LINE_SEPARATOR + + " Abstract:" + + " Auto-generated AutoGen.c for building module or library." + + ToolDefinitions.LINE_SEPARATOR + + "**/" + + ToolDefinitions.LINE_SEPARATOR + + ToolDefinitions.LINE_SEPARATOR; + + /// + /// The defintions for identifying current module + /// is PEI Pcd driver or Dxe Pcd driver. + /// + public static enum PCD_DRIVER_TYPE { NOT_PCD_DRIVER, + PEI_PCD_DRIVER, + DXE_PCD_DRIVER, + UNKNOWN_PCD_DRIVER + }; + + + /// + /// module type + /// + public final static int ModuleTypeBase = 0; + public final static int ModuleTypeSec = 1; + public final static int ModuleTypePeiCore = 2; + public final static int ModuleTypePeim = 3; + public final static int ModuleTypeDxeCore = 4; + public final static int ModuleTypeDxeDriver = 5; + public final static int ModuleTypeDxeRuntimeDriver = 6; + public final static int ModuleTypeDxeSmmDriver = 7; + public final static int ModuleTypeDxeSalDriver = 8; + public final static int ModuleTypeUefiDriver = 9; + public final static int ModuleTypeUefiApplication = 10; + public final static int ModuleTypeUnknown = 11; + + /// + /// Usaged style + /// + public final static String ALWAYSCONSUMED = "ALWAYS_CONSUMED"; + public final static String ALWAYSPRODUCED = "ALWAYS_PRODUCED"; + + + public static class MyEnum { + String moduleTypeStr; + int type; + + MyEnum (String str, int type) { + this.type = type; + this.moduleTypeStr = str; + } + + int ForInt(String str) { + if (str.equals(this.moduleTypeStr)) { + return this.type; + } else + return -1; + } + } + + /// + /// Module type + /// + public static final MyEnum[] moduleEnum = new MyEnum[] { + new MyEnum(EdkDefinitions.MODULE_TYPE_BASE, ModuleTypeBase), + new MyEnum(EdkDefinitions.MODULE_TYPE_SEC, ModuleTypeSec), + new MyEnum(EdkDefinitions.MODULE_TYPE_PEI_CORE, ModuleTypePeiCore), + new MyEnum(EdkDefinitions.MODULE_TYPE_PEIM, ModuleTypePeim), + new MyEnum(EdkDefinitions.MODULE_TYPE_DXE_CORE, ModuleTypeDxeCore), + new MyEnum(EdkDefinitions.MODULE_TYPE_DXE_DRIVER, ModuleTypeDxeDriver), + new MyEnum(EdkDefinitions.MODULE_TYPE_DXE_RUNTIME_DRIVER, ModuleTypeDxeRuntimeDriver), + new MyEnum(EdkDefinitions.MODULE_TYPE_DXE_SAL_DRIVER, ModuleTypeDxeSalDriver), + new MyEnum(EdkDefinitions.MODULE_TYPE_DXE_SMM_DRIVER, ModuleTypeDxeSmmDriver), + new MyEnum(EdkDefinitions.MODULE_TYPE_UEFI_DRIVER, ModuleTypeUefiDriver), + new MyEnum(EdkDefinitions.MODULE_TYPE_UEFI_APPLICATION, ModuleTypeUefiApplication)}; + + /** + getModuleType + + This function get the module type value according module type string. + + @param moduleTypeStr String of modlue type. + @return + **/ + public static int getModuleType(String moduleTypeStr) { + int returnValue = -1; + for (int i = 0; i < CommonDefinition.moduleEnum.length; i++) { + returnValue = CommonDefinition.moduleEnum[i].ForInt(moduleTypeStr); + if (returnValue != -1) { + return returnValue; + } + } + return CommonDefinition.ModuleTypeUnknown; + } + + /** + formateGuidName + + This function is to formate GUID to ANSI c form. + + @param guidNameCon + String of GUID. + @return Formated GUID. + **/ + public static String formatGuidName(String guidNameConv) { + String[] strList; + String guid = ""; + int index = 0; + if (guidNameConv + .matches("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}")) { + strList = guidNameConv.split("-"); + guid = "0x" + strList[0] + ", "; + guid = guid + "0x" + strList[1] + ", "; + guid = guid + "0x" + strList[2] + ", "; + guid = guid + "{"; + guid = guid + "0x" + strList[3].substring(0, 2) + ", "; + guid = guid + "0x" + strList[3].substring(2, 4); + + while (index < strList[4].length()) { + guid = guid + ", "; + guid = guid + "0x" + strList[4].substring(index, index + 2); + index = index + 2; + } + guid = guid + "}"; + return guid; + } else if (guidNameConv + .matches("0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},( )*0x[a-fA-F0-9]{1,4}(,( )*\\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\\})?")) { + strList = guidNameConv.split(","); + + // + // chang Microsoft specific form to ANSI c form + // + for (int i = 0; i < 3; i++) { + guid = guid + strList[i] + ","; + } + guid = guid + "{"; + + for (int i = 3; i < strList.length; i++) { + if (i == strList.length - 1) { + guid = guid + strList[i]; + } else { + guid = guid + strList[i] + ","; + } + } + guid = guid + "}"; + return guid; + } else { + System.out + .println("Check GUID Value, It doesn't conform to the registry format specified in the schema!!!"); + return "0"; + + } + } + + /** + Remove deuplicat string in list + + This function is to duplicat string in list + + @param String[] + String list. + @return String[] String list which remove the duplicate string. + **/ + public static String[] remDupString (String[] orgList){ + Set strList = new LinkedHashSet(); + String[] desList ; + if (orgList == null) { + return new String[0]; + } + for (int i = 0; i < orgList.length; i++) { + strList.add(orgList[i]); + } + desList = new String[strList.size()]; + Iterator item = strList.iterator(); + int index = 0; + while (item.hasNext()) { + desList[index] = (String)item.next(); + index++; + } + return desList; + } + +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/exception/AutoGenException.java b/Tools/Java/Source/GenBuild/org/tianocore/build/exception/AutoGenException.java new file mode 100644 index 0000000000..5db092be48 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/exception/AutoGenException.java @@ -0,0 +1,40 @@ +/** @file + AutoGenException class. + + The class handle the exception throwed by entity class. + +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.exception; + + +/** + The class handle the exception throwed by entity class. +**/ +public class AutoGenException extends GenBuildException { + static final long serialVersionUID = -8034897190740066939L; + /** + Constructure function + + @param expStr exception message string. + **/ + public AutoGenException(String expStr) { + super(expStr); + } + + public AutoGenException() { + + } + + public AutoGenException(Exception e, String messsge){ + super(e, messsge); + } +} \ No newline at end of file diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/exception/GenBuildException.java b/Tools/Java/Source/GenBuild/org/tianocore/build/exception/GenBuildException.java new file mode 100644 index 0000000000..b81d54cba2 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/exception/GenBuildException.java @@ -0,0 +1,40 @@ +/** @file + GenBuildException class. + + The class handle the exception throwed by entity class. + +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.exception; + +import org.tianocore.common.exception.EdkException; + +/** + The class handle the exception throwed by entity class. +**/ +public class GenBuildException extends EdkException { + static final long serialVersionUID = -8034897190740066937L; + /** + Constructure function + + @param expStr exception message string. + **/ + public GenBuildException(String expStr) { + super(expStr); + } + + public GenBuildException() { + super(); + } + public GenBuildException(Exception e, String message){ + super(e, message); + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/exception/PcdAutogenException.java b/Tools/Java/Source/GenBuild/org/tianocore/build/exception/PcdAutogenException.java new file mode 100644 index 0000000000..3a3430c820 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/exception/PcdAutogenException.java @@ -0,0 +1,35 @@ +/** @file + AutoGenException class. + + The class handle the exception throwed by entity class. + +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.exception; + +/** + The class handle the exception throwed by entity class. +**/ +public class PcdAutogenException extends AutoGenException { + static final long serialVersionUID = -8034897190740066936L; + /** + Constructure function + + @param expStr exception message string. + **/ + public PcdAutogenException(String expStr) { + super(expStr); + } + + public PcdAutogenException() { + super(); + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/exception/PlatformPcdPreprocessBuildException.java b/Tools/Java/Source/GenBuild/org/tianocore/build/exception/PlatformPcdPreprocessBuildException.java new file mode 100644 index 0000000000..6bf6110148 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/exception/PlatformPcdPreprocessBuildException.java @@ -0,0 +1,36 @@ +/** @file + PlatformPcdPreprocessBuildException class. + + The class handle the exception throwed by PlatformPcdPreprocessActionForBuilding class. + +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.exception; + +public class PlatformPcdPreprocessBuildException extends GenBuildException { + /** + serial version ID + **/ + private static final long serialVersionUID = -1014589090055424954L; + + /** + Constructure function + + @param expStr exception message string. + **/ + public PlatformPcdPreprocessBuildException(String expStr) { + super(expStr); + } + + public PlatformPcdPreprocessBuildException() { + super(); + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/exception/XmlParseException.java b/Tools/Java/Source/GenBuild/org/tianocore/build/exception/XmlParseException.java new file mode 100644 index 0000000000..44d3fdc389 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/exception/XmlParseException.java @@ -0,0 +1,35 @@ +/** @file + XmlParseException class. + + The class handle the exception throwed by entity class. + +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.exception; + +/** + The class handle the exception throwed by entity class. +**/ +public class XmlParseException extends GenBuildException { + static final long serialVersionUID = -8034897190740066934L; + /** + Constructure function + + @param expStr exception message string. + **/ + public XmlParseException(String expStr) { + super(expStr); + } + + public XmlParseException() { + super(); + } +} \ No newline at end of file diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java b/Tools/Java/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java new file mode 100644 index 0000000000..93510a7727 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java @@ -0,0 +1,409 @@ +/** @file + This file is ANT task FpdParserTask. + + 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.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.taskdefs.Ant; +import org.apache.xmlbeans.XmlObject; + +import org.tianocore.build.global.GenBuildLogger; +import org.tianocore.build.global.GlobalData; +import org.tianocore.build.global.OutputManager; +import org.tianocore.build.id.FpdModuleIdentification; +import org.tianocore.build.id.ModuleIdentification; +import org.tianocore.build.FrameworkBuildTask; +import org.tianocore.build.GenBuildThread; +import org.tianocore.common.exception.EdkException; +import org.tianocore.common.logger.EdkLog; + +/** + + @since GenBuild 1.0 +**/ +public class FpdParserForThread extends FpdParserTask { + + public static Map allThreads = new LinkedHashMap(); + + List queueList = new ArrayList(); + + public final static Object deamonSemaphore = new Object(); + + private final static Object countSemaphore = new Object(); + + public static int STATUS_DEPENDENCY_NOT_READY = 1; + + public static int STATUS_DEPENDENCY_READY = 2; + + public static int STATUS_START_RUN = 3; + + public static int STATUS_END_RUN = 4; + + private int currentQueueCode = 0; + + public static int currentRunNumber = 0; + + public static int totalNumber = 0; + + public static int remainNumber = 0; + + public static ThreadGroup tg = new ThreadGroup("Framework"); + + public static FpdModuleIdentification errorModule = null; + + /** + Public construct method. It is necessary for ANT task. + **/ + public FpdParserForThread() { + } + + /** + + + **/ + public void execute() throws BuildException { + + this.setTaskName("........."); + // + // Parse FPD file + // + parseFpdFile(); + + // + // 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(); + getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/")); + + // + // Gen Fv.inf files + // + genFvInfFiles(ffsCommonDir); + } + } + + // + // Gen build.xml + // + String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml"; + PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile); + fileGenerator.genBuildFile(); + + // + // Prepare Queue + // + queueList.add("libqueue"); + + String[] validFv = saq.getFpdValidImageNames(); + + for (int i = 0; i < validFv.length; i++) { + queueList.add(validFv[i]); + } + + Iterator fvsNameIter = fvs.keySet().iterator(); + + while (fvsNameIter.hasNext()) { + String fvName = fvsNameIter.next(); + if (!isContain(validFv, fvName)) { + queueList.add(fvName); + } + } + + // + // Ant call ${PLATFORM}_build.xml + // + Ant ant = new Ant(); + ant.setProject(getProject()); + ant.setAntfile(platformBuildFile); + ant.setTarget("prebuild"); + ant.setInheritAll(true); + ant.init(); + ant.execute(); + + remainNumber = totalNumber = allThreads.size(); + + EdkLog.log(this, EdkLog.EDK_ALWAYS, "Total thread number is " + totalNumber); + GenBuildLogger.setCacheEnable(true); + // + // Waiting for all thread over, or time out + // + synchronized (deamonSemaphore) { + + while (true) { + // + // If all modules are already built + // + if (currentQueueCode >= queueList.size()) { + break ; + } + + int percentage = (totalNumber - remainNumber) * 100 / totalNumber; + updateTaskName(percentage); + EdkLog.log(this, EdkLog.EDK_ALWAYS, percentage + "% finished. Has built " + (totalNumber - remainNumber) + " modules of " + totalNumber + " total. "); + + Set currentQueueModules = fvs.get(queueList.get(currentQueueCode)); + + if (currentQueueModules == null) { + ++currentQueueCode; + continue ; + } + Iterator currentIter = currentQueueModules.iterator(); + + GenBuildThread a = null; + + boolean existNoneReady = false; + + while (currentIter.hasNext()) { + GenBuildThread item = allThreads.get(currentIter.next()); + if (item.getStatus() == STATUS_DEPENDENCY_NOT_READY) { + existNoneReady = true; + } else if (item.getStatus() == STATUS_DEPENDENCY_READY) { + a = item; + addCount(); + a.start(); + if (currentRunNumber == FrameworkBuildTask.MAX_CONCURRENT_THREAD_NUMBER) { + break ; + } + } + } + + if (a != null) { + // + // Exist ready thread + // + EdkLog.log(this, EdkLog.EDK_DEBUG, "Exist ready thread"); + + } else if (existNoneReady && currentRunNumber == 0) { + // + // No active thread, but still have dependency not read thread + // + throw new BuildException("Existing some modules can't resolve depedencies. "); + } else if (!existNoneReady && currentRunNumber == 0) { + // + // Current queue build finish, move to next + // + EdkLog.log(this, EdkLog.EDK_DEBUG, "Current queue build finish, move to next"); + ++currentQueueCode; + continue ; + } else { + // + // active thread exist, but no ready thread + // + EdkLog.log(this, EdkLog.EDK_DEBUG, "Active thread exist, but no ready thread. Current running number is " + currentRunNumber); + } + + try { + deamonSemaphore.wait(); + + // + // if find error. Waiting running threads to finish + // + if (errorModule != null) { + while (currentRunNumber > 0) { + deamonSemaphore.wait(); + } + + GenBuildLogger.setCacheEnable(false); + + GenBuildLogger.flushErrorModuleLog(errorModule); + + EdkLog.flushLogToFile(new File(buildDir + File.separatorChar + "build.log")); + + throw new BuildException(errorModule + " build error. "); + } + } catch (InterruptedException ex) { + BuildException e = new BuildException("Thread wait Error. \n" + ex.getMessage()); + e.setStackTrace(ex.getStackTrace()); + throw e; + } + } + } + + GenBuildLogger.setCacheEnable(false); + // + // call fvs, postbuild + // + ant = new Ant(); + ant.setProject(getProject()); + ant.setAntfile(platformBuildFile); + ant.setTarget("fvs"); + ant.setInheritAll(true); + ant.init(); + ant.execute(); + + ant = new Ant(); + ant.setProject(getProject()); + ant.setAntfile(platformBuildFile); + ant.setTarget("postbuild"); + ant.setInheritAll(true); + ant.init(); + ant.execute(); + + EdkLog.flushLogToFile(new File(buildDir + File.separatorChar + "build.log")); + } + + + /** + Parse all modules listed in FPD file. + **/ + void parseModuleSAFiles() throws EdkException{ + + Map> moduleSAs = saq.getFpdModules(); + + // + // For every Module lists in FPD file. + // + Set keys = moduleSAs.keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()) { + FpdModuleIdentification fpdModuleId = iter.next(); + + // + // Generate GenBuildThread + // + GenBuildThread genBuildThread = new GenBuildThread(fpdModuleId.getModule(), fpdModuleId.getArch()); + genBuildThread.setParentModuleId(null); + genBuildThread.setProject(getProject()); + + Set dependencies = new LinkedHashSet(); + + GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId)); + + // + // Add all dependent Library Instance + // + saq.push(GlobalData.getDoc(fpdModuleId)); + + ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch()); + saq.pop(); + + for (int i = 0; i < libinstances.length; i++) { + FpdModuleIdentification libFpdModuleId = new FpdModuleIdentification(libinstances[i], fpdModuleId.getArch()); + // + // Add to dependencies + // + dependencies.add(libFpdModuleId); + + // + // Create thread for library instances + // + GenBuildThread liBuildThread = new GenBuildThread(libinstances[i], fpdModuleId.getArch()); + liBuildThread.setParentModuleId(fpdModuleId.getModule()); + liBuildThread.setProject(getProject()); + liBuildThread.setStatus(STATUS_DEPENDENCY_READY); + liBuildThread.setHighPriority(true); + allThreads.put(libFpdModuleId, liBuildThread); + + updateFvs("libqueue", libFpdModuleId); + } + + genBuildThread.setDependencies(dependencies); + +// if (dependencies.size() == 0) { + genBuildThread.setStatus(STATUS_DEPENDENCY_READY); +// } + + allThreads.put(fpdModuleId, genBuildThread); + + // + // Put fpdModuleId to the corresponding FV + // + saq.push(GlobalData.getDoc(fpdModuleId)); + String fvBinding = saq.getModuleFvBindingKeyword(); + + fpdModuleId.setFvBinding(fvBinding); + updateFvs(fvBinding, fpdModuleId); + + // + // Prepare for out put file name + // + ModuleIdentification moduleId = fpdModuleId.getModule(); + + String baseName = saq.getModuleOutputFileBasename(); + + if (baseName == null) { + baseName = moduleId.getName(); + } + outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar + + moduleId.getGuid() + "-" + baseName + + getSuffix(moduleId.getModuleType())); + + // + // parse module build options, if any + // + GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false)); + GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true)); + saq.pop(); + } + } + + private boolean isContain(String[] list, String item) { + for (int i = 0; i < list.length; i++) { + if (list[i].equalsIgnoreCase(item)) { + return true; + } + } + return false; + } + + public synchronized static void addCount() { + synchronized (countSemaphore) { + ++currentRunNumber; + } + } + + public synchronized static void subCount() { + synchronized (countSemaphore) { + --currentRunNumber; + --remainNumber; + } + } + + private void updateTaskName(int percentage){ + int number = percentage/10; + StringBuffer str = new StringBuffer(9); + for(int i = 0; i < 9; i++) { + if (i < number) { + str.append('>'); + } else { + str.append('.'); + } + } + this.setTaskName(str.toString()); + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java b/Tools/Java/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java new file mode 100644 index 0000000000..2b1f30fa0d --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java @@ -0,0 +1,756 @@ +/** @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. + **/ +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; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +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.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 + 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 { + + private File fpdFile = null; + + PlatformIdentification platformId; + + private String type; + + /// + /// Mapping from modules identification to out put file name + /// + Map outfiles = new LinkedHashMap(); + + /// + /// Mapping from FV name to its modules + /// + Map> fvs = new HashMap>(); + + /// + /// FpdParserTask can specify some ANT properties. + /// + private Vector properties = new Vector(); + + SurfaceAreaQuery saq = null; + + boolean isUnified = true; + + /** + Public construct method. It is necessary for ANT task. + **/ + 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 PlatformName_build.xml file for Flatform build;
  • +
  • Collect PCD information.
  • +
+ + @throws BuildException + Surface area is not valid. + **/ + public void execute() throws BuildException { + this.setTaskName("FpdParser"); + + // + // Parse FPD file + // + parseFpdFile(); + + // + // 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(); + getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/")); + + // + // Gen Fv.inf files + // + genFvInfFiles(ffsCommonDir); + } + } + + // + // Gen build.xml + // + 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(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 FV_DIR. + + @throws BuildException + File write FV.inf files error. + **/ + void genFvInfFiles(String ffsCommonDir) throws BuildException { + String[] validFv = saq.getFpdValidImageNames(); + for (int i = 0; i < validFv.length; i++) { + // + // Get all global variables from FPD and set them to properties + // + String[][] globalVariables = saq.getFpdGlobalVariable(); + for (int j = 0; j < globalVariables.length; j++) { + getProject().setProperty(globalVariables[j][0], globalVariables[j][1]); + } + + 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 = saq.getFpdOptions(validFv[i]); + if (options.length > 0) { + bw.write("[options]"); + bw.newLine(); + for (int j = 0; j < options.length; j++) { + StringBuffer str = new StringBuffer(100); + str.append(options[j][0]); + while (str.length() < 40) { + str.append(' '); + } + str.append("= "); + str.append(options[j][1]); + bw.write(getProject().replaceProperties(str.toString())); + bw.newLine(); + } + bw.newLine(); + } + + // + // Attributes; + // + String[][] attributes = saq.getFpdAttributes(validFv[i]); + if (attributes.length > 0) { + bw.write("[attributes]"); + bw.newLine(); + for (int j = 0; j < attributes.length; j++) { + StringBuffer str = new StringBuffer(100); + str.append(attributes[j][0]); + while (str.length() < 40) { + str.append(' '); + } + str.append("= "); + str.append(attributes[j][1]); + bw.write(getProject().replaceProperties(str.toString())); + bw.newLine(); + } + bw.newLine(); + } + + // + // Components + // + String[][] components = saq.getFpdComponents(validFv[i]); + if (components.length > 0) { + bw.write("[components]"); + bw.newLine(); + for (int j = 0; j < components.length; j++) { + StringBuffer str = new StringBuffer(100); + str.append(components[j][0]); + while (str.length() < 40) { + str.append(' '); + } + str.append("= "); + str.append(components[j][1]); + bw.write(getProject().replaceProperties(str.toString())); + bw.newLine(); + } + bw.newLine(); + } + + // + // Files + // + 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 = ffsCommonDir + File.separatorChar + outfiles.get(files[j]); + bw.write(getProject().replaceProperties("EFI_FILE_NAME = " + str)); + bw.newLine(); + } + } + bw.flush(); + bw.close(); + fw.close(); + } 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; + } + } + } + /** + This method is used for Single Module Build. + + + @throws BuildException + FPD file is not valid. + **/ + 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 { + XmlObject doc = XmlObject.Factory.parse(fpdFile); + + if (!doc.validate()) { + throw new BuildException("Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!"); + } + + 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(); + + // + // 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()); + } 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. + **/ + void parseModuleSAFiles() throws EdkException{ + Map> moduleSAs = saq.getFpdModules(); + + // + // For every Module lists in FPD file. + // + Set keys = moduleSAs.keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()) { + FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next(); + + // + // Judge if Module is existed? + // TBD + GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId)); + + // + // Put fpdModuleId to the corresponding FV + // + saq.push(GlobalData.getDoc(fpdModuleId)); + String fvBinding = saq.getModuleFvBindingKeyword(); + + fpdModuleId.setFvBinding(fvBinding); + updateFvs(fvBinding, fpdModuleId); + + // + // Prepare for out put file name + // + ModuleIdentification moduleId = fpdModuleId.getModule(); + + String baseName = saq.getModuleOutputFileBasename(); + + if (baseName == null) { + baseName = moduleId.getName(); + } + outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar + + moduleId.getGuid() + "-" + baseName + + getSuffix(moduleId.getModuleType())); + + // + // parse module build options, if any + // + 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 = ""; + } + 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. + + @param fvName current FV name + @param moduleName current module identification + **/ + 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 module type. Current relationship are listed: + +
+      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 moduleType module type + @return + @throws BuildException + If module type is null + **/ + public static String getSuffix(String moduleType) throws BuildException { + if (moduleType == null) { + throw new BuildException("Module type is not specified."); + } + + String[][] suffix = EdkDefinitions.ModuleTypeExtensions; + + for (int i = 0; i < suffix.length; i++) { + if (suffix[i][0].equalsIgnoreCase(moduleType)) { + return suffix[i][1]; + } + } + // + // Default is '.FFS' + // + return ".FFS"; + } + /** + Add a property. + + @param p property + **/ + public void addProperty(Property p) { + properties.addElement(p); + } + + public void setFpdFile(File fpdFile) { + this.fpdFile = fpdFile; + } + + public void setType(String type) { + this.type = type; + } + + 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; + } + + 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"); + } + } + } + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java b/Tools/Java/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java new file mode 100644 index 0000000000..d4b4622c60 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java @@ -0,0 +1,619 @@ +/** @file + + 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.File; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +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.Project; +import org.tianocore.build.global.GlobalData; +import org.tianocore.build.global.SurfaceAreaQuery; +import org.tianocore.build.id.FpdModuleIdentification; +import org.tianocore.build.id.ModuleIdentification; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + class PlatformBuildFileGenerator is used to generate ${PLATFORM}_build.xml file. + + @since GenBuild 1.0 +**/ +public class PlatformBuildFileGenerator { + + /// + /// Mapping from modules identification to out put file name + /// + private Map outfiles; + + /// + /// Mapping from FV name to its modules + /// + private Map> fvs = new HashMap>(); + + + private boolean isUnified = true; + + private SurfaceAreaQuery saq = null; + + private File platformBuildFile = null; + + private Project project; + + private String info = "DO NOT EDIT \n" + + "This file is auto-generated by the build utility\n" + + "\n" + + "Abstract:\n" + + "Auto-generated ANT build file for building EFI Modules and Platforms\n"; + + public PlatformBuildFileGenerator(Project project, Map outfiles, Map> fvs, boolean isUnified, SurfaceAreaQuery saq, String platformBuildFile){ + this.project = project; + this.outfiles = outfiles; + this.isUnified = isUnified; + this.fvs = fvs; + this.saq = saq; + this.platformBuildFile = new File(platformBuildFile); + } + + /** + Generate build.out.xml file. + + @throws BuildException + build.out.xml XML document create error + **/ + public 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", project.getProperty("PLATFORM")); + root.setAttribute("default", "all"); + 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("taskdef"); + ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml"); + 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", "all"); + ele.setAttribute("depends", "prebuild, modules, fvs, postbuild"); + root.appendChild(ele); + + // + // Modules and Fvs Target + // + applyModules(document, root); + + applyFvs(document, root); + + // + // Clean Target + // + applyClean(document, root); + + // + // Deep Clean Target + // + applyCleanall(document, root); + + // + // User Extension pre build + // + applyUserExtensionsPreBuild(document, root); + + // + // User Extension Post build + // + applyUserExtensionsPostBuild(document, root); + + document.appendChild(rootComment); + document.appendChild(root); + // + // Prepare the DOM document for writing + // + Source source = new DOMSource(document); + // + // generate all directory path + // + (new File(platformBuildFile.getParent())).mkdirs(); + Result result = new StreamResult(platformBuildFile); + // + // 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("Generating platform build file [" + platformBuildFile.getPath() + "_build.xml] failed. \n" + ex.getMessage()); + } + } + + /** + 1. Get All valid Fv Image Names in sequence + 2. For each FV, get modules by sequences + 3. Get other modules + + @param document XML document + @param root Node + **/ + private void applyModules(Document document, Node root) { + root.appendChild(document.createComment("Modules target")); + Element ele = document.createElement("target"); + ele.setAttribute("name", "modules"); + + // + // Get all valid FV name + // + String[] validFv = saq.getFpdValidImageNames(); + + // + // For each valid FV, get all modules in sequence + // + for (int i = 0; i < validFv.length; i++) { + if (fvs.containsKey(validFv[i])) { + Set set = fvs.get(validFv[i]); + Iterator iter = set.iterator(); + while (iter.hasNext()) { + FpdModuleIdentification fpdModuleId = iter.next(); + applySingleModule(document, ele, fpdModuleId); + } + } + } + + // + // Get all other modules + // + Iterator fvsNameIter = fvs.keySet().iterator(); + + while (fvsNameIter.hasNext()) { + String fvName = fvsNameIter.next(); + if (!isContain(validFv, fvName)) { + Set set = fvs.get(fvName); + Iterator iter = set.iterator(); + while (iter.hasNext()) { + FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next(); + applySingleModule(document, ele, fpdModuleId); + } + } + } + + root.appendChild(ele); + } + + private void applySingleModule(Document document, Node root, FpdModuleIdentification fpdModuleId) { + ModuleIdentification moduleId = fpdModuleId.getModule(); + Element moduleEle = document.createElement("GenBuild"); + moduleEle.setAttribute("type", "build"); + // + // Inherit Properties. + //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"} + // + + // + // ARCH + // + Element property = document.createElement("property"); + property.setAttribute("name", "ARCH"); + property.setAttribute("value", fpdModuleId.getArch()); + moduleEle.appendChild(property); + + // + // MODULE_GUID + // + property = document.createElement("property"); + property.setAttribute("name", "MODULE_GUID"); + property.setAttribute("value", moduleId.getGuid()); + moduleEle.appendChild(property); + + // + // MODULE_VERSION + // + property = document.createElement("property"); + property.setAttribute("name", "MODULE_VERSION"); + property.setAttribute("value", moduleId.getVersion()); + moduleEle.appendChild(property); + + // + // PACKAGE_GUID + // + property = document.createElement("property"); + property.setAttribute("name", "PACKAGE_GUID"); + property.setAttribute("value", moduleId.getPackage().getGuid()); + moduleEle.appendChild(property); + + // + // PACKAGE_VERSION + // + property = document.createElement("property"); + property.setAttribute("name", "PACKAGE_VERSION"); + property.setAttribute("value", moduleId.getPackage().getVersion()); + moduleEle.appendChild(property); + + root.appendChild(moduleEle); + } + + private boolean isContain(String[] list, String item) { + for (int i = 0; i < list.length; i++) { + if (list[i].equalsIgnoreCase(item)) { + return true; + } + } + return false; + } + + private void applyFvs(Document document, Node root) { + // + // FVS Target + // + root.appendChild(document.createComment("FVs target")); + Element ele = document.createElement("target"); + ele.setAttribute("name", "fvs"); + + // + // 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++){ + String fvOutputDir = project.getProperty("BUILD_DIR") + File.separatorChar + + targetList[i] + "_" + + toolchainList[j] + File.separatorChar + "FV"; + String[] validFv = saq.getFpdValidImageNames(); + for (int k = 0; k < validFv.length; k++) { + String inputFile = fvOutputDir + "" + File.separatorChar + validFv[k].toUpperCase() + ".inf"; + Element fvEle = document.createElement("genfvimage"); + fvEle.setAttribute("infFile", inputFile); + fvEle.setAttribute("outputDir", fvOutputDir); + ele.appendChild(fvEle); + } + } + } + root.appendChild(ele); + } + + private void applyClean(Document document, Node root) { + // + // Clean Target + // + root.appendChild(document.createComment("Clean target")); + Element 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", project.getProperty("BUILD_DIR")); + filesetEle.setAttribute("includes", "**\\OUTPUT\\**"); + cleanEle.appendChild(filesetEle); + ele.appendChild(cleanEle); + } else { + Set set = outfiles.keySet(); + Iterator iter = set.iterator(); + while (iter.hasNext()) { + FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next(); + ModuleIdentification moduleId = fpdModuleId.getModule(); + + Element ifEle = document.createElement("if"); + Element availableEle = document.createElement("available"); + availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar + + "build.xml"); + ifEle.appendChild(availableEle); + Element elseEle = document.createElement("then"); + + Element moduleEle = document.createElement("ant"); + moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar + + "build.xml"); + moduleEle.setAttribute("target", "clean"); + // + // Inherit Properties. + //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"} + // + + // + // ARCH + // + Element property = document.createElement("property"); + property.setAttribute("name", "ARCH"); + property.setAttribute("value", fpdModuleId.getArch()); + moduleEle.appendChild(property); + + // + // PACKAGE + // + property = document.createElement("property"); + property.setAttribute("name", "PACKAGE"); + property.setAttribute("value", moduleId.getPackage().getName()); + moduleEle.appendChild(property); + + // + // PACKAGE_GUID + // + property = document.createElement("property"); + property.setAttribute("name", "PACKAGE_GUID"); + property.setAttribute("value", moduleId.getPackage().getGuid()); + moduleEle.appendChild(property); + + // + // PACKAGE_VERSION + // + property = document.createElement("property"); + property.setAttribute("name", "PACKAGE_VERSION"); + property.setAttribute("value", moduleId.getPackage().getVersion()); + moduleEle.appendChild(property); + + // + // MODULE_DIR + // + property = document.createElement("property"); + property.setAttribute("name", "MODULE_DIR"); + property.setAttribute("value", moduleId.getMsaFile().getParent()); + moduleEle.appendChild(property); + elseEle.appendChild(moduleEle); + ifEle.appendChild(elseEle); + ele.appendChild(ifEle); + } + } + root.appendChild(ele); + } + + private void applyCleanall(Document document, Node root) { + // + // Deep Clean Target + // + root.appendChild(document.createComment("Target: cleanall")); + Element ele = document.createElement("target"); + ele.setAttribute("name", "cleanall"); + + if (isUnified) { + 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++) { + Element cleanAllEle = document.createElement("delete"); + cleanAllEle.setAttribute("dir", project.getProperty("BUILD_DIR") + File.separatorChar + targetList[i] + "_" + toolchainList[j]); + ele.appendChild(cleanAllEle); + } + } + } else { + Set set = outfiles.keySet(); + Iterator iter = set.iterator(); + while (iter.hasNext()) { + FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next(); + ModuleIdentification moduleId = fpdModuleId.getModule(); + + Element ifEle = document.createElement("if"); + Element availableEle = document.createElement("available"); + availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar + + "build.xml"); + ifEle.appendChild(availableEle); + Element elseEle = document.createElement("then"); + + Element moduleEle = document.createElement("ant"); + moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar + + "build.xml"); + moduleEle.setAttribute("target", "cleanall"); + // + // Inherit Properties. + //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"} + // + + // + // ARCH + // + Element property = document.createElement("property"); + property.setAttribute("name", "ARCH"); + property.setAttribute("value", fpdModuleId.getArch()); + moduleEle.appendChild(property); + + // + // PACKAGE + // + property = document.createElement("property"); + property.setAttribute("name", "PACKAGE"); + property.setAttribute("value", moduleId.getPackage().getName()); + moduleEle.appendChild(property); + + // + // PACKAGE_GUID + // + property = document.createElement("property"); + property.setAttribute("name", "PACKAGE_GUID"); + property.setAttribute("value", moduleId.getPackage().getGuid()); + moduleEle.appendChild(property); + + // + // PACKAGE_VERSION + // + property = document.createElement("property"); + property.setAttribute("name", "PACKAGE_VERSION"); + property.setAttribute("value", moduleId.getPackage().getVersion()); + moduleEle.appendChild(property); + + // + // MODULE_DIR + // + property = document.createElement("property"); + property.setAttribute("name", "MODULE_DIR"); + property.setAttribute("value", moduleId.getMsaFile().getParent()); + moduleEle.appendChild(property); + elseEle.appendChild(moduleEle); + ifEle.appendChild(elseEle); + ele.appendChild(ifEle); + } + } + root.appendChild(ele); + } + + private void applyUserExtensionsPreBuild(Document document, Node root) { + // + // User Extensions + // + root.appendChild(document.createComment("Pre-Build Processing")); + Element ele = document.createElement("target"); + ele.setAttribute("name", "prebuild"); + + Node node = saq.getFpdUserExtensionPreBuild(); + if (node != null) { + // + // 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 = project.getProperty("BUILD_DIR") + File.separatorChar + + targetList[i] + "_" + + toolchainList[j]; + File fvDir = new File(ffsCommonDir + File.separatorChar + "FV"); + Element fvEle = document.createElement("var"); + fvEle.setAttribute("name", "FV_DIR"); + fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/")); + ele.appendChild(fvEle); + + Element targetDirEle = document.createElement("var"); + targetDirEle.setAttribute("name", "TARGET_DIR"); + targetDirEle.setAttribute("value", ffsCommonDir.replaceAll("(\\\\)", "/")); + ele.appendChild(targetDirEle); + + NodeList childNodes = node.getChildNodes(); + for (int k = 0; k < childNodes.getLength(); k++) { + Node childItem = childNodes.item(k); + if (childItem.getNodeType() == Node.ELEMENT_NODE) { + ele.appendChild(recursiveNode(childItem, document)); + } + } + } + } + } + + root.appendChild(ele); + } + + private void applyUserExtensionsPostBuild(Document document, Node root) { + // + // User Extensions + // + root.appendChild(document.createComment("Post-Build Processing")); + Element ele = document.createElement("target"); + ele.setAttribute("name", "postbuild"); + + Node node = saq.getFpdUserExtensionPostBuild(); + if (node != null) { + // + // 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 = project.getProperty("BUILD_DIR") + File.separatorChar + + targetList[i] + "_" + + toolchainList[j]; + File fvDir = new File(ffsCommonDir + File.separatorChar + "FV"); + Element fvEle = document.createElement("var"); + fvEle.setAttribute("name", "FV_DIR"); + fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/")); + ele.appendChild(fvEle); + + Element targetDirEle = document.createElement("var"); + targetDirEle.setAttribute("name", "TARGET_DIR"); + targetDirEle.setAttribute("value", ffsCommonDir.replaceAll("(\\\\)", "/")); + ele.appendChild(targetDirEle); + + NodeList childNodes = node.getChildNodes(); + for (int k = 0; k < childNodes.getLength(); k++) { + Node childItem = childNodes.item(k); + if (childItem.getNodeType() == Node.ELEMENT_NODE) { + ele.appendChild(recursiveNode(childItem, document)); + } + } + + } + } + } + + root.appendChild(ele); + } + + private Element recursiveNode(Node node, Document document) { + Element root = document.createElement(node.getNodeName()); + NamedNodeMap attr = node.getAttributes(); + for (int i = 0; i < attr.getLength(); i++) { + Node attrItem = attr.item(i); + root.setAttribute(attrItem.getNodeName(), attrItem.getNodeValue()); + } + NodeList childNodes = node.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node childItem = childNodes.item(i); + if (childItem.getNodeType() == Node.ELEMENT_NODE) { + root.appendChild(recursiveNode(childItem, document)); + } + else if (childItem.getNodeType() == Node.TEXT_NODE){ + if (!childItem.getNodeValue().trim().equalsIgnoreCase("")) { + root.setTextContent(childItem.getNodeValue()); + } + } + } + return root; + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/global/DpFile.java b/Tools/Java/Source/GenBuild/org/tianocore/build/global/DpFile.java new file mode 100644 index 0000000000..af6590f5b6 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/global/DpFile.java @@ -0,0 +1,130 @@ +/** @file +This file is used to define class which represents dependency file in ANT task + +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.global; + +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.BuildException; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + DpFile is a ANT DataType which can be used to specify dependency files from + a file list file, from file list string separated by space, comma or semi-comma, + or from file name with absolute path + **/ +public class DpFile extends DataType { + /// + /// keep the list of files path + /// + private List nameList = new ArrayList(); + + /** + Empty constructor just in case + **/ + public DpFile() { + } + + /** + Empty execute method of ANT task, just in case + **/ + public void execute() { + } + + /** + Standard set method of ANT task/datatype, for ListFile attribute. It simply + fetch one file path a line from specified list file, and put them in nameList + + @param fileListFile file which contains a file list, one file a line, + with full path + **/ + public void setListFile(String fileListFile) { + File file = new File(fileListFile); + if (!file.exists()) { + return; + } + + try { + FileReader fileReader = new FileReader(file); + LineNumberReader lineReader = new LineNumberReader(fileReader); + + String filePath = null; + while ((filePath = lineReader.readLine()) != null) { + filePath = filePath.trim(); + if (filePath.length() == 0) { + continue; + } + this.nameList.add(filePath); + } + + lineReader.close(); + fileReader.close(); + } catch (IOException e) { + throw new BuildException(e.getMessage()); + } + } + + /** + Standard set method of ANT task/datatype, for List attribute. + + @param fileList string with file pathes separated by space, comma, + or semi-comma + **/ + public void setList(String fileList) { + // + // space, comma or semi-comma separated files list + // + Pattern pattern = Pattern.compile("([^ ,;\n\r]++)[ ,;\n\r]*+"); + Matcher matcher = pattern.matcher(fileList); + + while (matcher.find()) { + // + // keep each file name before " ,;\n\r" + // + String filePath = fileList.substring(matcher.start(1), matcher.end(1)).trim(); + if (filePath.length() == 0) { + continue; + } + nameList.add(Path.translateFile(filePath)); + } + + } + + /** + Standard set method of ANT task/datatype, for Name attribute. + + @param fileName string of a file full path + **/ + public void setName(String fileName) { + this.nameList.add(fileName); + } + + /** + Fetch the file name list. + + @returns A string list which contains file names specified to check dependnecy + **/ + public List getList() { + return this.nameList; + } +} + + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/global/DpFileList.java b/Tools/Java/Source/GenBuild/org/tianocore/build/global/DpFileList.java new file mode 100644 index 0000000000..dd032526d8 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/global/DpFileList.java @@ -0,0 +1,64 @@ +/** @file +This file is used to nest elements corresponding to DpFile + +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.global; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.FileSet; + +/** + DpFileList is a container of Dpfile at the point of ANT task/datatype + **/ +public class DpFileList extends DataType { + /// + /// Keep all the file names from all nested DpFile + /// + List nameList = new ArrayList(); + + /** + Empty constructor just in case + **/ + public DpFileList() { + } + + /** + Empty execute method of ANT task. ANT will call it even we don't need it. + **/ + public void execute() { + } + + /** + Standard add method of ANT task, for nested DpFile type of elements. It just + simply fetch the files list from DpFile and put them in its own nameList. + + @param f a DpFile object which will be instantiated by ANT + **/ + public void addConfiguredFile(DpFile f) { + this.nameList.addAll(f.getList()); + } + + public void addConfiguredFileSet(FileSet fileSet) { + DirectoryScanner ds = fileSet.getDirectoryScanner(getProject()); + String dir = fileSet.getDir(getProject()).getAbsolutePath(); + String[] files = ds.getIncludedFiles(); + + for (int i = 0; i < files.length; ++i) { + nameList.add(dir + "/" + files[i]); + } + } +} + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/global/GenBuildLogger.java b/Tools/Java/Source/GenBuild/org/tianocore/build/global/GenBuildLogger.java new file mode 100644 index 0000000000..c7bc01599b --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/global/GenBuildLogger.java @@ -0,0 +1,274 @@ +/*++ + + 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. + + Module Name: + GenBuildLogger.java + + Abstract: + + --*/ + +package org.tianocore.build.global; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringReader; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DefaultLogger; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.util.StringUtils; + +import org.tianocore.build.id.FpdModuleIdentification; +import org.tianocore.common.logger.EdkLog; +import org.tianocore.common.logger.LogMethod; + +public class GenBuildLogger extends DefaultLogger implements LogMethod { + + Project project = null; + + /// + /// flag to present whether cache all msg or not + /// true means to cache. + /// + private static boolean flag = false; + + private static boolean enableFlag = true; + + private static Map> map = new LinkedHashMap >(256); + + private FpdModuleIdentification id = null; + + public GenBuildLogger () { + + } + + public GenBuildLogger (Project project) { + this.project = project; + } + + /** + Rules: flag = false: means no cache Action: Print it to console + + flag = true: mean cache all msg exception some special Action: loglevel + is EDK_ALWAYS -- Print but no cache loglevel is EDK_ERROR -- Print and + cache the msg others -- No print and cache the msg + **/ + public synchronized void putMessage(Object msgSource, int msgLevel, String msg) { + if (this.project == null) { + return; + } + + // + // If msgLevel is always print, then print it + // + switch (msgLevel) { + case EdkLog.EDK_ALWAYS: + // + // Do some special + // + log(msgSource, msg, Project.MSG_ERR); + break; + case EdkLog.EDK_ERROR: + log(msgSource, msg, Project.MSG_ERR); + break; + case EdkLog.EDK_WARNING: + log(msgSource, msg, Project.MSG_WARN); + break; + case EdkLog.EDK_INFO: + log(msgSource, msg, Project.MSG_INFO); + break; + case EdkLog.EDK_VERBOSE: + log(msgSource, msg, Project.MSG_VERBOSE); + break; + case EdkLog.EDK_DEBUG: + log(msgSource, msg, Project.MSG_DEBUG); + break; + } + } + + public static void flushErrorModuleLog(FpdModuleIdentification errorModuleId) { + List errorLogs = map.get(errorModuleId); + if (errorLogs != null) { + EdkLog.log("ErrorLog", EdkLog.EDK_ERROR, errorModuleId + " error logs: "); + for(int i = 0; i < errorLogs.size(); i++) { + EdkLog.log(EdkLog.EDK_ERROR, errorLogs.get(i)); + } + } + } + + public void flushToFile(File file) { + // + // Put all messages in map to file + // + String msg = "Writing log to file [" + file.getPath() + "]"; + log("Logging", msg, Project.MSG_INFO); + try { + BufferedWriter bw = new BufferedWriter(new FileWriter(file)); + Iterator iter = map.keySet().iterator(); + List mainLogs = null; + while (iter.hasNext()) { + FpdModuleIdentification item = iter.next(); + if(item == null) { + mainLogs = map.get(item); + continue ; + } + bw.write(">>>>>>>>>>>>>"); + bw.write(" " + item + " Build Log "); + bw.write(">>>>>>>>>>>>>"); + bw.newLine(); + List allMessages = map.get(item); + for(int i = 0; i < allMessages.size(); i++) { + bw.write(allMessages.get(i)); + bw.newLine(); + } + } + if (mainLogs != null) { + bw.write(">>>>>>>>>>>>>"); + bw.write(" Main Logs (already print to command) "); + bw.write(">>>>>>>>>>>>>"); + bw.newLine(); + for(int i = 0; i < mainLogs.size(); i++) { + bw.write(mainLogs.get(i)); + bw.newLine(); + } + } + bw.flush(); + bw.close(); + } catch (IOException e) { + new BuildException("Writing log error. " + e.getMessage()); + } + + } + + private void log(Object msgSource, String msg, int level) { + if (msgSource instanceof Task) { + ((Task)msgSource).getProject().log((Task)msgSource, msg, level); + } else if (msgSource instanceof String){ + // + // Pad 12 space to keep message in unify format + // + msg = msg.replaceAll("\n", "\n "); + this.project.log(String.format("%12s", "[" + msgSource + "] ") + msg, level); + } else { + this.project.log(msg, level); + } + } + public void targetStarted(BuildEvent event) { + if (!flag) { + super.targetStarted(event); + } + } + + public void messageLogged(BuildEvent event) { + if (!enableFlag) { + return ; + } + int currentLevel = event.getPriority(); + // + // If current level is upper than Ant Level, skip it + // + if (currentLevel <= this.msgOutputLevel) { + String originalMessage = event.getMessage(); + + StringBuffer message = new StringBuffer(); + if (!emacsMode && event.getTask() != null) { + String label = String.format("%12s", "[" + event.getTask().getTaskName() + "] "); + // + // Append label first + // + message.append(label); + + // + // Format all output message's line separator + // + try { + BufferedReader r = new BufferedReader(new StringReader(originalMessage)); + boolean ifFirstLine = true; + String line = null; + while ((line = r.readLine()) != null) { + if (!ifFirstLine) { + message.append(StringUtils.LINE_SEP); + } + ifFirstLine = false; + message.append(line); + } + } catch (IOException e) { + message.append(originalMessage); + } + } else { + message.append(originalMessage); + } + + String msg = message.toString(); + if (currentLevel == Project.MSG_ERR) { + printMessage(msg, err, currentLevel); + } else if(currentLevel == Project.MSG_WARN) { + printMessage(msg, out, currentLevel); + } else if(!flag) { + printMessage(msg, out, currentLevel); + } + log(msg); + } + } + + public static void setCacheEnable(boolean enable) { + flag = enable; + } + + public static void maskAllLog(boolean enable) { + enableFlag = !enable; + } + + protected synchronized void log(String message) { + // + // cache log + // + if (map.containsKey(this.id)) { + map.get(this.id).add(message); + } else { + List list = new Vector(1024); + list.add(message); + map.put(this.id, list); + } + } + + public Object clone() { + GenBuildLogger newLogger = new GenBuildLogger(); + // + // Transfer emacs mode, out, err, level to new Logger + // + newLogger.setEmacsMode(this.emacsMode); + newLogger.setOutputPrintStream(this.out); + newLogger.setErrorPrintStream(this.err); + newLogger.setMessageOutputLevel(this.msgOutputLevel); + + // + // Transfer project + // + newLogger.project = this.project; + return newLogger; + } + + public void setId(FpdModuleIdentification id) { + this.id = id; + } +} \ No newline at end of file diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/global/GlobalData.java b/Tools/Java/Source/GenBuild/org/tianocore/build/global/GlobalData.java new file mode 100644 index 0000000000..ceb19d91db --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/global/GlobalData.java @@ -0,0 +1,958 @@ +/** @file + GlobalData class. + + GlobalData provide initializing, instoring, querying and update global data. + It is a bridge to intercommunicate between multiple component, such as AutoGen, + PCD and so on. + +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.global; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; + +import org.tianocore.common.exception.EdkException; +import org.tianocore.common.logger.EdkLog; +import org.tianocore.pcd.entity.MemoryDatabaseManager; +import org.tianocore.DbPathAndFilename; +import org.tianocore.FrameworkDatabaseDocument; +import org.tianocore.ModuleSurfaceAreaDocument; +import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea; +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.toolchain.ToolChainAttribute; +import org.tianocore.build.toolchain.ToolChainConfig; +import org.tianocore.build.toolchain.ToolChainElement; +import org.tianocore.build.toolchain.ToolChainInfo; +import org.tianocore.build.toolchain.ToolChainKey; +import org.tianocore.build.toolchain.ToolChainMap; + +/** + GlobalData provide initializing, instoring, querying and update global data. + It is a bridge to intercommunicate between multiple component, such as AutoGen, + PCD and so on. + +

Note that all global information are initialized incrementally. All data will + parse and record only of necessary during build time.

+ + @since GenBuild 1.0 +**/ +public class GlobalData { + /// + /// Record current WORKSPACE Directory + /// + private static String workspaceDir = ""; + + /// + /// Be used to ensure Global data will be initialized only once. + /// + private static boolean globalFlag = false; + + /// + /// Framework Database information: package list and platform list + /// + private static Set packageList = new HashSet(); + + private static Set platformList = new HashSet(); + + /// + /// Every detail SPD informations: Module list, Library class definition, + /// Package header file, GUID/PPI/Protocol definitions + /// + private static final Map spdTable = new HashMap(); + + /// + /// Build informations are divided into three parts: + /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA + /// + private static Map> nativeMsa = new HashMap>(); + + private static Map> fpdModuleSA= new HashMap>(); + + private static Map fpdBuildOptionsMap = new HashMap(); + + private static XmlObject fpdBuildOptions; + + private static XmlObject fpdDynamicPcds; + + /// + /// Parsed modules list + /// + private static Map> parsedModules = new HashMap>(); + + /// + /// built modules list with ARCH, TARGET, TOOLCHAIN + /// + private static Set builtModules = new HashSet(); + + /// + /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD. + /// + private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager(); + + /// + /// build target + tool chain family/tag name + arch + command types + command options + /// + /// + /// Tool Chain Data + /// toolsDef - build tool program information + /// fpdBuildOption - all modules's build options for tool tag or tool chain families + /// moduleSaBuildOption - build options for a specific module + /// + private static ToolChainConfig toolsDef; + + private static ToolChainInfo toolChainInfo; + private static ToolChainInfo toolChainEnvInfo; + private static ToolChainInfo toolChainPlatformInfo; + + private static ToolChainMap platformToolChainOption; + private static ToolChainMap platformToolChainFamilyOption; + + private static Map moduleToolChainOption = new HashMap(); + private static Map moduleToolChainFamilyOption = new HashMap(); + + /** + Parse framework database (DB) and all SPD files listed in DB to initialize + the environment for next build. This method will only be executed only once + in the whole build process. + + @param workspaceDatabaseFile the file name of framework database + @param workspaceDir current workspace directory path + @throws BuildException + Framework Dababase or SPD or MSA file is not valid + **/ + public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir, String toolsDefFilename ) throws EdkException { + // + // ensure this method will be revoked only once + // + if (globalFlag) { + return; + } + globalFlag = true; + + // + // Backup workspace directory. It will be used by other method + // + GlobalData.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/"); + + // + // Parse tools definition file + // + // + // If ToolChain has been set up before, do nothing. + // CONF dir + tools definition file name + // + File toolsDefFile = new File(workspaceDir + File.separatorChar + toolsDefFilename); + EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Using tool definition file [" + toolsDefFile.getPath() + "]."); + toolsDef = new ToolChainConfig(toolsDefFile); + + // + // Parse Framework Database + // + File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile); + try { + FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile); + // + // validate FrameworkDatabaseFile + // + if (!db.validate()) { + throw new EdkException("Framework Database file [" + dbFile.getPath() + "] format is invalid!"); + } + // + // Get package list + // + if (db.getFrameworkDatabase().getPackageList() != null ) { + List packages = db.getFrameworkDatabase().getPackageList().getFilenameList(); + Iterator iter = packages.iterator(); + while (iter.hasNext()) { + String fileName = iter.next().getStringValue().trim(); + Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName)); + packageList.add(spd.getPackageId()); + // + // Report warning if existing two packages with same GUID and Version + // + if (spdTable.containsKey(spd.getPackageId())) { + // + // BUGBUG + // + EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two packages with same GUID and Version. They are ... " + spd.getPackageId().getSpdFile().getPath()); + } + spdTable.put(spd.getPackageId(), spd); + } + } + + // + // Get platform list + // + if (db.getFrameworkDatabase().getPlatformList() != null) { + List platforms = db.getFrameworkDatabase().getPlatformList().getFilenameList(); + Iterator iter = platforms.iterator(); + while (iter.hasNext()) { + String fileName = iter.next().getStringValue().trim(); + File fpdFile = new File(workspaceDir + File.separatorChar + fileName); + if ( !fpdFile.exists() ) { + throw new EdkException("Platform file [" + fpdFile.getPath() + "] not exists. "); + } + XmlObject fpdDoc = XmlObject.Factory.parse(fpdFile); + // + // Verify FPD file, if is invalid, throw Exception + // + if (!fpdDoc.validate()) { + throw new EdkException("Framework Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!"); + } + // + // We can change Map to XmlObject + // + Map fpdDocMap = new HashMap(); + fpdDocMap.put("PlatformSurfaceArea", fpdDoc); + SurfaceAreaQuery saq = new SurfaceAreaQuery(fpdDocMap); + PlatformIdentification platformId = saq.getFpdHeader(); + platformId.setFpdFile(fpdFile); + // + // Report warning if existing two platfrom with same GUID and Version + // + if (platformList.contains(platformId)) { + // + // BUGBUG + // + EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two platforms with same GUID and Version. They are ... " + fpdFile.getPath()); + } + platformList.add(platformId); + } + } + } catch(IOException ex) { + EdkException edkException = new EdkException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; + } catch(XmlException ex) { + EdkException edkException = new EdkException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; + } + } + + /** + Get the current WORKSPACE Directory. + + @return current workspace directory + **/ + public synchronized static String getWorkspacePath() { + return workspaceDir; + } + + + /** + Get the MSA file name with absolute path + */ + public synchronized static File getMsaFile(ModuleIdentification moduleId) throws EdkException { + File msaFile = null; + // + // TBD. Do only when package is null. + // + Iterator iter = packageList.iterator(); + while (iter.hasNext()) { + PackageIdentification packageId = (PackageIdentification)iter.next(); + Spd spd = spdTable.get(packageId); + msaFile = spd.getModuleFile(moduleId); + if (msaFile != null ) { + break ; + } + } + if (msaFile == null){ + throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!"); + } else { + return msaFile; + } + } + + public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) throws EdkException { + // + // If package already defined in module + // + if (moduleId.getPackage() != null) { + return moduleId.getPackage(); + } + + PackageIdentification packageId = null; + Iterator iter = packageList.iterator(); + while (iter.hasNext()) { + packageId = (PackageIdentification)iter.next(); + moduleId.setPackage(packageId); + Spd spd = spdTable.get(packageId); + File tempMsaFile = null; + if ((tempMsaFile = spd.getModuleFile(moduleId)) != null ) { + if (tempMsaFile.getParent().equalsIgnoreCase(moduleId.getMsaFile().getParent())) { + break ; + } + tempMsaFile = null; + } + } + if (packageId == null){ + throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!"); + } else { + return packageId; + } + } + + /** + Difference between build and parse: ToolChain and Target + **/ + public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) { + return builtModules.contains(moduleId); + } + + public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) { + builtModules.add(fpdModuleId); + } + + + public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map doc) throws EdkException{ + Map result = new HashMap(); + Set keySet = doc.keySet(); + Iterator iter = keySet.iterator(); + while (iter.hasNext()){ + String key = (String)iter.next(); + XmlObject item = cloneXmlObject(doc.get(key), true); + result.put(key, item); + } + fpdModuleSA.put(fpdModuleId, result); + } + + public synchronized static boolean hasFpdModuleSA(FpdModuleIdentification fpdModuleId) { + return fpdModuleSA.containsKey(fpdModuleId); + } + + /** + Query module surface area information. + +

Note that surface area parsing is incremental. That means the method will + only parse the MSA files if necessary.

+ + @param fpdModuleId Module ID with arch + @return ModuleSA info and MSA info for fpdModuleId + @throws BuildException Can't find MSA + **/ + public synchronized static Map getDoc(FpdModuleIdentification fpdModuleId) throws EdkException{ + if (parsedModules.containsKey(fpdModuleId)) { + return parsedModules.get(fpdModuleId); + } + Map doc = new HashMap(); + ModuleIdentification moduleId = fpdModuleId.getModule(); + // + // First part: get the MSA files info + // + doc.putAll(getNativeMsa(moduleId)); + + // + // Second part: put build options + // + doc.put("BuildOptions", fpdBuildOptions); + + // + // Third part: get Module info from FPD, such as Library instances, PCDs + // + if (fpdModuleSA.containsKey(fpdModuleId)){ + // + // merge module info in FPD to final Doc + // For Library Module, do nothing here + // + doc.putAll(fpdModuleSA.get(fpdModuleId)); + } + parsedModules.put(fpdModuleId, doc); + return doc; + } + + public synchronized static Map getDoc(ModuleIdentification moduleId, String arch) throws EdkException{ + FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch); + return getDoc(fpdModuleId); + } + + /** + Query the native MSA information with module base name. + +

Note that MSA parsing is incremental. That means the method will + only to parse the MSA files when never parsed before.

+ + @param moduleName the base name of the module + @return the native MSA information + @throws BuildException + MSA file is not valid + **/ + public synchronized static Map getNativeMsa(ModuleIdentification moduleId) throws EdkException { + if (nativeMsa.containsKey(moduleId)) { + return nativeMsa.get(moduleId); + } + File msaFile = getMsaFile(moduleId); + Map msaMap = getNativeMsa(msaFile); + nativeMsa.put(moduleId, msaMap); + return msaMap; + } + + public synchronized static Map getNativeMsa(File msaFile) throws EdkException { + if (!msaFile.exists()) { + throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] can't be found!"); + } + try { + ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile); + // + // Validate File if they accord with XML Schema + // + if ( !doc.validate()){ + throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] format is invalid!"); + } + // + // parse MSA file + // + ModuleSurfaceArea msa= doc.getModuleSurfaceArea(); + Map msaMap = new HashMap(); + msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true)); + msaMap.put("ModuleDefinitions", cloneXmlObject(msa.getModuleDefinitions(), true)); + msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true)); + msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true)); + msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true)); + msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true)); + msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true)); + msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true)); + msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true)); + msaMap.put("PcdCoded", cloneXmlObject(msa.getPcdCoded(), true)); + return msaMap; + } catch(IOException ex) { + EdkException edkException = new EdkException("Parsing MSA file [" + msaFile.getPath() + "] error. \n" + ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; + } catch(XmlException ex) { + EdkException edkException = new EdkException("Parsing MSA file [" + msaFile.getPath() + "] error. \n" + ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; + } + } + + public static Map getFpdBuildOptionsMap() { + return fpdBuildOptionsMap; + } + + public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws EdkException { + GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true); + fpdBuildOptionsMap.put("BuildOptions", GlobalData.fpdBuildOptions); + } + + public static XmlObject getFpdDynamicPcds() { + return fpdDynamicPcds; + } + + public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) { + GlobalData.fpdDynamicPcds = fpdDynamicPcds; + } + + public static Set getModules(PackageIdentification packageId){ + Spd spd = spdTable.get(packageId); + if (spd == null ) { + Set dummy = new HashSet(); + return dummy; + } else { + return spd.getModules(); + } + } + + /** + * The header file path is relative to workspace dir + */ + public static String[] getLibraryClassHeaderFiles( + PackageIdentification[] packages, String name) throws EdkException{ + if (packages == null) { + // throw Exception or not???? + return new String[0]; + } + String[] result = null; + for (int i = 0; i < packages.length; i++) { + Spd spd = spdTable.get(packages[i]); + // + // If find one package defined the library class + // + if ((result = spd.getLibClassIncluder(name)) != null) { + return result; + } + } + // + // If can't find library class declaration in every package + // + throw new EdkException("Can not find library class [" + name + + "] declaration in any SPD package!"); + } + + /** + * The header file path is relative to workspace dir + */ + public static String getPackageHeaderFiles(PackageIdentification packages, + String moduleType) { + if (packages == null) { + return new String(""); + } + Spd spd = spdTable.get(packages); + // + // If can't find package header file, skip it + // + String temp = null; + if (spd != null) { + if ((temp = spd.getPackageIncluder(moduleType)) != null) { + return temp; + } else { + temp = ""; + return temp; + } + } else { + return null; + } + } + + /** + * return two values: {cName, GuidValue} + */ + public static String[] getGuid(List packages, String name) { + if (packages == null) { + // throw Exception or not???? + return new String[0]; + } + String[] result = null; + Iterator item = packages.iterator(); + while (item.hasNext()){ + Spd spd = spdTable.get(item.next()); + // + // If find one package defined the GUID + // + if ((result = spd.getGuid(name)) != null) { + return result; + } + } + + return null; + } + + /** + * return two values: {cName, GuidValue} + */ + public static String[] getPpiGuid(List packages, + String name) { + if (packages == null) { + return new String[0]; + } + String[] result = null; + Iterator item = packages.iterator(); + while (item.hasNext()){ + Spd spd = spdTable.get(item.next()); + // + // If find one package defined the Ppi GUID + // + if ((result = spd.getPpi(name)) != null) { + return result; + } + } + return null; + } + + /** + * return two values: {cName, GuidValue} + */ + public static String[] getProtocolGuid(List packages, + String name) { + if (packages == null) { + return new String[0]; + } + String[] result = null; + Iterator item = packages.iterator(); + while (item.hasNext()){ + Spd spd = spdTable.get(item.next()); + // + // If find one package defined the protocol GUID + // + if ((result = spd.getProtocol(name))!= null){ + return result; + } + } + return null; + + } + + public synchronized static PlatformIdentification getPlatformByName(String name) throws EdkException { + Iterator iter = platformList.iterator(); + while(iter.hasNext()){ + PlatformIdentification platformId = (PlatformIdentification)iter.next(); + if (platformId.getName().equalsIgnoreCase(name)) { + return platformId; + } + } + throw new EdkException("Can't find platform [" + name + "] in the current WORKSPACE database!"); + } + + public synchronized static PlatformIdentification getPlatform(String filename) throws EdkException { + File file = new File(workspaceDir + File.separatorChar + filename); + Iterator iter = platformList.iterator(); + while(iter.hasNext()){ + PlatformIdentification platformId = (PlatformIdentification)iter.next(); + if (platformId.getFpdFile().getPath().equalsIgnoreCase(file.getPath())) { + return platformId; + } + } + throw new EdkException("Can't find platform file [" + filename + "] in the current WORKSPACE database!"); + } + + public synchronized static PackageIdentification refreshPackageIdentification(PackageIdentification packageId) throws EdkException { + Iterator iter = packageList.iterator(); + while(iter.hasNext()){ + PackageIdentification packageItem = (PackageIdentification)iter.next(); + if (packageItem.equals(packageId)) { + packageId.setName(packageItem.getName()); + packageId.setSpdFile(packageItem.getSpdFile()); + return packageId; + } + } + throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!"); + } + + public synchronized static ModuleIdentification refreshModuleIdentification(ModuleIdentification moduleId) throws EdkException { + PackageIdentification packageId = getPackageForModule(moduleId); + moduleId.setPackage(packageId); + Spd spd = spdTable.get(packageId); + if (spd == null) { + throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!"); + } + Set modules = spd.getModules(); + Iterator iter = modules.iterator(); + while (iter.hasNext()) { + ModuleIdentification item = iter.next(); + if (item.equals(moduleId)) { + moduleId.setName(item.getName()); + moduleId.setModuleType(item.getModuleType()); + moduleId.setMsaFile(item.getMsaFile()); + return moduleId; + } + } + throw new EdkException("Can't find module GUID value " + moduleId.toGuidString() + " in " + packageId + " under the current workspace!"); + } + + public synchronized static Set getPackageList(){ + return packageList; + } + + /** + BUGBUG: It is a walk around method. If do not clone, can't query info with + XPath correctly. + + @param object XmlObject + @param deep flag for deep clone + @return XmlObject after clone + @throws BuildException parse original XmlObject error. + **/ + private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws EdkException { + if ( object == null) { + return null; + } + XmlObject result = null; + try { + result = XmlObject.Factory.parse(object.getDomNode() + .cloneNode(deep)); + } catch (XmlException ex) { + EdkException edkException = new EdkException(ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; + } + return result; + } + + /// + /// Tool Chain Related, try to refine and put some logic process to ToolChainFactory + /// + public synchronized static ToolChainInfo getToolChainInfo() { + if (toolChainInfo == null) { + toolChainInfo = toolsDef.getConfigInfo().intersection(toolChainEnvInfo); + if (toolChainPlatformInfo != null) { + toolChainInfo = toolChainInfo.intersection(toolChainPlatformInfo); + } + toolChainInfo.addCommands(toolsDef.getConfigInfo().getCommands()); + toolChainInfo.normalize(); + EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Current build tool chain information summary: "); + EdkLog.log("Init", EdkLog.EDK_ALWAYS, toolChainInfo + ""); + } + return toolChainInfo; + } + + public static void setPlatformToolChainFamilyOption(ToolChainMap map) { + platformToolChainFamilyOption = map; + } + + public static void setPlatformToolChainOption(ToolChainMap map) { + platformToolChainOption = map; + } + + public static void addModuleToolChainOption(FpdModuleIdentification fpdModuleId, + ToolChainMap toolChainOption) { + moduleToolChainOption.put(fpdModuleId, toolChainOption); + } + + public static void addModuleToolChainFamilyOption(FpdModuleIdentification fpdModuleId, + ToolChainMap toolChainOption) { + moduleToolChainFamilyOption.put(fpdModuleId, toolChainOption); + } + + public static boolean isCommandSet(String target, String toolchain, String arch) { + String[] commands = getToolChainInfo().getCommands(); + + for (int i = 0; i < commands.length; ++i) { + String cmdName = toolsDef.getConfig().get(new String[] {target, toolchain, arch, commands[i], ToolChainAttribute.NAME.toString()}); + if (cmdName != null && cmdName.length() != 0) { + return true; + } + } + + return false; + } + + public synchronized static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) throws EdkException { + ToolChainKey toolChainKey = new ToolChainKey(commandDescription); + ToolChainMap toolChainConfig = toolsDef.getConfig(); + String setting = null; + + setting = toolChainConfig.get(toolChainKey); + if (setting == null) { + setting = ""; + } + if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolChainAttribute.FLAGS.toString())) { + return setting; + } + + // + // get module specific options, if any + // + // tool tag first + ToolChainMap option = moduleToolChainOption.get(fpdModuleId); + ToolChainKey toolChainFamilyKey = null; + + if (option != null && option.get(toolChainKey) != null) + { + String str = option.get(toolChainKey); + + Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+"); + Matcher matcher = myPattern.matcher(str + " "); + while (matcher.find()) + { + setting = setting + " " + str.substring(matcher.start(1), matcher.end(1)); + } + } +// else +// { + if (toolChainFamilyKey == null) + { + toolChainFamilyKey = new ToolChainKey(commandDescription); + toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value); + String family = toolChainConfig.get(toolChainFamilyKey); + toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value); + toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value); + } + + option = moduleToolChainFamilyOption.get(fpdModuleId); + if (option != null && option.get(toolChainFamilyKey) != null) + { + String str = option.get(toolChainFamilyKey); + + Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+"); + Matcher matcher = myPattern.matcher(str + " "); + while (matcher.find()) + { + setting = setting + " " + str.substring(matcher.start(1), matcher.end(1)); + } + } +// } + + // + // get platform options, if any + // + // tool tag first +// if (platformToolChainOption != null && platformToolChainOption.get(toolChainKey) != null) + if (platformToolChainOption.get(toolChainKey) != null) + { + String str = platformToolChainOption.get(toolChainKey); + + Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+"); + Matcher matcher = myPattern.matcher(str + " "); + while (matcher.find()) + { + setting = setting + " " + str.substring(matcher.start(1), matcher.end(1)); + } + } +// else +// { + // then tool chain family + if (toolChainFamilyKey == null) + { + toolChainFamilyKey = new ToolChainKey(commandDescription); + toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value); + String family = toolChainConfig.get(toolChainFamilyKey); + toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value); + toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value); + } + +// if (platformToolChainFamilyOption != null && platformToolChainFamilyOption.get(toolChainFamilyKey) != null) + if (platformToolChainFamilyOption.get(toolChainFamilyKey) != null) + { + String str = platformToolChainFamilyOption.get(toolChainFamilyKey); + + setting = setting + " " + str; + +// Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+"); +// Matcher matcher = myPattern.matcher(str + " "); +// while (matcher.find()) +// { +// setting = setting + " " + str.substring(matcher.start(1), matcher.end(1)); +// } + } +// } + + return setting; + +/* + // + // get module specific options, if any + // + // tool tag first + ToolChainMap option = moduleToolChainOption.get(fpdModuleId); + ToolChainKey toolChainFamilyKey = null; + + if ((option == null) || (option != null && (setting = option.get(toolChainKey)) == null)) + { + // + // then tool chain family + // + toolChainFamilyKey = new ToolChainKey(commandDescription); + toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value); + String family = toolChainConfig.get(toolChainFamilyKey); + toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value); + toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value); + + option = moduleToolChainFamilyOption.get(fpdModuleId); + if (option != null) { + setting = option.get(toolChainFamilyKey); + } + } + + // + // get platform options, if any + // + if (setting == null) { + // tool tag first + if (platformToolChainOption == null || (setting = platformToolChainOption.get(toolChainKey)) == null) { + // then tool chain family + if (toolChainFamilyKey == null) { + toolChainFamilyKey = new ToolChainKey(commandDescription); + toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value); + String family = toolChainConfig.get(toolChainFamilyKey); + toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value); + toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value); + } + + setting = platformToolChainFamilyOption.get(toolChainFamilyKey); + } + } + + if (setting == null) { + setting = ""; + } + + return setting; +*/ + } + + public static void setToolChainEnvInfo(ToolChainInfo envInfo) { + toolChainEnvInfo = envInfo; + } + public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) { + toolChainPlatformInfo = platformInfo; + } + + // + // for PCD + // + public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() { + return pcdDbManager; + } + + // + // For PCD get tokenSpaceGUid + // + public synchronized static String getGuidInfoFromCname(String cName){ + String cNameGuid = null; + String guid = null; + Set set = spdTable.keySet(); + Iterator iter = set.iterator(); + + if (iter == null) { + return null; + } + + while (iter.hasNext()){ + Spd spd = (Spd) spdTable.get(iter.next()); + guid = spd.getGuidFromCname(cName); + if (guid != null){ + cNameGuid = guid; + break; + } + } + return cNameGuid; + } + + // + // For PCD + // + public synchronized static Map + getFpdModuleSaXmlObject(String xmlObjectName) { + Set fpdModuleSASet = fpdModuleSA.keySet(); + Iterator item = fpdModuleSASet.iterator(); + + + Map SAPcdBuildDef = new HashMap(); + Map SANode = new HashMap(); + FpdModuleIdentification moduleId; + while (item.hasNext()) { + + moduleId = (FpdModuleIdentification) item.next(); + SANode = fpdModuleSA.get(moduleId); + try{ + if (SANode.get(xmlObjectName)!= null){ + SAPcdBuildDef.put(moduleId, + (XmlObject) SANode.get(xmlObjectName)); + + } + } catch (Exception e){ + EdkLog.log(EdkLog.EDK_INFO, e.getMessage()); + } + } + return SAPcdBuildDef; + } + + public synchronized static Map getFpdPcdBuildDefinitions() { + Map pcdBuildDef = getFpdModuleSaXmlObject ("PcdBuildDefinition"); + + return pcdBuildDef; + } +} + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/global/OnDependency.java b/Tools/Java/Source/GenBuild/org/tianocore/build/global/OnDependency.java new file mode 100644 index 0000000000..678bfb869b --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/global/OnDependency.java @@ -0,0 +1,145 @@ +/** @file +This file is to define OnDependency class. + +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.global; + +import java.io.File; +import java.util.Iterator; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.Sequential; +import org.tianocore.common.logger.EdkLog; +import org.tianocore.common.cache.FileTimeStamp; + +/** + Class OnDepdendency is used to check the timestamp between source files and + target files, which can be used to determine if the target files are needed to + be re-generated from source files. + **/ +public class OnDependency extends Task { + // + // source files list + // + private DpFileList sources = null; + + // + // target files list + // + private DpFileList targets = null; + + // + // tasks to be performed to generate target files + // + private Sequential task = null; + + /** + An empty constructor for an ANT task can avoid some potential issues + **/ + public OnDependency(){ + } + + /** + Standard execute method of ANT task + **/ + public void execute() throws BuildException { + if (isOutOfDate() && task != null) { + task.perform(); + } + + // + // Update the time stamp of target files since they are just re-generated + // + for (Iterator dstIt = targets.nameList.iterator(); dstIt.hasNext();) { + FileTimeStamp.update((String)dstIt.next()); + } + } + + // + // check if the target files are outofdate + // + private boolean isOutOfDate() { + /// + /// if no source files specified, take it as a fresh start + /// + if (sources.nameList.size() == 0) { + EdkLog.log(this, EdkLog.EDK_VERBOSE, "No source file spcified!"); + return true; + } + + if (targets.nameList.size() == 0) { + EdkLog.log(this, EdkLog.EDK_VERBOSE, "No target file found!"); + return true; + } + + Iterator dstIt = targets.nameList.iterator(); + while (dstIt.hasNext()) { + String dstFileName = (String)dstIt.next(); + File dstFile = new File(dstFileName); + if (!dstFile.exists()) { + EdkLog.log(this, EdkLog.EDK_VERBOSE, "Target file [" + dstFileName + "] doesn't exist!"); + return true; + } + + long dstTimeStamp = FileTimeStamp.get(dstFileName); + Iterator srcIt = sources.nameList.iterator(); + while (srcIt.hasNext()) { + String srcFileName = (String)srcIt.next(); + long srcTimeStamp = FileTimeStamp.get(srcFileName); + + if (srcTimeStamp == 0) { + // + // time stamp 0 means that the file doesn't exist + // + throw new BuildException("Source File name: " + srcFileName + " doesn't exist!!!"); + } + + if (dstTimeStamp < srcTimeStamp) { + EdkLog.log(this, EdkLog.EDK_VERBOSE, "Source file [" + srcFileName + "] has been changed since last build!"); + return true; + } + } + } + + EdkLog.log(this, EdkLog.EDK_VERBOSE, "Target files are up-to-date!"); + return false; + } + + /** + Add method of ANT task for nested element with Sequential type + + @param task Sequential object which contains tasks for generating target files + **/ + public void addSequential(Sequential task) { + this.task = task; + } + + /** + Add method of ANT task for nested element with DpFileList type + + @param sources DpFileList object which contains the list of source files + **/ + public void addSourcefiles(DpFileList sources) { + this.sources = sources; + } + + /** + Add method of ANT task for nested element with DpFileList type + + @param targets DpFileList object which contains the list of target files + **/ + public void addTargetfiles(DpFileList targets) { + this.targets = targets; + } +} + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/global/OutputManager.java b/Tools/Java/Source/GenBuild/org/tianocore/build/global/OutputManager.java new file mode 100644 index 0000000000..2c70326202 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/global/OutputManager.java @@ -0,0 +1,201 @@ +/** @file + OutputManager class. + + OutputManager class set output directories for every module by BUILD_MODE. + +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.global; + +import org.apache.tools.ant.Project; +import java.io.File; + +/** + OutputManager class is used to setup output directories (BIN_DIR, DEST_DIR_OUTPUT, + DEST_DIR_DEBUG). + + @since GenBuild 1.0 +**/ +public class OutputManager { + + /// + /// means intermediate files will put under Module's dir + /// + private String MODULE = "MODULE"; + + /// + /// mean intermediate files will put under a unify dir + /// + private String UNIFIED = "UNIFIED"; + + + private String userdir; + + private String type; + /// + /// Singleton Design Pattern + /// + private static OutputManager object; + + public synchronized static OutputManager getInstance() { + if ( object == null ) { + object = new OutputManager(); + } + return object; + } + + public void setup(String userdir, String type) { + this.userdir = userdir; + this.type = type; + } + + /** + Setup BIN_DIR, DEST_DIR_OUTPUT and DEST_DIR_OUTPUT, following are the rules: + +

Divide all output files into two types: one is final files, such as FFS + file for driver module while LIB file for library module; another is + intermediate files, such AutoGen.c, OBJ files, Section files and so on. + +

In FPD, OutputDirectory element is used to specify where to put the output + files to. There are two mode (MODULE | UNIFIED). MODULE mode means that all + output files will put to the module directory while UNIFIED mode means that + all output files will put together. Default is UNIFIED mode. + +

BUILD_DIR is the base directory for current module build. By default, + BUILD_DIR is PLATFORM_DIR/Build in UNIFIED mode while is MODULE_DIR/Build + in MODULE mode. Of course, user can customize BUILD_DIR. If user-defined + BUILD_DIR is relative path, then look as related to WORKSPACE_DIR. + +

Then, BIN_DIR is BUILD_DIR/TARGET/TOOLCHAIN/ARCH; + +

FV_DIR is BUILD_DIR/TARGET/TOOLCHAIN/FV; + +

DEST_DIR_DEBUG | DEST_DIR_OUTPUT is: + BIN_DIR/PACKAGE_RELATIVE_DIR/MODULE_RELATIVE_DIR/DEBUG | OUTPUT + + + @param project current ANT build Project + @param userdir user-defined directory + @param type the module build type (MODULE or UNIFIED) + **/ + public void update(Project project) { + // + // Default mode is UNIFIED. + // + if (type != null && type.equalsIgnoreCase(MODULE)) { + type = MODULE; + } + else { + type = UNIFIED; + } + + // + // default BUILD_DIR value + // + String buildDir; + if(type.equals(MODULE)){ + buildDir = project.getProperty("MODULE_DIR") + File.separatorChar + "Build"; + } + else { + buildDir = project.getProperty("PLATFORM_DIR") + File.separatorChar + "Build"; + } + + // + // If user define BUILD_DIR + // + if (userdir != null && ! userdir.equals("")) { + File buildFile = new File(userdir); + if (buildFile.isAbsolute()){ + buildDir = userdir; + } + // + // If path is not absolute, then look as related to WORKSPACE_DIR + // + else { + buildDir = GlobalData.getWorkspacePath() + File.separatorChar + userdir; + } + } + + // + // Define TARGET_DIR + // + String targetDir = buildDir + File.separatorChar + project.getProperty("TARGET") + + "_" + project.getProperty("TOOLCHAIN"); + + // + // Define BIN_DIR and FV_DIR + // + String binDir = targetDir + File.separatorChar + project.getProperty("ARCH") ; + + String fvDir = targetDir + File.separatorChar + "FV"; + + // + // Define DEST_DIR_OUTPUT and DEST_DIR_DEBUG + // + String destDir = binDir + File.separatorChar + project.getProperty("PACKAGE_RELATIVE_DIR") + + File.separatorChar + project.getProperty("MODULE_RELATIVE_DIR"); + + // + // Set properties + // + project.setProperty("BUILD_DIR", buildDir.replaceAll("(\\\\)", "/")); + project.setProperty("TARGET_DIR", targetDir.replaceAll("(\\\\)", "/")); + project.setProperty("FV_DIR", fvDir.replaceAll("(\\\\)", "/")); + project.setProperty("BIN_DIR", binDir.replaceAll("(\\\\)", "/")); + project.setProperty("DEST_DIR_DEBUG", (destDir + File.separatorChar + "DEBUG").replaceAll("(\\\\)", "/")); + project.setProperty("DEST_DIR_OUTPUT", (destDir + File.separatorChar + "OUTPUT").replaceAll("(\\\\)", "/")); + + // + // Create all directory if necessary + // + (new File(buildDir)).mkdirs(); + (new File(fvDir)).mkdirs(); + (new File(binDir)).mkdirs(); + (new File(destDir + File.separatorChar + "DEBUG")).mkdirs(); + (new File(destDir + File.separatorChar + "OUTPUT")).mkdirs(); + } + + public boolean prepareBuildDir(Project project){ + boolean isUnified = true; + + if (type.equalsIgnoreCase("MODULE")) { + isUnified = false; + } + + String buildDir = project.getProperty("PLATFORM_DIR") + File.separatorChar + "Build"; + // + // If user define BUILD_DIR + // + if (userdir != null && ! userdir.equals("")) { + File buildFile = new File(userdir); + if (buildFile.isAbsolute()){ + buildDir = userdir; + } + // + // If path is not absolute, then look as related to WORKSPACE_DIR + // + else { + buildDir = GlobalData.getWorkspacePath() + File.separatorChar + userdir; + } + } + + // + // Set to property + // + project.setProperty("BUILD_DIR", buildDir.replaceAll("(\\\\)", "/")); + + // + // Create all directory if necessary + // + (new File(buildDir)).mkdirs(); + return isUnified; + } + +} \ No newline at end of file diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/global/PropertyManager.java b/Tools/Java/Source/GenBuild/org/tianocore/build/global/PropertyManager.java new file mode 100644 index 0000000000..1bd7cf97da --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/global/PropertyManager.java @@ -0,0 +1,196 @@ +/** @file + PropertyManager class. + + PropertyManager class wraps Project.setProperty and tracks overrided properties. + +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.global; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Set; +import java.util.Stack; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.PropertyHelper; + +/** + PropertyManager uses a incremental way to to track overrided properties when + setProperty. This is useful for property recovery in nestly calling build files. + Another functionality of this class is to prevent warning message printed when + building with "verbose" mode. + **/ +public class PropertyManager { + // + // Property table stack, keeps track the history of properties changes + // + private static Stack> propertyTableStack = new Stack>(); + // + // The very original properties + // + private static HashMap orgPropertyTable = null; + // + // The last changes of properties + // + private static HashMap oldPropertyTable = null; + // + // The current changes of properties + // + private static HashMap bakPropertyTable = null; + // + // The Project of tracking properties + // + private static Project prj = null; + // + // PropertyHelper of this project for setting property quietly + // + private static PropertyHelper ph = null; + + /** + Backup properties that have been overrided onto the stack for later recovery. + **/ + public static void save() { + // + // If this is the first time to save properties changes, keep all properties + // of this project as the original property table. + // + if (orgPropertyTable == null) { + Hashtable prjProperties = prj.getProperties(); + orgPropertyTable = new HashMap(); + + Set keys = prjProperties.keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()) { + String item = (String)iter.next(); + orgPropertyTable.put(item, (String)prjProperties.get(item)); + } + } + + // + // If there're already overrided properties, push it onto stack; otherwise + // prepare taking new overrided property by allocating space for it. + // + if (bakPropertyTable != null) { + propertyTableStack.push(bakPropertyTable); + oldPropertyTable = bakPropertyTable; + } else { + oldPropertyTable = orgPropertyTable; + } + bakPropertyTable = new HashMap(); + } + + /** + Restore the properties backup + **/ + public static void restore() { + if (bakPropertyTable == null) { + // + // No properties backup, do nothing + // + return; + } + Set keys = bakPropertyTable.keySet(); + + // + // Re-set properties in backup + // + Iterator iter = keys.iterator(); + while (iter.hasNext()) { + String name = (String)iter.next(); + String value = (String)bakPropertyTable.get(name); + ph.setProperty(null, name, value, false); + } + + // + // If there's backup history, get top one for next recovery + // + if (propertyTableStack.size() > 0) { + bakPropertyTable = (HashMap)propertyTableStack.pop(); + } else { + bakPropertyTable = null; // no recovery any more + } + + // + // Determine last overrided properties for incremental judgement + // + if (propertyTableStack.size() == 0) { + oldPropertyTable = orgPropertyTable; + } else { + oldPropertyTable = (HashMap)propertyTableStack.peek(); + } + } + + /** + Set current Project for save() and restore() use. + + @param prj + **/ + public static void setProject(Project prj) { + PropertyManager.prj = prj; + PropertyManager.ph = PropertyHelper.getPropertyHelper(prj); + } + + /** + Set a property for current project. It will also be put into property + history record if the record table has been setup. + + @param name Property name + @param value Property value + **/ + public static void setProperty(String name, String value) { + if (prj == null) { + return; + } + + setProperty(prj, name, value); + } + + /** + Set a property for current project. It will also be put into property + history record if the record table has been setup. + + @param project The Project for which the property will be set + @param name Property name + @param value Property value + **/ + public static void setProperty(Project project, String name, String value) { + if (project == null) { + if (prj == null) { + return; // a Project must be given; otherwise nothing can be set + } + project = prj; + } + + // + // Using PropertyHelper to set a property can be quiet (no override + // warning preset). + // + PropertyHelper.getPropertyHelper(project).setProperty(null, name, value, false); + + // + // If no property override history record is found, do nothing further + // + if (oldPropertyTable == null || bakPropertyTable == null) { + return; + } + + // + // Put a copy of given property in history record. + // + String oldValue = oldPropertyTable.get(name); + if (oldValue == null) { + oldValue = value; + } + bakPropertyTable.put(name, oldValue); + } +} + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/global/Spd.java b/Tools/Java/Source/GenBuild/org/tianocore/build/global/Spd.java new file mode 100644 index 0000000000..965e8ef499 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/global/Spd.java @@ -0,0 +1,279 @@ +/** @file + Spd class. + + This class is to generate a global table for the content of spd file. + + 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.global; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.tianocore.build.id.ModuleIdentification; +import org.tianocore.build.id.PackageIdentification; +import org.tianocore.common.exception.EdkException; + +/** + + This class is to generate a global table for the content of spd file. + +**/ +public class Spd { + /// + /// + /// + Map msaInfo = new HashMap(); + + /// + /// Map of module info. + /// Key : moduletype + /// Value: moduletype related include file + /// + Map packageHeaderInfo = new HashMap(); + + /// + /// Map of PPI info. + /// Key : PPI name + /// value: String[] a. PPI C_NAME; b. PPI GUID; + /// + Map ppiInfo = new HashMap(); + + /// + /// Map of Protocol info. + /// Key : Protocol name + /// value: String[] a. Protocol C_NAME; b. Protocol GUID; + /// + Map protocolInfo = new HashMap(); + + /// + /// Map of Guid info. + /// Key : Guid name + /// value: String[] a. Guid C_NAME; b. Guid's GUID; + /// + Map guidInfo = new HashMap(); + + /// + /// Map of Guid info + /// Key: GuidCName + /// value: String Guid's GUID + /// + Map guidCnameInfo = new HashMap(); + + /// Map of library class and its exposed header file. + /// Key : library class name + /// value : library class corresponding header file + /// + Map libClassHeaderList = new HashMap(); + + /// + /// Package path. + /// + PackageIdentification packageId; + + /** + Constructor function + + This function mainly initialize some member variables. + **/ + Spd(File packageFile) throws EdkException { + // + // If specified package file not exists + // + if ( ! packageFile.exists()) { + throw new EdkException("Package file [" + packageFile.getPath() + "] does not exist!"); + } + try { + XmlObject spdDoc = XmlObject.Factory.parse(packageFile); + // + // Verify SPD file, if is invalid, throw Exception + // + if (! spdDoc.validate()) { + throw new EdkException("Package Surface Area file [" + packageFile.getPath() + "] format is invalid!"); + } + // + // We can change Map to XmlObject + // + Map spdDocMap = new HashMap(); + spdDocMap.put("PackageSurfaceArea", spdDoc); + SurfaceAreaQuery saq = new SurfaceAreaQuery(spdDocMap); + + packageId = saq.getSpdHeader(); + packageId.setSpdFile(packageFile); + + // + // initialize Msa Files + // MSA file is absolute file path + // + String[] msaFilenames = saq.getSpdMsaFile(); + for (int i = 0; i < msaFilenames.length; i++){ + File msaFile = new File(packageId.getPackageDir() + File.separatorChar + msaFilenames[i]); + Map msaDoc = GlobalData.getNativeMsa( msaFile ); + saq.push(msaDoc); + ModuleIdentification moduleId = saq.getMsaHeader(); + saq.pop(); + moduleId.setPackage(packageId); + moduleId.setMsaFile(msaFile); + if (msaInfo.containsKey(moduleId)) { + throw new EdkException("Found two modules with the same GUID and Version in package " + packageId + ".\nThey are module [" + msaInfo.get(moduleId) + "] and MSA file [" + msaFile + "]!"); + } + msaInfo.put(moduleId, msaFile); + } + + // + // initialize Package header files + // + Map packageHeaders = saq.getSpdPackageHeaderFiles(); + Set keys = packageHeaders.keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()){ + String moduleType = (String)iter.next(); + String header = packageId.getPackageRelativeDir() + File.separatorChar + packageHeaders.get(moduleType); + + // + // Change path seperator to system-dependent path separator + // + File file = new File (header); + header = file.getPath(); + packageHeaderInfo.put(moduleType, header); + } + + // + // initialize Guid Info + // + guidInfo.putAll(saq.getSpdGuid()); + + // + // For Pcd get TokenSpaceGuid + // + Set key = guidInfo.keySet(); + Iterator item = key.iterator(); + String [] nameValue = new String[2]; + while(item.hasNext()){ + nameValue = guidInfo.get(item.next()); + guidCnameInfo.put(nameValue[0], nameValue[1]); + } + + // + // initialize PPI info + // + ppiInfo.putAll(saq.getSpdPpi()); + + // + // initialize Protocol info + // + protocolInfo.putAll(saq.getSpdProtocol()); + + // + // initialize library class declaration + // + Map libraryClassHeaders = saq.getSpdLibraryClasses(); + keys = libraryClassHeaders.keySet(); + iter = keys.iterator(); + while (iter.hasNext()){ + String libraryClassName = (String)iter.next(); + String[] headerFiles = libraryClassHeaders.get(libraryClassName); + for (int i = 0; i < headerFiles.length; i++){ + headerFiles[i] = packageId.getPackageRelativeDir() + File.separatorChar + headerFiles[i]; + + // + // Change path separator to system system-dependent path separator. + // + File file = new File (headerFiles[i]); + headerFiles[i] = file.getPath(); + } + libClassHeaderList.put(libraryClassName, headerFiles); + } + } catch (IOException ex) { + EdkException edkException = new EdkException("Parse of the package description file [" + packageFile.getPath() + "] failed!\n" + ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; + } catch (XmlException ex) { + EdkException edkException = new EdkException("Parse of the package description file [" + packageFile.getPath() + "] failed!\n" + ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; + } + } + + public PackageIdentification getPackageId() { + return packageId; + } + + public File getModuleFile(ModuleIdentification moduleId) { + return msaInfo.get(moduleId); + } + + public Set getModules(){ + return msaInfo.keySet(); + } + + /** + return two value {CName, Guid}. If not found, return null. + **/ + public String[] getPpi(String ppiName) { + return ppiInfo.get(ppiName); + } + + /** + return two value {CName, Guid}. If not found, return null. + **/ + public String[] getProtocol(String protocolName) { + return protocolInfo.get(protocolName); + } + + /** + return two value {CName, Guid}. If not found, return null. + **/ + public String[] getGuid(String guidName) { + return guidInfo.get(guidName); + } + + /** + * return Guid Value. + */ + public String getGuidFromCname(String cName){ + return guidCnameInfo.get(cName); + } + + /** + getLibClassInclude + + This function is to get the library exposed header file name according + library class name. + + @param libName Name of library class + @return Name of header file + **/ + String[] getLibClassIncluder(String libName) { + return libClassHeaderList.get(libName); + } + + /** + getModuleTypeIncluder + + This function is to get the header file name from module info map + according to module type. + + @param moduleType Module type. + @return Name of header file. + **/ + String getPackageIncluder(String moduleType) { + return packageHeaderInfo.get(moduleType); + } + + +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java b/Tools/Java/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java new file mode 100644 index 0000000000..0140e8b704 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java @@ -0,0 +1,2007 @@ +/** @file + This file is for surface area information retrieval. + + 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.global; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.tianocore.ExternsDocument.Externs.Extern; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlString; +import org.tianocore.*; +import org.tianocore.FilenameDocument.Filename; +import org.tianocore.MsaHeaderDocument.MsaHeader; +import org.tianocore.ProtocolsDocument.Protocols.Protocol; +import org.tianocore.ProtocolsDocument.Protocols.ProtocolNotify; +import org.tianocore.build.autogen.CommonDefinition; +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.toolchain.ToolChainInfo; +import org.tianocore.common.exception.EdkException; +import org.tianocore.common.logger.EdkLog; +import org.w3c.dom.Node; + +/** + * SurfaceAreaQuery class is used to query Surface Area information from msa, + * mbd, spd and fpd files. + * + * This class should not instantiated. All the public interfaces is static. + * + * @since GenBuild 1.0 + */ +public class SurfaceAreaQuery { + + public String prefix = "http://www.TianoCore.org/2006/Edk2.0"; + + // + // Contains name/value pairs of Surface Area document object. The name is + // always the top level element name. + // + private Map map = null; + + // + // mapStack is used to do nested query + // + private Stack> mapStack = new Stack>(); + + // + // prefix of name space + // + private String nsPrefix = "sans"; + + // + // xmlbeans needs a name space for each Xpath element + // + private String ns = null; + + // + // keep the namep declaration for xmlbeans Xpath query + // + private String queryDeclaration = null; + + private StringBuffer normQueryString = new StringBuffer(4096); + private Pattern xPathPattern = Pattern.compile("([^/]*)(/|//)([^/]+)"); + + /** + * Set a Surface Area document for query later + * + * @param map + * A Surface Area document in TopLevelElementName/XmlObject + * format. + */ + public SurfaceAreaQuery(Map map) { + ns = prefix; + queryDeclaration = "declare namespace " + nsPrefix + "='" + ns + "'; "; + this.map = map; + } + + /** + * Push current used Surface Area document into query stack. The given new + * document will be used for any immediately followed getXXX() callings, + * untill pop() is called. + * + * @param newMap + * The TopLevelElementName/XmlObject format of a Surface Area + * document. + */ + public void push(Map newMap) { + mapStack.push(this.map); + this.map = newMap; + } + + /** + * Discard current used Surface Area document and use the top document in + * stack instead. + */ + public void pop() { + this.map = mapStack.pop(); + } + + // / + // / Convert xPath to be namespace qualified, which is necessary for + // XmlBeans + // / selectPath(). For example, converting /MsaHeader/ModuleType to + // / /ns:MsaHeader/ns:ModuleType + // / + private String normalizeQueryString(String[] exp, String from) { + normQueryString.setLength(0); + + int i = 0; + while (i < exp.length) { + String newExp = from + exp[i]; + Matcher matcher = xPathPattern.matcher(newExp); + + while (matcher.find()) { + String starter = newExp.substring(matcher.start(1), matcher + .end(1)); + String seperator = newExp.substring(matcher.start(2), matcher + .end(2)); + String token = newExp.substring(matcher.start(3), matcher + .end(3)); + + normQueryString.append(starter); + normQueryString.append(seperator); + normQueryString.append(nsPrefix); + normQueryString.append(":"); + normQueryString.append(token); + } + + ++i; + if (i < exp.length) { + normQueryString.append(" | "); + } + } + + return normQueryString.toString(); + } + + /** + * Search all XML documents stored in "map" for the specified xPath, using + * relative path (starting with '$this') + * + * @param xPath + * xpath query string array + * @returns An array of XmlObject if elements are found at the specified + * xpath + * @returns NULL if nothing is at the specified xpath + */ + public Object[] get(String[] xPath) { + if (map == null) { + return null; + } + + String[] keys = (String[]) map.keySet().toArray(new String[map.size()]); + List result = new ArrayList(); + for (int i = 0; i < keys.length; ++i) { + XmlObject rootNode = (XmlObject) map.get(keys[i]); + if (rootNode == null) { + continue; + } + + String query = queryDeclaration + + normalizeQueryString(xPath, "$this/" + keys[i]); + XmlObject[] tmp = rootNode.selectPath(query); + for (int j = 0; j < tmp.length; ++j) { + result.add((Object)tmp[j]); + } + } + + int size = result.size(); + if (size <= 0) { + return null; + } + + return (Object[]) result.toArray(new Object[size]); + } + + /** + * Search XML documents named by "rootName" for the given xPath, using + * relative path (starting with '$this') + * + * @param rootName + * The top level element name + * @param xPath + * The xpath query string array + * @returns An array of XmlObject if elements are found at the given xpath + * @returns NULL if nothing is found at the given xpath + */ + public Object[] get(String rootName, String[] xPath) { + if (map == null) { + return null; + } + + XmlObject root = (XmlObject) map.get(rootName); + if (root == null) { + return null; + } + + String query = queryDeclaration + + normalizeQueryString(xPath, "$this/" + rootName); + XmlObject[] result = root.selectPath(query); + if (result.length > 0) { + return (Object[])result; + } + + query = queryDeclaration + normalizeQueryString(xPath, "/" + rootName); + result = root.selectPath(query); + if (result.length > 0) { + return (Object[])result; + } + + return null; + } + + /** + * Retrieve SourceFiles/Filename for specified ARCH type + * + * @param arch + * architecture name + * @returns An 2 dimension string array if elements are found at the known + * xpath + * @returns NULL if nothing is found at the known xpath + */ + public String[][] getSourceFiles(String arch) { + String[] xPath; + Object[] returns; + + xPath = new String[] { "/Filename" }; + + returns = get("SourceFiles", xPath); + + if (returns == null || returns.length == 0) { + return new String[0][0]; + } + + Filename[] sourceFileNames = (Filename[]) returns; + List outputList = new ArrayList(); + for (int i = 0; i < sourceFileNames.length; i++) { + List archList = sourceFileNames[i].getSupArchList(); + if (arch == null || arch.equalsIgnoreCase("") || archList == null || contains(archList, arch)) { + outputList.add(new String[] {sourceFileNames[i].getToolCode(),sourceFileNames[i].getStringValue()}); + } + } + + String[][] outputString = new String[outputList.size()][2]; + for (int index = 0; index < outputList.size(); index++) { + outputString[index][0] = outputList.get(index)[0]; + outputString[index][1] = outputList.get(index)[1]; + } + return outputString; + } + + /** + * Retrieve /PlatformDefinitions/OutputDirectory from FPD + * + * @returns Directory names array if elements are found at the known xpath + * @returns Empty if nothing is found at the known xpath + */ + public String getFpdOutputDirectory() { + String[] xPath = new String[] { "/PlatformDefinitions" }; + + Object[] returns = get("PlatformSurfaceArea", xPath); + if (returns == null || returns.length == 0) { + return null; + } + PlatformDefinitionsDocument.PlatformDefinitions item = (PlatformDefinitionsDocument.PlatformDefinitions)returns[0]; + return item.getOutputDirectory(); + } + + public String getFpdIntermediateDirectories() { + String[] xPath = new String[] { "/PlatformDefinitions" }; + + Object[] returns = get("PlatformSurfaceArea", xPath); + if (returns == null || returns.length == 0) { + return "UNIFIED"; + } + PlatformDefinitionsDocument.PlatformDefinitions item = (PlatformDefinitionsDocument.PlatformDefinitions)returns[0]; + if(item.getIntermediateDirectories() == null) { + return null; + } + else { + return item.getIntermediateDirectories().toString(); + } + } + + public String getModuleFfsKeyword() { + String[] xPath = new String[] { "/" }; + + Object[] returns = get("ModuleSaBuildOptions", xPath); + if (returns == null || returns.length == 0) { + return null; + } + ModuleSaBuildOptionsDocument.ModuleSaBuildOptions item = (ModuleSaBuildOptionsDocument.ModuleSaBuildOptions)returns[0]; + return item.getFfsFormatKey(); + } + + public String getModuleFvBindingKeyword() { + String[] xPath = new String[] { "/" }; + + Object[] returns = get("ModuleSaBuildOptions", xPath); + if (returns == null || returns.length == 0) { + return null; + } + ModuleSaBuildOptionsDocument.ModuleSaBuildOptions item = (ModuleSaBuildOptionsDocument.ModuleSaBuildOptions)returns[0]; + return item.getFvBinding(); + } + + public List getModuleSupportedArchs() { + String[] xPath = new String[] { "/" }; + + Object[] returns = get("ModuleDefinitions", xPath); + if (returns == null || returns.length == 0) { + return null; + } + ModuleDefinitionsDocument.ModuleDefinitions item = (ModuleDefinitionsDocument.ModuleDefinitions)returns[0]; + return item.getSupportedArchitectures(); + } + + public BuildOptionsDocument.BuildOptions.Ffs[] getFpdFfs() { + String[] xPath = new String[] {"/Ffs"}; + + Object[] returns = get("BuildOptions", xPath); + if (returns == null || returns.length == 0) { + return new BuildOptionsDocument.BuildOptions.Ffs[0]; + } + return (BuildOptionsDocument.BuildOptions.Ffs[])returns; + } + + public String getModuleOutputFileBasename() { + String[] xPath = new String[] { "/" }; + + Object[] returns = get("ModuleDefinitions", xPath); + if (returns == null || returns.length == 0) { + return null; + } + ModuleDefinitionsDocument.ModuleDefinitions item = (ModuleDefinitionsDocument.ModuleDefinitions)returns[0]; + return item.getOutputFileBasename(); + } + + /** + * Retrieve BuildOptions/Option or Arch/Option + * + * @param toolChainFamilyFlag + * if true, retrieve options for toolchain family; otherwise for + * toolchain + * + * @returns String[][5] name, target, toolchain, arch, coommand of options + * if elements are found at the known xpath. String[0][] if dont + * find element. + * + * @returns Empty array if nothing is there + */ + public String[][] getOptions(String from, String[] xPath, boolean toolChainFamilyFlag) { + String target = null; + String toolchain = null; + String toolchainFamily = null; + List archList = null; + String cmd = null; + String optionName = null; + + Object[] returns = get(from, xPath); + if (returns == null) { + return new String[0][5]; + } + + List optionList = new ArrayList(); + OptionDocument.Option option; + + for (int i = 0; i < returns.length; i++) { + option = (OptionDocument.Option) returns[i]; + + // + // Get Target, ToolChain(Family), Arch, Cmd, and Option from Option, + // then + // put to result[][5] array in above order. + // + String[] targetList; + if (option.getBuildTargets() == null) { + target = null; + } + else { + target = option.getBuildTargets().toString(); + } + if (target != null) { + targetList = target.split(" "); + } else { + targetList = new String[1]; + targetList[0] = null; + } + + if (toolChainFamilyFlag) { + toolchainFamily = option.getToolChainFamily(); + if (toolchainFamily != null) { + toolchain = toolchainFamily.toString(); + } else { + toolchain = null; + } + } else { + toolchain = option.getTagName(); + } + + archList = new ArrayList(); + List archEnumList = option.getSupArchList(); + if (archEnumList == null) { + archList.add(null); + } else { + //archList.addAll(archEnumList); + Iterator it = archEnumList.iterator(); + while (it.hasNext()) { + String archType = (String)it.next(); + archList.add(archType); + } + } + + cmd = option.getToolCode(); + + optionName = option.getStringValue(); + for (int t = 0; t < targetList.length; t++) { + for (int j = 0; j < archList.size(); j++) { + optionList.add(new String[] { targetList[t], + toolchain, archList.get(j), cmd, optionName}); + } + } + } + + String[][] result = new String[optionList.size()][5]; + for (int i = 0; i < optionList.size(); i++) { + result[i][0] = optionList.get(i)[0]; + result[i][1] = optionList.get(i)[1]; + result[i][2] = optionList.get(i)[2]; + result[i][3] = optionList.get(i)[3]; + result[i][4] = optionList.get(i)[4]; + } + return result; + } + + public String[][] getModuleBuildOptions(boolean toolChainFamilyFlag) { + String[] xPath; + + if (toolChainFamilyFlag == true) { + xPath = new String[] { + "/Options/Option[not(@ToolChainFamily) and not(@TagName)]", + "/Options/Option[@ToolChainFamily]", }; + } else { + xPath = new String[] { + "/Options/Option[not(@ToolChainFamily) and not(@TagName)]", + "/Options/Option[@TagName]", }; + } + return getOptions("ModuleSaBuildOptions", xPath, toolChainFamilyFlag); + } + + public String[][] getPlatformBuildOptions(boolean toolChainFamilyFlag) { + String[] xPath; + + if (toolChainFamilyFlag == true) { + xPath = new String[] { + "/BuildOptions/Options/Option[not(@ToolChainFamily) and not(@TagName)]", + "/BuildOptions/Options/Option[@ToolChainFamily]", }; + } else { + xPath = new String[] { + "/BuildOptions/Options/Option[not(@ToolChainFamily) and not(@TagName)]", + "/BuildOptions/Options/Option[@TagName]", }; + } + + return getOptions("PlatformSurfaceArea", xPath, toolChainFamilyFlag); + } + + public ToolChainInfo getFpdToolChainInfo() { + String[] xPath = new String[] { "/PlatformDefinitions" }; + + Object[] returns = get("PlatformSurfaceArea", xPath); + if (returns == null || returns.length == 0) { + return null; + } + + PlatformDefinitionsDocument.PlatformDefinitions item = (PlatformDefinitionsDocument.PlatformDefinitions)returns[0]; + ToolChainInfo toolChainInfo = new ToolChainInfo(); + toolChainInfo.addTargets(item.getBuildTargets().toString()); + toolChainInfo.addArchs(item.getSupportedArchitectures().toString()); + toolChainInfo.addTagnames((String)null); + return toolChainInfo; + } + + /** + * Retrieve /ModuleType + * + * @returns The module type name if elements are found at the known xpath + * @returns null if nothing is there + */ + public String getModuleType() { + String[] xPath = new String[] { "/ModuleType" }; + + Object[] returns = get(xPath); + if (returns != null && returns.length > 0) { + ModuleTypeDef type = (ModuleTypeDef) returns[0]; + return type.enumValue().toString(); + } + + return null; + } + + /** + * Retrieve PackageDependencies/Package + * + * @param arch + * Architecture name + * + * @returns package name list if elements are found at the known xpath + * @returns null if nothing is there + */ + public PackageIdentification[] getDependencePkg(String arch) throws EdkException { + String[] xPath; + String packageGuid = null; + String packageVersion = null; + + + xPath = new String[] { "/Package" }; + + Object[] returns = get("PackageDependencies", xPath); + if (returns == null) { + return new PackageIdentification[0]; + } + + // + // Get packageIdentification + // + List packageIdList = new ArrayList(); + for (int i = 0; i < returns.length; i++) { + PackageDependenciesDocument.PackageDependencies.Package item = (PackageDependenciesDocument.PackageDependencies.Package) returns[i]; + List archList = item.getSupArchList(); + if (arch == null || archList == null || contains(archList, arch)) { + packageGuid = item.getPackageGuid(); + packageVersion = item.getPackageVersion(); + PackageIdentification pkgId = new PackageIdentification(null, packageGuid, packageVersion); + GlobalData.refreshPackageIdentification(pkgId); + packageIdList.add(pkgId); + } + } + + return packageIdList.toArray(new PackageIdentification[packageIdList.size()]); + } + + /** + * Retrieve LibraryClassDefinitions/LibraryClass for specified usage + * + * @param usage + * Library class usage + * + * @returns LibraryClass objects list if elements are found at the known + * xpath + * @returns null if nothing is there + */ + public String[] getLibraryClasses(String usage, String arch) { + String[] xPath; + if (usage == null || usage.equals("")) { + xPath = new String[] { "/LibraryClass" }; + } else { + xPath = new String[] { "/LibraryClass[@Usage='" + usage + "']" }; + } + + Object[] returns = get("LibraryClassDefinitions", xPath); + if (returns == null || returns.length == 0) { + return new String[0]; + } + + LibraryClassDocument.LibraryClass[] libraryClassList = (LibraryClassDocument.LibraryClass[]) returns; + List libraryClassName = new ArrayList(); + for (int i = 0; i < libraryClassList.length; i++) { + List archList = libraryClassList[i].getSupArchList(); + + if (arch == null || contains(archList, arch)) { + libraryClassName.add(libraryClassList[i].getKeyword()); + } + } + + String[] libraryArray = new String[libraryClassName.size()]; + libraryClassName.toArray(libraryArray); + return libraryArray; + } + + /** + * Retrieve ModuleEntryPoint names + * + * @returns ModuleEntryPoint name list if elements are found at the known + * xpath + * @returns null if nothing is there + */ + public String[] getModuleEntryPointArray() { + String[] xPath = new String[] { "/Extern/ModuleEntryPoint" }; + + Object[] returns = get("Externs", xPath); + + if (returns != null && returns.length > 0) { + String[] entryPoints = new String[returns.length]; + + for (int i = 0; i < returns.length; ++i) { + entryPoints[i] = ((CNameType) returns[i]).getStringValue(); + } + + return entryPoints; + } + + return null; + } + + /** + * retrieve Protocol for specified usage + * + * @param usage + * Protocol usage arch Architecture + * + * @returns Protocol String list if elements are found at the known xpath + * @returns String[0] if nothing is there + */ + public String[] getProtocolArray(String arch, String usage) { + String[] xPath; + String usageXpath = ""; + String archXpath = ""; + + if (arch == null || arch.equals("")) { + return new String[0]; + } else { + archXpath = "/Protocol"; + if (usage != null && !usage.equals("")) { + usageXpath = "/Protocol[@Usage='" + usage + "']"; + xPath = new String[] { usageXpath, archXpath }; + } else { + return getProtocolArray(arch); + } + + } + + Object[] returns = get("Protocols", xPath); + if (returns == null) { + return new String[0]; + } + Protocol[] protocolList = (Protocol[]) returns; + + String[] protocolArray = new String[returns.length]; + for (int i = 0; i < returns.length; i++) { + protocolArray[i] = protocolList[i].getProtocolCName(); + } + return protocolArray; + } + + /** + * retrieve Protocol for specified usage + * + * @param arch + * Architecture + * + * @returns Protocol String list if elements are found at the known xpath + * @returns String[0] if nothing is there + */ + public String[] getProtocolArray(String arch) { + String[] xPath; + + if (arch == null || arch.equals("")) { + return new String[0]; + } else { + xPath = new String[] { "/Protocol" }; + } + + Object[] returns = get("Protocols", xPath); + if (returns == null) { + return new String[0]; + } + Protocol[] returnlList = (Protocol[]) returns; + + List protocolList = new ArrayList(); + + for (int i = 0; i < returns.length; i++) { + List archList = returnlList[i].getSupArchList(); + if (archList == null || contains(archList, arch)){ + protocolList.add(returnlList[i].getProtocolCName()); + } + } + String[] protocolArray = new String[protocolList.size()]; + for (int i = 0; i < protocolList.size(); i++) { + protocolArray[i] = protocolList.get(i); + } + return protocolArray; + } + + /** + * Retrieve ProtocolNotify for specified usage + * + * @param usage + * ProtocolNotify usage + * + * @returns String[] if elements are found at the known xpath + * @returns String[0] if nothing is there + */ + public String[] getProtocolNotifyArray(String arch) { + String[] xPath; + + if (arch == null || arch.equals("")) { + return new String[0]; + } else { + xPath = new String[] { "/ProtocolNotify" }; + } + + Object[] returns = get("Protocols", xPath); + if (returns == null) { + return new String[0]; + } + + List protocolNotifyList = new ArrayList(); + + for (int i = 0; i < returns.length; i++) { + List archList = ((ProtocolNotify) returns[i]).getSupArchList(); + if (archList == null || contains(archList, arch)){ + protocolNotifyList.add(((ProtocolNotify) returns[i]).getProtocolNotifyCName()); + } + + } + String[] protocolNotifyArray = new String[protocolNotifyList.size()]; + for (int i = 0; i < protocolNotifyList.size(); i++) { + protocolNotifyArray[i] = protocolNotifyList.get(i); + } + return protocolNotifyArray; + } + + /** + * Retrieve ProtocolNotify for specified usage + * + * @param usage + * ProtocolNotify usage + * + * @returns String[] if elements are found at the known xpath + * @returns String[0] if nothing is there + */ + public String[] getProtocolNotifyArray(String arch, String usage) { + + String[] xPath; + String usageXpath; + String archXpath; + + if (arch == null || arch.equals("")) { + return new String[0]; + } else { + archXpath = "/ProtocolNotify"; + if (usage != null && !usage.equals("")) { + usageXpath = "/ProtocolNotify[@Usage='" + arch + "']"; + xPath = new String[] { archXpath, usageXpath }; + } else { + return getProtocolNotifyArray(arch); + } + } + + Object[] returns = get("Protocols", xPath); + if (returns == null) { + return new String[0]; + } + + String[] protocolNotifyList = new String[returns.length]; + + for (int i = 0; i < returns.length; i++) { + protocolNotifyList[i] = ((ProtocolNotify) returns[i]).getProtocolNotifyCName(); + } + return protocolNotifyList; + } + + /** + * Retrieve ModuleUnloadImage names + * + * @returns ModuleUnloadImage name list if elements are found at the known + * xpath + * @returns null if nothing is there + */ + public String[] getModuleUnloadImageArray() { + String[] xPath = new String[] { "/Extern/ModuleUnloadImage" }; + + Object[] returns = get("Externs", xPath); + if (returns != null && returns.length > 0) { + String[] stringArray = new String[returns.length]; + CNameType[] doc = (CNameType[]) returns; + + for (int i = 0; i < returns.length; ++i) { + stringArray[i] = doc[i].getStringValue(); + } + + return stringArray; + } + + return null; + } + + /** + * Retrieve Extern + * + * @returns Extern objects list if elements are found at the known xpath + * @returns null if nothing is there + */ + public ExternsDocument.Externs.Extern[] getExternArray() { + String[] xPath = new String[] { "/Extern" }; + + Object[] returns = get("Externs", xPath); + if (returns != null && returns.length > 0) { + return (ExternsDocument.Externs.Extern[]) returns; + } + + return null; + } + + /** + * Retrieve PpiNotify for specified arch + * + * @param arch + * PpiNotify arch + * + * @returns String[] if elements are found at the known xpath + * @returns String[0] if nothing is there + */ + public String[] getPpiNotifyArray(String arch) { + String[] xPath; + + if (arch == null || arch.equals("")) { + return new String[0]; + } else { + xPath = new String[] { "/PpiNotify" }; + } + + Object[] returns = get("PPIs", xPath); + if (returns == null) { + return new String[0]; + } + + + List ppiNotifyList = new ArrayList(); + for (int i = 0; i < returns.length; i++) { + List archList = ((PPIsDocument.PPIs.PpiNotify) returns[i]).getSupArchList(); + if (archList == null || contains(archList, arch)){ + ppiNotifyList.add(((PPIsDocument.PPIs.PpiNotify) returns[i]).getPpiNotifyCName()); + } + + } + String[] ppiNotifyArray = new String[ppiNotifyList.size()]; + for (int i = 0; i < ppiNotifyList.size(); i++) { + ppiNotifyArray[i] = ppiNotifyList.get(i); + } + + return ppiNotifyArray; + } + + /** + * Retrieve PpiNotify for specified usage and arch + * + * @param arch + * PpiNotify arch usage PpiNotify usage + * + * + * @returns String[] if elements are found at the known xpath + * @returns String[0] if nothing is there + */ + public String[] getPpiNotifyArray(String arch, String usage) { + + String[] xPath; + String usageXpath; + String archXpath; + + if (arch == null || arch.equals("")) { + return new String[0]; + } else { + archXpath = "/PpiNotify"; + if (usage != null && !usage.equals("")) { + usageXpath = "/PpiNotify[@Usage='" + arch + "']"; + xPath = new String[] { archXpath, usageXpath }; + } else { + return getProtocolNotifyArray(arch); + } + } + + Object[] returns = get("PPIs", xPath); + if (returns == null) { + return new String[0]; + } + + String[] ppiNotifyList = new String[returns.length]; + + for (int i = 0; i < returns.length; i++) { + ppiNotifyList[i] = ((PPIsDocument.PPIs.PpiNotify) returns[i]).getPpiNotifyCName(); + } + return ppiNotifyList; + } + + /** + * Retrieve Ppi for specified arch + * + * @param arch + * Ppi arch + * + * @returns String[] if elements are found at the known xpath + * @returns String[0] if nothing is there + */ + public String[] getPpiArray(String arch) { + String[] xPath; + + if (arch == null || arch.equals("")) { + return new String[0]; + } else { + xPath = new String[] { "/Ppi" }; + } + + Object[] returns = get("PPIs", xPath); + if (returns == null) { + return new String[0]; + } + + List ppiList = new ArrayList(); + for (int i = 0; i < returns.length; i++) { + List archList = ((PPIsDocument.PPIs.Ppi) returns[i]).getSupArchList(); + if (archList == null || contains(archList, arch)){ + ppiList.add(((PPIsDocument.PPIs.Ppi) returns[i]).getPpiCName()); + } + + } + String[] ppiArray = new String[ppiList.size()]; + for (int i = 0; i < ppiList.size(); i++) { + ppiArray[i] = ppiList.get(i); + } + return ppiArray; + } + + /** + * Retrieve PpiNotify for specified usage and arch + * + * @param arch + * PpiNotify arch usage PpiNotify usage + * + * + * @returns String[] if elements are found at the known xpath + * @returns String[0] if nothing is there + */ + public String[] getPpiArray(String arch, String usage) { + + String[] xPath; + String usageXpath; + String archXpath; + + if (arch == null || arch.equals("")) { + return new String[0]; + } else { + archXpath = "/Ppi"; + if (usage != null && !usage.equals("")) { + usageXpath = "/Ppi[@Usage='" + arch + "']"; + xPath = new String[] { archXpath, usageXpath }; + } else { + return getProtocolNotifyArray(arch); + } + } + + Object[] returns = get("PPIs", xPath); + if (returns == null) { + return new String[0]; + } + + String[] ppiList = new String[returns.length]; + + for (int i = 0; i < returns.length; i++) { + ppiList[i] = ((PPIsDocument.PPIs.Ppi) returns[i]).getPpiCName(); + } + return ppiList; + } + + /** + * Retrieve GuidEntry information for specified usage + * + * @param arch + * GuidEntry arch + * + * @returns GuidEntry objects list if elements are found at the known xpath + * @returns null if nothing is there + */ + public String[] getGuidEntryArray(String arch) { + String[] xPath; + + if (arch == null || arch.equals("")) { + xPath = new String[] { "/GuidCNames" }; + } else { + xPath = new String[] { "/GuidCNames" }; + } + + Object[] returns = get("Guids", xPath); + if (returns == null) { + return new String[0]; + } + + List guidList = new ArrayList(); + for (int i = 0; i < returns.length; i++) { + List archList = ((GuidsDocument.Guids.GuidCNames) returns[i]).getSupArchList(); + if (archList == null || contains(archList, arch)){ + guidList.add(((GuidsDocument.Guids.GuidCNames) returns[i]).getGuidCName()); + } + + } + String[] guidArray = new String[guidList.size()]; + for (int i = 0; i < guidList.size(); i++) { + guidArray[i] = guidList.get(i); + } + return guidArray; + + } + + /** + * Retrieve GuidEntry information for specified usage + * + * @param arch + * GuidEntry arch usage GuidEntry usage + * + * @returns GuidEntry objects list if elements are found at the known xpath + * @returns null if nothing is there + */ + public String[] getGuidEntryArray(String arch, String usage) { + String[] xPath; + String archXpath; + String usageXpath; + + if (arch == null || arch.equals("")) { + return new String[0]; + } else { + archXpath = "/GuidEntry"; + if (usage != null && !usage.equals("")) { + usageXpath = "/GuidEntry[@Usage='" + arch + "']"; + xPath = new String[] { archXpath, usageXpath }; + } else { + return getProtocolNotifyArray(arch); + } + } + + Object[] returns = get("Guids", xPath); + if (returns == null) { + return new String[0]; + } + + String[] guidList = new String[returns.length]; + + for (int i = 0; i < returns.length; i++) { + guidList[i] = ((GuidsDocument.Guids.GuidCNames) returns[i]).getGuidCName(); + } + return guidList; + } + + /** + * Retrieve Library instance information + * + * @param arch + * Architecture name + * @param usage + * Library instance usage + * + * @returns library instance name list if elements are found at the known + * xpath + * @returns null if nothing is there + */ + public ModuleIdentification[] getLibraryInstance(String arch) throws EdkException { + String[] xPath; + String saGuid = null; + String saVersion = null; + String pkgGuid = null; + String pkgVersion = null; + + if (arch == null || arch.equalsIgnoreCase("")) { + xPath = new String[] { "/Instance" }; + } else { + // + // Since Schema don't have SupArchList now, so the follow Xpath is + // equal to "/Instance" and [not(@SupArchList) or @SupArchList= arch] + // don't have effect. + // + xPath = new String[] { "/Instance[not(@SupArchList) or @SupArchList='" + + arch + "']" }; + } + + Object[] returns = get("Libraries", xPath); + if (returns == null || returns.length == 0) { + return new ModuleIdentification[0]; + } + + ModuleIdentification[] saIdList = new ModuleIdentification[returns.length]; + for (int i = 0; i < returns.length; i++) { + LibrariesDocument.Libraries.Instance library = (LibrariesDocument.Libraries.Instance) returns[i]; + saGuid = library.getModuleGuid(); + saVersion = library.getModuleVersion(); + + pkgGuid = library.getPackageGuid(); + pkgVersion = library.getPackageVersion(); + + ModuleIdentification saId = new ModuleIdentification(null, saGuid, + saVersion); + PackageIdentification pkgId = new PackageIdentification(null, + pkgGuid, pkgVersion); + GlobalData.refreshPackageIdentification(pkgId); + saId.setPackage(pkgId); + GlobalData.refreshModuleIdentification(saId); + + saIdList[i] = saId; + + } + return saIdList; + } + + // / + // / This method is used for retrieving the elements information which has + // / CName sub-element + // / + private String[] getCNames(String from, String xPath[]) { + Object[] returns = get(from, xPath); + if (returns == null || returns.length == 0) { + return null; + } + + String[] strings = new String[returns.length]; + for (int i = 0; i < returns.length; ++i) { + // TBD + strings[i] = ((CNameType) returns[i]).getStringValue(); + } + + return strings; + } + + /** + * Retrive library's constructor name + * + * @returns constructor name list if elements are found at the known xpath + * @returns null if nothing is there + */ + public String getLibConstructorName() { + String[] xPath = new String[] { "/Extern/Constructor" }; + + Object[] returns = get("Externs", xPath); + if (returns != null && returns.length > 0) { + CNameType constructor = ((CNameType) returns[0]); + return constructor.getStringValue(); + } + + return null; + } + + /** + * Retrive library's destructor name + * + * @returns destructor name list if elements are found at the known xpath + * @returns null if nothing is there + */ + public String getLibDestructorName() { + String[] xPath = new String[] { "/Extern/Destructor" }; + + Object[] returns = get("Externs", xPath); + if (returns != null && returns.length > 0) { + // + // Only support one Destructor function. + // + CNameType destructor = (CNameType) returns[0]; + return destructor.getStringValue(); + } + + return null; + } + + /** + * Retrive DriverBinding names + * + * @returns DriverBinding name list if elements are found at the known xpath + * @returns null if nothing is there + */ + public String[] getDriverBindingArray() { + String[] xPath = new String[] { "/Extern/DriverBinding" }; + return getCNames("Externs", xPath); + } + + /** + * Retrive ComponentName names + * + * @returns ComponentName name list if elements are found at the known xpath + * @returns null if nothing is there + */ + public String[] getComponentNameArray() { + String[] xPath = new String[] { "/Extern/ComponentName" }; + return getCNames("Externs", xPath); + } + + /** + * Retrive DriverConfig names + * + * @returns DriverConfig name list if elements are found at the known xpath + * @returns null if nothing is there + */ + public String[] getDriverConfigArray() { + String[] xPath = new String[] { "/Extern/DriverConfig" }; + return getCNames("Externs", xPath); + } + + /** + * Retrive DriverDiag names + * + * @returns DriverDiag name list if elements are found at the known xpath + * @returns null if nothing is there + */ + public String[] getDriverDiagArray() { + String[] xPath = new String[] { "/Extern/DriverDiag" }; + return getCNames("Externs", xPath); + } + + /** + * Retrive DriverBinding, ComponentName, DriverConfig, + * DriverDiag group array + * + * @returns DriverBinding group name list if elements are found + * at the known xpath + * @returns null if nothing is there + */ + public String[][] getExternProtocolGroup() { + String[] xPath = new String[] {"/Extern"}; + Object[] returns = get("Externs",xPath); + + if (returns == null) { + return new String[0][4]; + } + List externList = new ArrayList(); + for (int i = 0; i < returns.length; i++) { + org.tianocore.ExternsDocument.Externs.Extern extern = (org.tianocore.ExternsDocument.Externs.Extern)returns[i]; + if (extern.getDriverBinding() != null) { + externList.add(extern); + } + } + + String[][] externGroup = new String[externList.size()][4]; + for (int i = 0; i < externList.size(); i++) { + String driverBindingStr = externList.get(i).getDriverBinding(); + if ( driverBindingStr != null){ + externGroup[i][0] = driverBindingStr; + } else { + externGroup[i][0] = null; + } + + String componentNameStr = externList.get(i).getComponentName(); + if (componentNameStr != null) { + externGroup[i][1] = componentNameStr; + } else { + externGroup[i][1] = null; + } + + String driverConfigStr = externList.get(i).getDriverConfig(); + if (driverConfigStr != null) { + externGroup[i][2] = driverConfigStr; + } else { + externGroup[i][2] = null; + } + + String driverDiagStr = externList.get(i).getDriverDiag(); + if (driverDiagStr != null) { + externGroup[i][3] = driverDiagStr; + } else { + externGroup[i][3] = null; + } + } + return externGroup; + } + + /** + * Retrive SetVirtualAddressMapCallBack names + * + * @returns SetVirtualAddressMapCallBack name list if elements are found at + * the known xpath + * @returns null if nothing is there + */ + public String[] getSetVirtualAddressMapCallBackArray() { + String[] xPath = new String[] { "/Extern/SetVirtualAddressMapCallBack" }; + return getCNames("Externs", xPath); + } + + /** + * Retrive ExitBootServicesCallBack names + * + * @returns ExitBootServicesCallBack name list if elements are found at the + * known xpath + * @returns null if nothing is there + */ + public String[] getExitBootServicesCallBackArray() { + String[] xPath = new String[] { "/Extern/ExitBootServicesCallBack" }; + return getCNames("Externs", xPath); + } + + /** + Judge whether current driver is PEI_PCD_DRIVER or DXE_PCD_DRIVER or + NOT_PCD_DRIVER. + + @return CommonDefinition.PCD_DRIVER_TYPE the type of current driver + **/ + public CommonDefinition.PCD_DRIVER_TYPE getPcdDriverType() { + String[] xPath = new String[] {"/PcdIsDriver"}; + Object[] results = get ("Externs", xPath); + + if (results != null && results.length != 0) { + PcdDriverTypes type = (PcdDriverTypes) results[0]; + String typeStr = type.enumValue().toString(); + if (typeStr.equals(CommonDefinition.PCD_DRIVER_TYPE.PEI_PCD_DRIVER.toString())) { + return CommonDefinition.PCD_DRIVER_TYPE.PEI_PCD_DRIVER; + } else if (typeStr.equals(CommonDefinition.PCD_DRIVER_TYPE.DXE_PCD_DRIVER.toString())) { + return CommonDefinition.PCD_DRIVER_TYPE.DXE_PCD_DRIVER; + } + return CommonDefinition.PCD_DRIVER_TYPE.UNKNOWN_PCD_DRIVER; + } + + return CommonDefinition.PCD_DRIVER_TYPE.NOT_PCD_DRIVER; + } + + /** + * Retrieve module surface area file information + * + * @returns ModuleSA objects list if elements are found at the known xpath + * @returns Empty ModuleSA list if nothing is there + */ + public Map> getFpdModules() throws EdkException { + String[] xPath = new String[] { "/FrameworkModules/ModuleSA" }; + Object[] result = get("PlatformSurfaceArea", xPath); + String arch = null; + String fvBinding = null; + String saGuid = null; + String saVersion = null; + String pkgGuid = null; + String pkgVersion = null; + + Map> fpdModuleMap = new LinkedHashMap>(); + + if (result == null) { + return fpdModuleMap; + } + + for (int i = 0; i < result.length; i++) { + // + // Get Fpd SA Module element node and add to ObjectMap. + // + Map ObjectMap = new HashMap(); + ModuleSADocument.ModuleSA moduleSA = (ModuleSADocument.ModuleSA) result[i]; + if (((ModuleSADocument.ModuleSA) result[i]).getLibraries() != null) { + ObjectMap.put("Libraries", moduleSA.getLibraries()); + } + if (((ModuleSADocument.ModuleSA) result[i]).getPcdBuildDefinition() != null) { + ObjectMap.put("PcdBuildDefinition", moduleSA.getPcdBuildDefinition()); + } + if (((ModuleSADocument.ModuleSA) result[i]).getModuleSaBuildOptions() != null) { + ObjectMap.put("ModuleSaBuildOptions", moduleSA.getModuleSaBuildOptions()); + } + + // + // Get Fpd SA Module attribute and create FpdMoudleIdentification. + // + if (moduleSA.isSetSupArchList()) { + arch = moduleSA.getSupArchList().toString(); + } else { + arch = null; + } + + // TBD + fvBinding = null; + saVersion = ((ModuleSADocument.ModuleSA) result[i]).getModuleVersion(); + + saGuid = moduleSA.getModuleGuid(); + pkgGuid = moduleSA.getPackageGuid(); + pkgVersion = moduleSA.getPackageVersion(); + + // + // Create Module Identification which have class member of package + // identification. + // + PackageIdentification pkgId = new PackageIdentification(null, pkgGuid, pkgVersion); + GlobalData.refreshPackageIdentification(pkgId); + + ModuleIdentification saId = new ModuleIdentification(null, saGuid, saVersion); + saId.setPackage(pkgId); + GlobalData.refreshModuleIdentification(saId); + + + + // + // Create FpdModule Identification which have class member of module + // identification + // + String[] archList = new String[0]; + if (arch == null || arch.trim().length() == 0) { + archList = GlobalData.getToolChainInfo().getArchs(); + } else { + archList = arch.split(" "); + } + for (int j = 0; j < archList.length; j++) { + FpdModuleIdentification fpdSaId = new FpdModuleIdentification(saId, archList[j]); + + if (fvBinding != null) { + fpdSaId.setFvBinding(fvBinding); + } + + // + // Put element to Map>. + // + fpdModuleMap.put(fpdSaId, ObjectMap); + } + } + return fpdModuleMap; + } + + /** + * Retrieve valid image names + * + * @returns valid iamges name list if elements are found at the known xpath + * @returns empty list if nothing is there + */ + public String[] getFpdValidImageNames() { + String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='ImageName']/FvImageNames" }; + + Object[] queryResult = get("PlatformSurfaceArea", xPath); + if (queryResult == null) { + return new String[0]; + } + + String[] result = new String[queryResult.length]; + for (int i = 0; i < queryResult.length; i++) { + result[i] = ((XmlString) queryResult[i]).getStringValue(); + } + + return result; + } + + public Node getFpdUserExtensionPreBuild() { + String[] xPath = new String[] { "/UserExtensions[@UserID='TianoCore' and @Identifier='0']" }; + + Object[] queryResult = get("PlatformSurfaceArea", xPath); + if (queryResult == null || queryResult.length == 0) { + return null; + } + UserExtensionsDocument.UserExtensions a = (UserExtensionsDocument.UserExtensions)queryResult[0]; + + return a.getDomNode(); + } + + public Node getFpdUserExtensionPostBuild() { + String[] xPath = new String[] { "/UserExtensions[@UserID='TianoCore' and @Identifier='1']" }; + + Object[] queryResult = get("PlatformSurfaceArea", xPath); + if (queryResult == null || queryResult.length == 0) { + return null; + } + UserExtensionsDocument.UserExtensions a = (UserExtensionsDocument.UserExtensions)queryResult[0]; + + return a.getDomNode(); + } + + /** + * Retrieve FV image option information + * + * @param fvName + * FV image name + * + * @returns option name/value list if elements are found at the known xpath + * @returns empty list if nothing is there + */ + public String[][] getFpdOptions(String fvName) { + String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='Options' and ./FvImageNames='" + + fvName + "']/FvImageOptions" }; + Object[] queryResult = get("PlatformSurfaceArea", xPath); + if (queryResult == null) { + return new String[0][]; + } + ArrayList list = new ArrayList(); + for (int i = 0; i < queryResult.length; i++) { + FvImagesDocument.FvImages.FvImage.FvImageOptions item = (FvImagesDocument.FvImages.FvImage.FvImageOptions) queryResult[i]; + List namevalues = item + .getNameValueList(); + Iterator iter = namevalues.iterator(); + while (iter.hasNext()) { + FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue nvItem = (FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue) iter + .next(); + list.add(new String[] { nvItem.getName(), nvItem.getValue() }); + } + } + String[][] result = new String[list.size()][2]; + for (int i = 0; i < list.size(); i++) { + result[i][0] = list.get(i)[0]; + result[i][1] = list.get(i)[1]; + } + return result; + + } + + public XmlObject getFpdBuildOptions() { + String[] xPath = new String[] { "/BuildOptions" }; + + Object[] queryResult = get("PlatformSurfaceArea", xPath); + + if (queryResult == null || queryResult.length == 0) { + return null; + } + return (XmlObject)queryResult[0]; + } + + public PlatformIdentification getFpdHeader() { + String[] xPath = new String[] { "/PlatformHeader" }; + + Object[] returns = get("PlatformSurfaceArea", xPath); + + if (returns == null || returns.length == 0) { + return null; + } + PlatformHeaderDocument.PlatformHeader header = (PlatformHeaderDocument.PlatformHeader) returns[0]; + + String name = header.getPlatformName(); + + String guid = header.getGuidValue(); + + String version = header.getVersion(); + + return new PlatformIdentification(name, guid, version); + } + + /** + * Retrieve FV image attributes information + * + * @param fvName + * FV image name + * + * @returns attribute name/value list if elements are found at the known + * xpath + * @returns empty list if nothing is there + */ + public String[][] getFpdAttributes(String fvName) { + String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='Attributes' and ./FvImageNames='" + + fvName + "']/FvImageOptions" }; + Object[] queryResult = get("PlatformSurfaceArea", xPath); + if (queryResult == null) { + return new String[0][]; + } + ArrayList list = new ArrayList(); + for (int i = 0; i < queryResult.length; i++) { + + FvImagesDocument.FvImages.FvImage.FvImageOptions item = (FvImagesDocument.FvImages.FvImage.FvImageOptions) queryResult[i]; + List namevalues = item.getNameValueList(); + Iterator iter = namevalues.iterator(); + while (iter.hasNext()) { + FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue nvItem = (FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue) iter + .next(); + list.add(new String[] { nvItem.getName(), nvItem.getValue() }); + } + } + String[][] result = new String[list.size()][2]; + for (int i = 0; i < list.size(); i++) { + result[i][0] = list.get(i)[0]; + result[i][1] = list.get(i)[1]; + } + return result; + } + + /** + * Retrieve flash definition file name + * + * @returns file name if elements are found at the known xpath + * @returns null if nothing is there + */ + public String getFlashDefinitionFile() { + String[] xPath = new String[] { "/PlatformDefinitions/FlashDeviceDefinitions/FlashDefinitionFile" }; + + Object[] queryResult = get("PlatformSurfaceArea", xPath); + if (queryResult == null || queryResult.length == 0) { + return null; + } + + FileNameConvention filename = (FileNameConvention) queryResult[queryResult.length - 1]; + return filename.getStringValue(); + } + + public String[][] getFpdGlobalVariable() { + String[] xPath = new String[] { "/Flash/FvImages/NameValue" }; + Object[] queryResult = get("PlatformSurfaceArea", xPath); + if (queryResult == null) { + return new String[0][]; + } + + String[][] result = new String[queryResult.length][2]; + + for (int i = 0; i < queryResult.length; i++) { + FvImagesDocument.FvImages.NameValue item = (FvImagesDocument.FvImages.NameValue)queryResult[i]; + result[i][0] = item.getName(); + result[i][1] = item.getValue(); + } + return result; + } + + /** + * Retrieve FV image component options + * + * @param fvName + * FV image name + * + * @returns name/value pairs list if elements are found at the known xpath + * @returns empty list if nothing is there + */ + public String[][] getFpdComponents(String fvName) { + String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='Components' and ./FvImageNames='"+ fvName + "']/FvImageOptions" }; + Object[] queryResult = get("PlatformSurfaceArea", xPath); + if (queryResult == null) { + return new String[0][]; + } + + ArrayList list = new ArrayList(); + for (int i = 0; i < queryResult.length; i++) { + FvImagesDocument.FvImages.FvImage.FvImageOptions item = (FvImagesDocument.FvImages.FvImage.FvImageOptions) queryResult[i]; + List namevalues = item.getNameValueList(); + Iterator iter = namevalues.iterator(); + while (iter.hasNext()) { + FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue nvItem = (FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue) iter + .next(); + list.add(new String[] { nvItem.getName(), nvItem.getValue() }); + } + } + String[][] result = new String[list.size()][2]; + for (int i = 0; i < list.size(); i++) { + result[i][0] = list.get(i)[0]; + result[i][1] = list.get(i)[1]; + } + return result; + } + + /** + * Retrieve PCD tokens + * + * @returns CName/ItemType pairs list if elements are found at the known + * xpath + * @returns null if nothing is there + */ + public String[][] getPcdTokenArray() { + String[] xPath = new String[] { "/PcdData" }; + + Object[] returns = get("PCDs", xPath); + if (returns == null || returns.length == 0) { + return null; + } + + return null; + } + + /** + * Retrieve MAS header + * + * @return + * @return + */ + public ModuleIdentification getMsaHeader() { + String[] xPath = new String[] { "/" }; + Object[] returns = get("MsaHeader", xPath); + + if (returns == null || returns.length == 0) { + return null; + } + + MsaHeader msaHeader = (MsaHeader) returns[0]; + // + // Get BaseName, ModuleType, GuidValue, Version + // which in MsaHeader. + // + String name = msaHeader.getModuleName(); + String moduleType = msaHeader.getModuleType().toString(); + String guid = msaHeader.getGuidValue(); + String version = msaHeader.getVersion(); + + ModuleIdentification moduleId = new ModuleIdentification(name, guid, + version); + + moduleId.setModuleType(moduleType); + + return moduleId; + } + + /** + * Retrieve Extern Specification + * + * @param + * + * @return String[] If have specification element in the String[0] + * If no specification element in the + * + */ + + public String[] getExternSpecificaiton() { + String[] xPath = new String[] { "/Specification" }; + + Object[] queryResult = get("Externs", xPath); + if (queryResult == null) { + return new String[0]; + } + + String[] specificationList = new String[queryResult.length]; + for (int i = 0; i < queryResult.length; i++) { + specificationList[i] = ((Sentence)queryResult[i]) + .getStringValue(); + } + return specificationList; + } + + /** + * Retreive MsaFile which in SPD + * + * @param + * @return String[][3] The string sequence is ModuleName, ModuleGuid, + * ModuleVersion, MsaFile String[0][] If no msafile in SPD + */ + public String[] getSpdMsaFile() { + String[] xPath = new String[] { "/MsaFiles" }; + + Object[] returns = get("PackageSurfaceArea", xPath); + if (returns == null) { + return new String[0]; + } + + List filenameList = ((MsaFilesDocument.MsaFiles) returns[0]) + .getFilenameList(); + return filenameList.toArray(new String[filenameList.size()]); + } + + /** + * Reteive + */ + public Map getSpdLibraryClasses() { + String[] xPath = new String[] { "/LibraryClassDeclarations/LibraryClass" }; + + Object[] returns = get("PackageSurfaceArea", xPath); + + // + // Create Map, Key - LibraryClass, String[] - LibraryClass Header file. + // + Map libClassHeaderMap = new HashMap(); + + if (returns == null) { + return libClassHeaderMap; + } + + for (int i = 0; i < returns.length; i++) { + LibraryClassDeclarationsDocument.LibraryClassDeclarations.LibraryClass library = (LibraryClassDeclarationsDocument.LibraryClassDeclarations.LibraryClass) returns[i]; + libClassHeaderMap.put(library.getName(), new String[] { library + .getIncludeHeader() }); + } + return libClassHeaderMap; + } + + /** + * Reteive + */ + public Map getSpdPackageHeaderFiles() { + String[] xPath = new String[] { "/PackageHeaders/IncludePkgHeader" }; + + Object[] returns = get("PackageSurfaceArea", xPath); + + // + // Create Map, Key - ModuleType, String - PackageInclude Header file. + // + Map packageIncludeMap = new HashMap(); + + if (returns == null) { + return packageIncludeMap; + } + + for (int i = 0; i < returns.length; i++) { + PackageHeadersDocument.PackageHeaders.IncludePkgHeader includeHeader = (PackageHeadersDocument.PackageHeaders.IncludePkgHeader) returns[i]; + packageIncludeMap.put(includeHeader.getModuleType().toString(), + includeHeader.getStringValue()); + } + return packageIncludeMap; + } + + public PackageIdentification getSpdHeader() { + String[] xPath = new String[] { "/SpdHeader" }; + + Object[] returns = get("PackageSurfaceArea", xPath); + + if (returns == null || returns.length == 0) { + return null; + } + + SpdHeaderDocument.SpdHeader header = (SpdHeaderDocument.SpdHeader) returns[0]; + + String name = header.getPackageName(); + + String guid = header.getGuidValue(); + + String version = header.getVersion(); + + return new PackageIdentification(name, guid, version); + } + + /** + * Reteive + */ + public Map getSpdGuid() { + String[] xPath = new String[] { "/GuidDeclarations/Entry" }; + + Object[] returns = get("PackageSurfaceArea", xPath); + + // + // Create Map, Key - GuidName, String[] - C_NAME & GUID value. + // + Map guidDeclMap = new HashMap(); + if (returns == null) { + return guidDeclMap; + } + + for (int i = 0; i < returns.length; i++) { + GuidDeclarationsDocument.GuidDeclarations.Entry entry = (GuidDeclarationsDocument.GuidDeclarations.Entry) returns[i]; + String[] guidPair = new String[2]; + guidPair[0] = entry.getCName(); + guidPair[1] = entry.getGuidValue(); + guidDeclMap.put(entry.getCName(), guidPair); + EdkLog.log(EdkLog.EDK_VERBOSE, entry.getName()); + EdkLog.log(EdkLog.EDK_VERBOSE, guidPair[0]); + EdkLog.log(EdkLog.EDK_VERBOSE, guidPair[1]); + } + return guidDeclMap; + } + + /** + * Reteive + */ + public Map getSpdProtocol() { + String[] xPath = new String[] { "/ProtocolDeclarations/Entry" }; + + Object[] returns = get("PackageSurfaceArea", xPath); + + // + // Create Map, Key - protocolName, String[] - C_NAME & GUID value. + // + Map protoclMap = new HashMap(); + + if (returns == null) { + return protoclMap; + } + + for (int i = 0; i < returns.length; i++) { + ProtocolDeclarationsDocument.ProtocolDeclarations.Entry entry = (ProtocolDeclarationsDocument.ProtocolDeclarations.Entry) returns[i]; + String[] protocolPair = new String[2]; + + protocolPair[0] = entry.getCName(); + protocolPair[1] = entry.getGuidValue(); + protoclMap.put(entry.getCName(), protocolPair); + EdkLog.log(EdkLog.EDK_VERBOSE, entry.getName()); + EdkLog.log(EdkLog.EDK_VERBOSE, protocolPair[0]); + EdkLog.log(EdkLog.EDK_VERBOSE, protocolPair[1]); + } + return protoclMap; + } + + /** + * getSpdPpi() Retrieve the SPD PPI Entry + * + * @param + * @return Map if get the PPI entry from SPD. Key - PPI + * Name String[0] - PPI CNAME String[1] - PPI Guid Null if no PPI + * entry in SPD. + */ + public Map getSpdPpi() { + String[] xPath = new String[] { "/PpiDeclarations/Entry" }; + + Object[] returns = get("PackageSurfaceArea", xPath); + + // + // Create Map, Key - protocolName, String[] - C_NAME & GUID value. + // + Map ppiMap = new HashMap(); + + if (returns == null) { + return ppiMap; + } + + for (int i = 0; i < returns.length; i++) { + PpiDeclarationsDocument.PpiDeclarations.Entry entry = (PpiDeclarationsDocument.PpiDeclarations.Entry) returns[i]; + String[] ppiPair = new String[2]; + ppiPair[0] = entry.getCName(); + ppiPair[1] = entry.getGuidValue(); + ppiMap.put(entry.getCName(), ppiPair); + } + return ppiMap; + } + + /** + * Retrieve module Guid string + * + * @returns GUILD string if elements are found at the known xpath + * @returns null if nothing is there + */ + public String getModuleGuid() { + String[] xPath = new String[] { "" }; + + Object[] returns = get("MsaHeader", xPath); + if (returns != null && returns.length > 0) { + String guid = ((MsaHeaderDocument.MsaHeader) returns[0]) + .getGuidValue(); + return guid; + } + + return null; + } + + // + // For new Pcd + // + public ModuleSADocument.ModuleSA[] getFpdModuleSAs() { + String[] xPath = new String[] { "/FrameworkModules/ModuleSA" }; + Object[] result = get("PlatformSurfaceArea", xPath); + if (result != null) { + return (ModuleSADocument.ModuleSA[]) result; + } + return new ModuleSADocument.ModuleSA[0]; + + } + /** + Get name array of PCD in a module. In one module, token space + is same, and token name should not be conflicted. + + @return String[] + **/ + public String[] getModulePcdEntryNameArray() { + PcdCodedDocument.PcdCoded.PcdEntry[] pcdEntries = null; + String[] results; + int index; + String[] xPath = new String[] {"/PcdEntry"}; + Object[] returns = get ("PcdCoded", xPath); + + if (returns == null) { + return new String[0]; + } + + pcdEntries = (PcdCodedDocument.PcdCoded.PcdEntry[])returns; + results = new String[pcdEntries.length]; + + for (index = 0; index < pcdEntries.length; index ++) { + results[index] = pcdEntries[index].getCName(); + } + return results; + } + + /** + Search in a List for a given string + + @return boolean + **/ + public boolean contains(List list, String str) { + if (list == null || list.size()== 0) { + return true; + } + Iterator it = list.iterator(); + while (it.hasNext()) { + String s = (String)it.next(); + if (s.equalsIgnoreCase(str)) { + return true; + } + } + + return false; + } + + public boolean isHaveTianoR8FlashMap(){ + String[] xPath = new String[] {"/"}; + Object[] returns = get ("Externs", xPath); + + if (returns == null) { + return false; + } + + ExternsDocument.Externs ext = (ExternsDocument.Externs)returns[0]; + + if (ext.getTianoR8FlashMapH()){ + return true; + }else { + return false; + } + } + + public Node getFpdModuleSequence(String fvName) { + String[] xPath = new String[] { "/BuildOptions/UserExtensions[@UserID='IMAGES' and @Identifier='1' and ./FvName='" + fvName + "']" }; + Object[] result = get("PlatformSurfaceArea", xPath); + + if (result == null || result.length == 0) { + return null; + } + + UserExtensionsDocument.UserExtensions a = (UserExtensionsDocument.UserExtensions)result[0]; + + return a.getDomNode(); + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/global/VariableTask.java b/Tools/Java/Source/GenBuild/org/tianocore/build/global/VariableTask.java new file mode 100644 index 0000000000..021b8d5b00 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/global/VariableTask.java @@ -0,0 +1,71 @@ +/** @file + * This file is ANT task VariableTask. + * + * VariableTask task implements part of ANT property task. The difference is + * this task will override variable with same name, but ANT property task do not. + * + * 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.global; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +/** + * VariableTask task implements part of ANT property task. The difference is + * this task will override variable with same name, but ANT property task do not. + * + * @since GenBuild 1.0 + */ +public class VariableTask extends Task { + + /** + * property value + */ + private String value; + + /** + * property name + */ + private String name; + + /** + * Set property name. + * + * @param name property name + */ + public void setName( String name ) { + this.name = name; + } + + + /** + * Set property value. + * + * @param value property value + */ + public void setValue( String value ) { + this.value = value; + } + + /** + * ANT task's entry point, will be called after init(). + * + * @exception BuildException + * If name or value is null + */ + public void execute() throws BuildException { + if (name == null || value == null) { + throw new BuildException("Name or value cannot be null."); + } + getProject().setProperty(name, value); + } +} + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/id/FpdModuleIdentification.java b/Tools/Java/Source/GenBuild/org/tianocore/build/id/FpdModuleIdentification.java new file mode 100644 index 0000000000..c9bb7109d5 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/id/FpdModuleIdentification.java @@ -0,0 +1,130 @@ +/** @file + Java class FpdModuleIdentification is used to present a module identification + from BaseName, GUID, Version, PackageName, and ARCH. + +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.id; + + +/** + This class is used to identify a module with Module Guid, Module Version, + Package Guid, Package Version and Arch. + + @since GenBuild 1.0 +**/ +public class FpdModuleIdentification { + + private String arch; + + private String fvBinding = "NULL"; // Optional + + private ModuleIdentification module; + + /** + Constructor Method. + + @param arch Build Arch + @param fvBinding Belong to what FVs + @param module ModuleIdentification + **/ + public FpdModuleIdentification(String arch, String fvBinding, ModuleIdentification module){ + this.arch = arch; + this.fvBinding = fvBinding; + this.module = module; + } + + /** + Constructor Method. + + @param arch Build Arch + @param module ModuleIdentification + **/ + public FpdModuleIdentification(ModuleIdentification module, String arch){ + this.arch = arch; + this.module = module; + } + /** + Override java.lang.Object#equals. + +

Currently, use BaseName and ARCH to identify a module. It will enhance + in the next version.

+ + @see java.lang.Object#equals(java.lang.Object) + **/ + public boolean equals(Object obj) { + if (obj instanceof FpdModuleIdentification) { + FpdModuleIdentification moduleIdObj = (FpdModuleIdentification)obj; + if ( module.equals(moduleIdObj.module) && arch.equalsIgnoreCase(moduleIdObj.arch)) { + return true; + } + return false; + } + else { + return false; + } + } + + /** + @param fvBinding + **/ + public void setFvBinding(String fvBinding) { + this.fvBinding = fvBinding; + } + + /* (non-Javadoc) + @see java.lang.Object#toString() + **/ + public String toString(){ + return arch + ":" + module; + } + + /** + @return String fvBinding + **/ + public String getFvBinding() { + return fvBinding; + } + + /** + @return ModuleIdentification module ID + **/ + public ModuleIdentification getModule() { + return module; + } + + /** + @param module Module Identification + **/ + public void setModule(ModuleIdentification module) { + this.module = module; + } + + /** + @return String arch + **/ + public String getArch() { + return arch; + } + + /** + @param arch build ARCH + **/ + public void setArch(String arch) { + this.arch = arch; + } + + /* (non-Javadoc) + @see java.lang.Object#hashCode() + **/ + public int hashCode(){ + return module.hashCode(); + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/id/Identification.java b/Tools/Java/Source/GenBuild/org/tianocore/build/id/Identification.java new file mode 100644 index 0000000000..677d096274 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/id/Identification.java @@ -0,0 +1,128 @@ +/** @file +This file is to define Identification class. + +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.id; + + +/** + This class is used to identify with its GUID and Version. + + @since GenBuild 1.0 +**/ +public class Identification { + + String name; + + String guid; + + String version; + + /** + @param name Name + @param guid Guid + @param version Version + **/ + Identification(String name, String guid, String version){ + this.name = name; + this.guid = guid; + this.version = version; + } + + /** + @param guid Guid + @param version Version + **/ + Identification(String guid, String version){ + this.guid = guid; + this.version = version; + } + + /* (non-Javadoc) + @see java.lang.Object#equals(java.lang.Object) + **/ + public boolean equals(Object obj) { + if (obj instanceof Identification) { + Identification id = (Identification)obj; + if ( guid.equalsIgnoreCase(id.guid)) { + if (version == null || id.version == null) { + return true; + } + else if (version.trim().equalsIgnoreCase("") || id.version.trim().equalsIgnoreCase("")){ + return true; + } + else if (version.equalsIgnoreCase(id.version)) { + return true; + } + } + return false; + } + else { + return super.equals(obj); + } + } + + /** + @param name Name + **/ + public void setName(String name) { + this.name = name; + } + + /** + @param guid Guid + **/ + public void setGuid(String guid) { + this.guid = guid; + } + + /** + @param version Version + **/ + public void setVersion(String version) { + this.version = version; + } + + public String getGuid() { + return guid; + } + + /** + @return String Name + **/ + public String getName() { + return name; + } + + /** + @return String Version + **/ + public String getVersion() { + return version; + } + + public String toGuidString() { + if (version == null || version.trim().equalsIgnoreCase("")) { + return "[" + guid + "]"; + } + else { + return "[" + guid + "] and version [" + version + "]"; + } + } + + /* (non-Javadoc) + @see java.lang.Object#hashCode() + **/ + public int hashCode(){ + return guid.toLowerCase().hashCode(); + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/id/ModuleIdentification.java b/Tools/Java/Source/GenBuild/org/tianocore/build/id/ModuleIdentification.java new file mode 100644 index 0000000000..87024d13a0 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/id/ModuleIdentification.java @@ -0,0 +1,171 @@ +/** @file +This file is to define ModuleIdentification class. + +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.id; + +import java.io.File; + +/** + This class is used to identify a module with Module Guid, Module Version, + Package Guid, Package Version. + + @since GenBuild 1.0 +**/ +public class ModuleIdentification extends Identification { + + private PackageIdentification packageId; + + private File msaFile; + + private String moduleType; + + private boolean isLibrary = false; + + /** + @param guid Guid + @param version Version + **/ + public ModuleIdentification(String guid, String version){ + super(guid, version); + } + + /** + @param guid Guid + @param version Version + @param packageId Package Identification + **/ + public ModuleIdentification(String guid, String version, PackageIdentification packageId){ + super(guid, version); + this.packageId = packageId; + } + + /** + @param name Name + @param guid Guid + @param version Version + **/ + public ModuleIdentification(String name, String guid, String version){ + super(name, guid, version); + } + + /** + @param name Name + @param guid Guid + @param version Version + @param packageId PackageIdentification + **/ + public ModuleIdentification(String name, String guid, String version, PackageIdentification packageId){ + super(name, guid, version); + this.packageId = packageId; + } + + /** + @return boolean is this module is library + **/ + public boolean isLibrary() { + return isLibrary; + } + + /** + @param isLibrary + **/ + public void setLibrary(boolean isLibrary) { + this.isLibrary = isLibrary; + } + + /** + @return MSA File + **/ + public File getMsaFile() { + return msaFile; + } + + /** + @return Module relative path to package + **/ + public String getModuleRelativePath() { + if (msaFile.getParent().length() == packageId.getPackageDir().length()) { + return "."; + } + return msaFile.getParent().substring(packageId.getPackageDir().length() + 1); + } + + /** + @param msaFile Set Msa File + **/ + public void setMsaFile(File msaFile) { + this.msaFile = msaFile; + } + + public boolean equals(Object obj) { + if (obj instanceof ModuleIdentification) { + ModuleIdentification id = (ModuleIdentification)obj; + if (guid.equalsIgnoreCase(id.getGuid()) && packageId.equals(id.getPackage())) { + if (version == null || id.version == null) { + return true; + } + else if (version.trim().equalsIgnoreCase("") || id.version.trim().equalsIgnoreCase("")){ + return true; + } + else if (version.equalsIgnoreCase(id.version)) { + return true; + } + } + return false; + } + else { + return super.equals(obj); + } + } + + public String toString() { + if (version == null || version.trim().equalsIgnoreCase("")) { + return "Module [" + name + "] in " + packageId; + } + else { + return "Module [" + name + " " + version + "] in " + packageId; + } + } + + /** + @param packageId set package identification + **/ + public void setPackage(PackageIdentification packageId) { + this.packageId = packageId; + } + + /** + @return get package identification + **/ + public PackageIdentification getPackage() { + return packageId; + } + + /** + @return get module type + **/ + public String getModuleType() { + return moduleType; + } + + /** + @param moduleType set module type + **/ + public void setModuleType(String moduleType) { + this.moduleType = moduleType; + } + + public String getName() { + return name; + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/id/PackageIdentification.java b/Tools/Java/Source/GenBuild/org/tianocore/build/id/PackageIdentification.java new file mode 100644 index 0000000000..9371f6afda --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/id/PackageIdentification.java @@ -0,0 +1,118 @@ +/** @file +This file is to define PackageIdentification class. + +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.id; +import java.io.File; + +import org.tianocore.build.global.GlobalData; + +/** + This class is used to identify a package. + + @since GenBuild 1.0 +**/ +public class PackageIdentification extends Identification{ + + // + // SPD file + // + private File spdFile; + + /** + @param guid Guid + @param version Version + **/ + public PackageIdentification(String guid, String version){ + super(guid, version); + } + + /** + @param name Name + @param guid Guid + @param version Version + **/ + public PackageIdentification(String name, String guid, String version){ + super(name, guid, version); + } + + /** + @param name Name + @param guid Guid + @param version Version + @param spdFilename SPD file name + **/ + public PackageIdentification(String name, String guid, String version, String spdFilename){ + super(name, guid, version); + this.spdFile = new File(spdFilename); + } + + /** + @param name Name + @param guid Guid + @param version Version + @param spdFile SPD file + **/ + public PackageIdentification(String name, String guid, String version, File spdFile){ + super(name, guid, version); + this.spdFile = spdFile; + } + + /** + set SPD file. + @param spdFile SPD file + **/ + public void setSpdFile(File spdFile) { + this.spdFile = spdFile; + } + + /** + get SPD file + @return SPD file + **/ + public File getSpdFile() { + return spdFile; + } + + public String toString(){ + if (version == null || version.trim().equalsIgnoreCase("")) { + return "package [" + name + "]"; + } + else { + return "package [" + name + " " + version + "]"; + } + } + + /** + get package directory + @return Package Directory + **/ + public String getPackageDir(){ + return spdFile.getParent(); + } + + /** + get package relative directory. + @return package relative directory + **/ + public String getPackageRelativeDir(){ + String relativeDir =spdFile.getParent().substring(GlobalData.getWorkspacePath().length()); + if(relativeDir.startsWith("\\") || relativeDir.startsWith("/")) { + relativeDir = relativeDir.substring(1); + } + return relativeDir; + } + + public String getName() { + return name; + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/id/PlatformIdentification.java b/Tools/Java/Source/GenBuild/org/tianocore/build/id/PlatformIdentification.java new file mode 100644 index 0000000000..7c669652b8 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/id/PlatformIdentification.java @@ -0,0 +1,113 @@ +/** @file +This file is to define PlatformIdentification class. + +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.id; +import java.io.File; + +import org.tianocore.build.global.GlobalData; + +/** + This class is used to identify a platform. + + @since GenBuild 1.0 +**/ +public class PlatformIdentification extends Identification{ + + /// + /// FPD file + /// + private File fpdFile; + + /** + @param guid Guid + @param version Version + **/ + public PlatformIdentification(String guid, String version){ + super(guid, version); + } + + /** + @param name Name + @param guid Guid + @param version Version + **/ + public PlatformIdentification(String name, String guid, String version){ + super(name, guid, version); + } + + /** + @param name Name + @param guid Guid + @param version Version + @param fpdFilename Fpd File Name + **/ + public PlatformIdentification(String name, String guid, String version, String fpdFilename){ + super(name, guid, version); + this.fpdFile = new File(fpdFilename); + } + + /** + @param name Name + @param guid Guid + @param version Version + @param fpdFile Fpd File + **/ + public PlatformIdentification(String name, String guid, String version, File fpdFile){ + super(name, guid, version); + this.fpdFile = fpdFile; + } + + public String toString(){ + return "Platform " + name + "["+guid+"]"; + } + + /** + Set FPD file. + @param fpdFile FPD File + **/ + public void setFpdFile(File fpdFile) { + this.fpdFile = fpdFile; + } + + /** + Get FPD file. + @return Fpd File + **/ + public File getFpdFile() { + return fpdFile; + } + + /** + Get FPD relative file to workspace. + @return Fpd Relative file. + **/ + public String getRelativeFpdFile (){ + String relativeDir = fpdFile.getPath().substring(GlobalData.getWorkspacePath().length()); + if(relativeDir.startsWith("\\") || relativeDir.startsWith("/")) { + relativeDir = relativeDir.substring(1); + } + return relativeDir; + } + + /** + Get Platform relative directory to workspace. + @return Platform relative directory + **/ + public String getPlatformRelativeDir(){ + String relativeDir = fpdFile.getParent().substring(GlobalData.getWorkspacePath().length()); + if(relativeDir.startsWith("\\") || relativeDir.startsWith("/")) { + relativeDir = relativeDir.substring(1); + } + return relativeDir; + } +} \ No newline at end of file diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java b/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java new file mode 100644 index 0000000000..a2f1c6a1bf --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java @@ -0,0 +1,384 @@ +/** @file + PCDAutoGenAction class. + + This class is to manage how to generate the PCD information into Autogen.c and + Autogen.h. + +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.pcd.action; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.tianocore.build.FrameworkBuildTask; +import org.tianocore.build.autogen.CommonDefinition; +import org.tianocore.build.global.GlobalData; +import org.tianocore.build.id.ModuleIdentification; +import org.tianocore.common.logger.EdkLog; +import org.tianocore.pcd.action.BuildAction; +import org.tianocore.pcd.entity.MemoryDatabaseManager; +import org.tianocore.pcd.entity.Token; +import org.tianocore.pcd.entity.UsageIdentification; +import org.tianocore.pcd.entity.UsageInstance; +import org.tianocore.pcd.exception.BuildActionException; + +/** + This class is to manage how to generate the PCD information into Autogen.c + and Autogen.h. +**/ +public class PCDAutoGenAction extends BuildAction { + /// + /// The reference of DBManager in GlobalData class. + /// + private MemoryDatabaseManager dbManager; + + /// + /// The identification for a UsageInstance. + /// + private UsageIdentification usageId; + + /// + /// Whether current autogen is for building library used by current module. + /// + private boolean isBuildUsedLibrary; + + /// + /// One of PEI_PCD_DRIVER, DXE_PCD_DRIVER, NOT_PCD_DRIVER + /// + private CommonDefinition.PCD_DRIVER_TYPE pcdDriverType; + + /// + /// The generated string for header file. + /// + private String hAutoGenString; + + /// + /// The generated string for C code file. + /// + private String cAutoGenString; + + /// + /// The name array of in a module. + /// + private String[] pcdNameArrayInMsa; + + private UsageIdentification parentId = null; + /** + Set parameter moduleId + + @param moduleName the module name parameter. + **/ + public void setUsageId(UsageIdentification usageId) { + this.usageId = usageId; + } + + /** + Set paramter pcdDriverType + + @param pcdDriverType the driver type for PCD + **/ + public void setPcdDriverType(CommonDefinition.PCD_DRIVER_TYPE pcdDriverType) { + this.pcdDriverType = pcdDriverType; + } + /** + set isBuildUsedLibrary parameter. + + @param isBuildUsedLibrary + **/ + public void setIsBuildUsedLibrary(boolean isBuildUsedLibrary) { + this.isBuildUsedLibrary = isBuildUsedLibrary; + } + + /** + set pcdNameArrayInMsa parameter. + + @param pcdNameArrayInMsa + */ + public void setPcdNameArrayInMsa(String[] pcdNameArrayInMsa) { + this.pcdNameArrayInMsa = pcdNameArrayInMsa; + } + + /** + Get the output of generated string for header file. + + @return the string of header file for PCD + **/ + public String getHAutoGenString() { + return hAutoGenString; + } + + /** + Get the output of generated string for C Code file. + + @return the string of C code file for PCD + **/ + public String getCAutoGenString() { + return cAutoGenString; + } + + + /** + Construct function + + This function mainly initialize some member variable. + + @param moduleId the identification for module + @param arch the architecture for module + @param isBuildUsedLibary Is the current module library. + @param pcdNameArrayInMsa the pcd name array got from MSA file. + @param pcdDriverType one of PEI_PCD_DRIVER, DXE_PCD_DRIVER, + NOT_PCD_DRIVER + **/ + public PCDAutoGenAction(ModuleIdentification moduleId, + String arch, + boolean isBuildUsedLibrary, + String[] pcdNameArrayInMsa, + CommonDefinition.PCD_DRIVER_TYPE pcdDriverType, + ModuleIdentification parentId) { + dbManager = null; + hAutoGenString = ""; + cAutoGenString = ""; + + setUsageId(new UsageIdentification(moduleId.getName(), + moduleId.getGuid(), + moduleId.getPackage().getName(), + moduleId.getPackage().getGuid(), + arch, + moduleId.getVersion(), + moduleId.getModuleType())); + if (parentId != null) { + this.parentId = new UsageIdentification(parentId.getName(), + parentId.getGuid(), + parentId.getPackage().getName(), + parentId.getPackage().getGuid(), + arch, + parentId.getVersion(), + parentId.getModuleType()); + } + setIsBuildUsedLibrary(isBuildUsedLibrary); + setPcdNameArrayInMsa(pcdNameArrayInMsa); + setPcdDriverType(pcdDriverType); + } + + /** + Override function: check the parameter for action class. + + @throws BuildActionException Bad parameter. + **/ + public void checkParameter() { + } + + /** + Core execution function for this action class. + + All PCD information of this module comes from memory dabase. The collection + work should be done before this action execution. + Currently, we should generated all PCD information(maybe all dynamic) as array + in Pei emulated driver for simulating PCD runtime database. + + @throws BuildActionException Failed to execute this aciton class. + **/ + public void performAction() { + EdkLog.log(EdkLog.EDK_DEBUG, "Starting PCDAutoGenAction to generate autogen.h and autogen.c!..."); + + dbManager = GlobalData.getPCDMemoryDBManager(); + + if(dbManager.getDBSize() == 0) { + return; + } + + EdkLog.log(EdkLog.EDK_DEBUG, "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens."); + + generateAutogenForModule(); + } + + /** + Generate the autogen string for a common module. + + All PCD information of this module comes from memory dabase. The collection + work should be done before this action execution. + **/ + private void generateAutogenForModule() + { + int index, index2; + List usageInstanceArray, usageContext; + String[] guidStringArray = null; + String guidStringCName = null; + String guidString = null; + String moduleName = usageId.moduleName; + UsageInstance usageInstance = null; + boolean found = false; + + usageInstanceArray = null; + + if (FrameworkBuildTask.multithread) { + if (parentId == null) { + usageInstanceArray = dbManager.getUsageInstanceArrayById(usageId); + } else if ((pcdNameArrayInMsa != null) && (pcdNameArrayInMsa.length > 0)) { + usageContext = dbManager.getUsageInstanceArrayById(parentId); + // + // For building library package, although all module are library, but PCD entries of + // these library should be used to autogen. + // + if (usageContext == null) { + usageInstanceArray = dbManager.getUsageInstanceArrayById(usageId); + } else { + usageInstanceArray = new ArrayList(); + + // + // Try to find all PCD defined in library's PCD in all in module's + // in FPD file. + // + for (index = 0; index < pcdNameArrayInMsa.length; index++) { + found = false; + for (index2 = 0; index2 < usageContext.size(); index2 ++) { + if (pcdNameArrayInMsa[index].equalsIgnoreCase(usageContext.get(index2).parentToken.cName)) { + usageInstanceArray.add(usageContext.get(index2)); + found = true; + break; + } + } + + if (!found) { + // + // All library's PCD should instanted in module's who + // use this library instance. If not, give errors. + // + throw new BuildActionException (String.format("Module %s using library instance %s; the PCD %s " + + "is required by this library instance, but can not be found " + + "in the %s's in the FPD file!", + MemoryDatabaseManager.CurrentModuleName, + moduleName, + pcdNameArrayInMsa[index], + MemoryDatabaseManager.CurrentModuleName + )); + } + } + } + } + } else { + if (!isBuildUsedLibrary) { + usageInstanceArray = dbManager.getUsageInstanceArrayById(usageId); + MemoryDatabaseManager.UsageInstanceContext = usageInstanceArray; + MemoryDatabaseManager.CurrentModuleName = moduleName; + } else if ((pcdNameArrayInMsa != null) && (pcdNameArrayInMsa.length > 0)) { + usageContext = MemoryDatabaseManager.UsageInstanceContext; + // + // For building library package, although all module are library, but PCD entries of + // these library should be used to autogen. + // + if (usageContext == null) { + usageInstanceArray = dbManager.getUsageInstanceArrayById(usageId); + } else { + usageInstanceArray = new ArrayList(); + + // + // Try to find all PCD defined in library's PCD in all in module's + // in FPD file. + // + for (index = 0; index < pcdNameArrayInMsa.length; index++) { + found = false; + for (index2 = 0; index2 < usageContext.size(); index2 ++) { + if (pcdNameArrayInMsa[index].equalsIgnoreCase(usageContext.get(index2).parentToken.cName)) { + usageInstanceArray.add(usageContext.get(index2)); + found = true; + break; + } + } + + if (!found) { + // + // All library's PCD should instanted in module's who + // use this library instance. If not, give errors. + // + throw new BuildActionException (String.format("Module %s using library instance %s; the PCD %s " + + "is required by this library instance, but can not be found " + + "in the %s's in the FPD file!", + MemoryDatabaseManager.CurrentModuleName, + moduleName, + pcdNameArrayInMsa[index], + MemoryDatabaseManager.CurrentModuleName + )); + } + } + } + } + } + if (usageInstanceArray == null) { + return; + } + + // + // Generate all PCD entry for a module. + // + for(index = 0; index < usageInstanceArray.size(); index ++) { + usageInstance = usageInstanceArray.get(index); + // + // Before generate any PCD information into autogen.h/autogen.c for a module, + // generate TokenSpaceGuid array variable firstly. For every dynamicEx type + // PCD in this module the token, they are all reference to TokenSpaceGuid + // array. + // + if (usageInstanceArray.get(index).modulePcdType == Token.PCD_TYPE.DYNAMIC_EX) { + guidStringArray = usageInstance.parentToken.tokenSpaceName.split("-"); + guidStringCName = "_gPcd_TokenSpaceGuid_" + + usageInstance.parentToken.tokenSpaceName.replaceAll("-", "_"); + guidString = String.format("{ 0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}", + guidStringArray[0], + guidStringArray[1], + guidStringArray[2], + (guidStringArray[3].substring(0, 2)), + (guidStringArray[3].substring(2, 4)), + (guidStringArray[4].substring(0, 2)), + (guidStringArray[4].substring(2, 4)), + (guidStringArray[4].substring(4, 6)), + (guidStringArray[4].substring(6, 8)), + (guidStringArray[4].substring(8, 10)), + (guidStringArray[4].substring(10, 12))); + + Pattern pattern = Pattern.compile("(" + guidStringCName + ")+?"); + Matcher matcher = pattern.matcher(cAutoGenString + " "); + // + // Find whether this guid array variable has been generated into autogen.c + // For different DyanmicEx pcd token who use same token space guid, the token space + // guid array should be only generated once. + // + if (!matcher.find()) { + hAutoGenString += String.format("extern EFI_GUID %s;\r\n", guidStringCName); + if (!isBuildUsedLibrary) { + cAutoGenString += String.format("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID %s = %s;\r\n", + guidStringCName, + guidString); + } + } + } + + usageInstance.generateAutoGen(isBuildUsedLibrary); + // + // For every PCD entry for this module(usage instance), autogen string would + // be appand. + // + hAutoGenString += usageInstance.getHAutogenStr() + "\r\n"; + cAutoGenString += usageInstance.getCAutogenStr(); + } + + if (pcdDriverType == CommonDefinition.PCD_DRIVER_TYPE.PEI_PCD_DRIVER) { + hAutoGenString += MemoryDatabaseManager.PcdPeimHString; + cAutoGenString += MemoryDatabaseManager.PcdPeimCString; + } else if (pcdDriverType == CommonDefinition.PCD_DRIVER_TYPE.DXE_PCD_DRIVER) { + hAutoGenString += MemoryDatabaseManager.PcdDxeHString; + cAutoGenString += MemoryDatabaseManager.PcdDxeCString; + } + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PcdDatabase.java b/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PcdDatabase.java new file mode 100644 index 0000000000..70adb9a6af --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PcdDatabase.java @@ -0,0 +1,1740 @@ +/** @file + PcdDatabase class. + +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.pcd.action; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.tianocore.pcd.entity.DynamicTokenValue; +import org.tianocore.pcd.entity.Token; +import org.tianocore.pcd.exception.EntityException; + +/** + CStructTypeDeclaration + + This class is used to store the declaration string, such as + "UINT32 PcdPlatformFlashBaseAddress", of + each memember in the C structure, which is a standard C language + feature used to implement a simple and efficient database for + dynamic(ex) type PCD entry. +**/ +class CStructTypeDeclaration { + String key; + int alignmentSize; + String cCode; + boolean initTable; + + public CStructTypeDeclaration (String key, int alignmentSize, String cCode, boolean initTable) { + this.key = key; + this.alignmentSize = alignmentSize; + this.cCode = cCode; + this.initTable = initTable; + } +} + +/** + StringTable + + This class is used to store the String in a PCD database. + +**/ +class StringTable { + class UnicodeString { + // + // In Schema, we define VariableName in DynamicPcdBuildDefinitions in FPD + // file to be HexWordArrayType. For example, Unicode String L"Setup" is + // 0x0053 0x0065 0x0074 0x0075 0x0070. + // We use raw to differentiate if the String is in form of L"Setup" (raw is false) or + // in form of {0x0053, 0x0065, 0x0074, 0x0075, 0x0070} + // + // This str is the string that can be pasted directly into the C structure. + // For example, this str can be two forms: + // + // L"Setup", + // {0x0053, 0065, 0x0074, 0x0075, 0x0070, 0x0000}, //This is another form of L"Setup" + // + public String str; + // + // This len includes the NULL character at the end of the String. + // + public int len; + + public UnicodeString (String str, int len) { + this.str = str; + this.len = len; + } + } + + private ArrayList al; + private ArrayList alComments; + private String phase; + int stringTableCharNum; + + public StringTable (String phase) { + this.phase = phase; + al = new ArrayList(); + alComments = new ArrayList(); + stringTableCharNum = 0; + } + + public String getSizeMacro () { + return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize()); + } + + private int getSize () { + // + // We have at least one Unicode Character in the table. + // + return stringTableCharNum == 0 ? 1 : stringTableCharNum; + } + + public String getExistanceMacro () { + return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE"); + } + + public void genCode (ArrayList declaList, HashMap instTable) { + final String stringTable = "StringTable"; + final String tab = "\t"; + final String newLine = "\r\n"; + final String commaNewLine = ",\r\n"; + + CStructTypeDeclaration decl; + + String cDeclCode = ""; + String cInstCode = ""; + + // + // If we have a empty StringTable + // + if (al.size() == 0) { + cDeclCode += String.format("%-20s%s[1]; /* StringTable is empty */", "UINT16", stringTable) + newLine; + decl = new CStructTypeDeclaration ( + stringTable, + 2, + cDeclCode, + true + ); + declaList.add(decl); + + cInstCode = String.format("/* %s */", stringTable) + newLine + tab + "{ 0 }"; + instTable.put(stringTable, cInstCode); + } else { + + // + // If there is any String in the StringTable + // + for (int i = 0; i < al.size(); i++) { + UnicodeString uStr = al.get(i); + String stringTableName; + + if (i == 0) { + // + // StringTable is a well-known name in the PCD DXE driver + // + stringTableName = stringTable; + + } else { + stringTableName = String.format("%s_%d", stringTable, i); + cDeclCode += tab; + } + cDeclCode += String.format("%-20s%s[%d]; /* %s */", "UINT16", + stringTableName, uStr.len, + alComments.get(i)) + + newLine; + + if (i == 0) { + cInstCode = "/* StringTable */" + newLine; + } + + cInstCode += tab + String.format("%s /* %s */", uStr.str, alComments.get(i)); + if (i != al.size() - 1) { + cInstCode += commaNewLine; + } + } + + decl = new CStructTypeDeclaration ( + stringTable, + 2, + cDeclCode, + true + ); + declaList.add(decl); + + instTable.put(stringTable, cInstCode); + } + } + + public int add (List inputStr, Token token) { + String str; + + str = "{"; + + for (int i = 0; i < inputStr.size(); i++) { + str += " " + inputStr.get(i) + ","; + } + + str += " 0x0000"; + + str += "}"; + // + // This is a raw Unicode String + // + return addToTable (str, inputStr.size() + 1, token); + } + + public int add (String inputStr, Token token) { + + int len; + String str = inputStr; + + // + // The input can be two types: + // "L\"Bootmode\"" or "Bootmode". + // We drop the L\" and \" for the first type. + if (str.startsWith("L\"") && str.endsWith("\"")) { + // + // Substract the character of "L", """, """. + // and add in the NULL character. So it is 2. + // + len = str.length() - 2; + } else { + // + // Include the NULL character. + // + len = str.length() + 1; + str = "L\"" + str + "\""; + } + + // + // After processing, this is L"A String Sample" type of string. + // + return addToTable (str, len, token); + } + + private int addToTable (String inputStr, int len, Token token) { + int i; + int pos; + + // + // Check if StringTable has this String already. + // If so, return the current pos. + // + for (i = 0, pos = 0; i < al.size(); i++) { + UnicodeString s = al.get(i);; + + if (inputStr.equals(s.str)) { + return pos; + } + pos += s.len; + } + + i = stringTableCharNum; + // + // Include the NULL character at the end of String + // + stringTableCharNum += len; + al.add(new UnicodeString(inputStr, len)); + alComments.add(token.getPrimaryKeyString()); + + return i; + } +} + +/** + SizeTable + + This class is used to store the Size information for + POINTER TYPE PCD entry in a PCD database. + +**/ +class SizeTable { + private ArrayList> al; + private ArrayList alComments; + private int len; + private String phase; + + public SizeTable (String phase) { + al = new ArrayList>(); + alComments = new ArrayList(); + len = 0; + this.phase = phase; + } + + public String getSizeMacro () { + return String.format(PcdDatabase.SizeTableSizeMacro, phase, getSize()); + } + + private int getSize() { + return len == 0 ? 1 : len; + } + + public void genCode (ArrayList declaList, HashMap instTable, String phase) { + final String name = "SizeTable"; + + CStructTypeDeclaration decl; + String cCode; + + cCode = String.format(PcdDatabase.SizeTableDeclaration, phase); + decl = new CStructTypeDeclaration ( + name, + 2, + cCode, + true + ); + declaList.add(decl); + + + cCode = PcdDatabase.genInstantiationStr(getInstantiation()); + instTable.put(name, cCode); + } + + private ArrayList getInstantiation () { + final String comma = ","; + ArrayList Output = new ArrayList(); + + Output.add("/* SizeTable */"); + Output.add("{"); + if (al.size() == 0) { + Output.add("\t0"); + } else { + for (int index = 0; index < al.size(); index++) { + ArrayList ial = al.get(index); + + String str = "\t"; + + for (int index2 = 0; index2 < ial.size(); index2++) { + str += " " + ial.get(index2).toString(); + if (index2 != ial.size() - 1) { + str += comma; + } + } + + str += " /* " + alComments.get(index) + " */"; + + if (index != (al.size() - 1)) { + str += comma; + } + + Output.add(str); + + } + } + Output.add("}"); + + return Output; + } + + public void add (Token token) { + + // + // We only have size information for POINTER type PCD entry. + // + if (token.datumType != Token.DATUM_TYPE.POINTER) { + return; + } + + ArrayList ial = token.getPointerTypeSize(); + + len+= ial.size(); + + al.add(ial); + alComments.add(token.getPrimaryKeyString()); + + return; + } + +} + +/** + GuidTable + + This class is used to store the GUIDs in a PCD database. +**/ +class GuidTable { + private ArrayList al; + private ArrayList alComments; + private String phase; + private int len; + private int bodyLineNum; + + public GuidTable (String phase) { + this.phase = phase; + al = new ArrayList(); + alComments = new ArrayList(); + len = 0; + bodyLineNum = 0; + } + + public String getSizeMacro () { + return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize()); + } + + private int getSize () { + return (al.size() == 0)? 1 : al.size(); + } + + public String getExistanceMacro () { + return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE"); + } + + public void genCode (ArrayList declaList, HashMap instTable, String phase) { + final String name = "GuidTable"; + + CStructTypeDeclaration decl; + String cCode = ""; + + cCode += String.format(PcdDatabase.GuidTableDeclaration, phase); + decl = new CStructTypeDeclaration ( + name, + 4, + cCode, + true + ); + declaList.add(decl); + + + cCode = PcdDatabase.genInstantiationStr(getInstantiation()); + instTable.put(name, cCode); + } + + private String getUuidCString (UUID uuid) { + String[] guidStrArray; + + guidStrArray =(uuid.toString()).split("-"); + + return String.format("{0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}", + guidStrArray[0], + guidStrArray[1], + guidStrArray[2], + (guidStrArray[3].substring(0, 2)), + (guidStrArray[3].substring(2, 4)), + (guidStrArray[4].substring(0, 2)), + (guidStrArray[4].substring(2, 4)), + (guidStrArray[4].substring(4, 6)), + (guidStrArray[4].substring(6, 8)), + (guidStrArray[4].substring(8, 10)), + (guidStrArray[4].substring(10, 12)) + ); + } + + private ArrayList getInstantiation () { + ArrayList Output = new ArrayList(); + + Output.add("/* GuidTable */"); + Output.add("{"); + + if (al.size() == 0) { + Output.add("\t" + getUuidCString(new UUID(0, 0))); + } + + for (int i = 0; i < al.size(); i++) { + String str = "\t" + getUuidCString(al.get(i)); + + str += "/* " + alComments.get(i) + " */"; + if (i != (al.size() - 1)) { + str += ","; + } + Output.add(str); + bodyLineNum++; + + } + Output.add("}"); + + return Output; + } + + public int add (UUID uuid, String name) { + // + // Check if GuidTable has this entry already. + // If so, return the GuidTable index. + // + for (int i = 0; i < al.size(); i++) { + if (al.get(i).compareTo(uuid) == 0) { + return i; + } + } + + len++; + al.add(uuid); + alComments.add(name); + + // + // Return the previous Table Index + // + return len - 1; + } + +} + +/** + SkuIdTable + + This class is used to store the SKU IDs in a PCD database. + +**/ +class SkuIdTable { + private ArrayList al; + private ArrayList alComment; + private String phase; + private int len; + + public SkuIdTable (String phase) { + this.phase = phase; + al = new ArrayList(); + alComment = new ArrayList(); + len = 0; + } + + public String getSizeMacro () { + return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize()); + } + + private int getSize () { + return (len == 0)? 1 : len; + } + + public String getExistanceMacro () { + return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE"); + } + + public void genCode (ArrayList declaList, HashMap instTable, String phase) { + final String name = "SkuIdTable"; + + CStructTypeDeclaration decl; + String cCode = ""; + + cCode += String.format(PcdDatabase.SkuIdTableDeclaration, phase); + decl = new CStructTypeDeclaration ( + name, + 1, + cCode, + true + ); + declaList.add(decl); + + + cCode = PcdDatabase.genInstantiationStr(getInstantiation()); + instTable.put(name, cCode); + + // + // SystemSkuId is in PEI phase PCD Database + // + if (phase.equalsIgnoreCase("PEI")) { + decl = new CStructTypeDeclaration ( + "SystemSkuId", + 1, + String.format("%-20sSystemSkuId;\r\n", "SKU_ID"), + true + ); + declaList.add(decl); + + instTable.put("SystemSkuId", "0"); + } + + } + + private ArrayList getInstantiation () { + ArrayList Output = new ArrayList (); + + Output.add("/* SkuIdTable */"); + Output.add("{"); + + if (al.size() == 0) { + Output.add("\t0"); + } + + for (int index = 0; index < al.size(); index++) { + String str; + + str = "/* " + alComment.get(index) + "*/ "; + str += "/* MaxSku */ "; + + + Integer[] ia = al.get(index); + + str += "\t" + ia[0].toString() + ", "; + for (int index2 = 1; index2 < ia.length; index2++) { + str += ia[index2].toString(); + if (!((index2 == ia.length - 1) && (index == al.size() - 1))) { + str += ", "; + } + } + + Output.add(str); + + } + + Output.add("}"); + + return Output; + } + + public int add (Token token) { + + int index; + int pos; + + // + // Check if this SKU_ID Array is already in the table + // + pos = 0; + for (Object o: al) { + Integer [] s = (Integer[]) o; + boolean different = false; + if (s[0] == token.getSkuIdCount()) { + for (index = 1; index < s.length; index++) { + if (s[index] != token.skuData.get(index-1).id) { + different = true; + break; + } + } + } else { + different = true; + } + if (different) { + pos += s[0] + 1; + } else { + return pos; + } + } + + Integer [] skuIds = new Integer[token.skuData.size() + 1]; + skuIds[0] = new Integer(token.skuData.size()); + for (index = 1; index < skuIds.length; index++) { + skuIds[index] = new Integer(token.skuData.get(index - 1).id); + } + + index = len; + + len += skuIds.length; + al.add(skuIds); + alComment.add(token.getPrimaryKeyString()); + + return index; + } + +} + +class LocalTokenNumberTable { + private ArrayList al; + private ArrayList alComment; + private String phase; + private int len; + + public LocalTokenNumberTable (String phase) { + this.phase = phase; + al = new ArrayList(); + alComment = new ArrayList(); + + len = 0; + } + + public String getSizeMacro () { + return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize()) + + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size()); + } + + public int getSize () { + return (al.size() == 0)? 1 : al.size(); + } + + public String getExistanceMacro () { + return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE"); + } + + public void genCode (ArrayList declaList, HashMap instTable, String phase) { + final String name = "LocalTokenNumberTable"; + + CStructTypeDeclaration decl; + String cCode = ""; + + cCode += String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase); + decl = new CStructTypeDeclaration ( + name, + 4, + cCode, + true + ); + declaList.add(decl); + + cCode = PcdDatabase.genInstantiationStr(getInstantiation()); + instTable.put(name, cCode); + } + + private ArrayList getInstantiation () { + ArrayList output = new ArrayList(); + + output.add("/* LocalTokenNumberTable */"); + output.add("{"); + + if (al.size() == 0) { + output.add("\t0"); + } + + for (int index = 0; index < al.size(); index++) { + String str; + + str = "\t" + (String)al.get(index); + + str += " /* " + alComment.get(index) + " */ "; + + + if (index != (al.size() - 1)) { + str += ","; + } + + output.add(str); + + } + + output.add("}"); + + return output; + } + + public int add (Token token) { + int index = len; + String str; + + len++; + + str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString()); + + if (token.isUnicodeStringType()) { + str += " | PCD_TYPE_STRING"; + } + + if (token.isSkuEnable()) { + str += " | PCD_TYPE_SKU_ENABLED"; + } + + if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) { + str += " | PCD_TYPE_HII"; + } + + if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) { + str += " | PCD_TYPE_VPD"; + } + + switch (token.datumType) { + case UINT8: + case BOOLEAN: + str += " | PCD_DATUM_TYPE_UINT8"; + break; + case UINT16: + str += " | PCD_DATUM_TYPE_UINT16"; + break; + case UINT32: + str += " | PCD_DATUM_TYPE_UINT32"; + break; + case UINT64: + str += " | PCD_DATUM_TYPE_UINT64"; + break; + case POINTER: + str += " | PCD_DATUM_TYPE_POINTER"; + break; + } + + al.add(str); + alComment.add(token.getPrimaryKeyString()); + + return index; + } +} + +/** + ExMapTable + + This class is used to store the table of mapping information + between DynamicEX ID pair(Guid, TokenNumber) and + the local token number assigned by PcdDatabase class. +**/ +class ExMapTable { + + /** + ExTriplet + + This class is used to store the mapping information + between DynamicEX ID pair(Guid, TokenNumber) and + the local token number assigned by PcdDatabase class. + **/ + class ExTriplet { + public Integer guidTableIdx; + public Long exTokenNumber; + public Long localTokenIdx; + + public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) { + this.guidTableIdx = new Integer(guidTableIdx); + this.exTokenNumber = new Long(exTokenNumber); + this.localTokenIdx = new Long(localTokenIdx); + } + } + + private ArrayList al; + private Map alComment; + private String phase; + private int len; + private int bodyLineNum; + + public ExMapTable (String phase) { + this.phase = phase; + al = new ArrayList(); + alComment = new HashMap(); + bodyLineNum = 0; + len = 0; + } + + public String getSizeMacro () { + return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen()) + + String.format(PcdDatabase.ExTokenNumber, phase, al.size()); + } + + public String getExistanceMacro () { + return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE"); + } + + public void genCode (ArrayList declaList, HashMap instTable, String phase) { + final String exMapTableName = "ExMapTable"; + + sortTable(); + + CStructTypeDeclaration decl; + String cCode = ""; + + cCode += String.format(PcdDatabase.ExMapTableDeclaration, phase); + decl = new CStructTypeDeclaration ( + exMapTableName, + 4, + cCode, + true + ); + declaList.add(decl); + + + cCode = PcdDatabase.genInstantiationStr(getInstantiation()); + instTable.put(exMapTableName, cCode); + } + + private ArrayList getInstantiation () { + ArrayList Output = new ArrayList(); + + Output.add("/* ExMapTable */"); + Output.add("{"); + if (al.size() == 0) { + Output.add("\t{0, 0, 0}"); + } + + int index; + for (index = 0; index < al.size(); index++) { + String str; + + ExTriplet e = (ExTriplet)al.get(index); + + str = "\t" + "{ " + String.format("0x%08X", e.exTokenNumber) + ", "; + str += e.localTokenIdx.toString() + ", "; + str += e.guidTableIdx.toString(); + + str += "}" + " /* " + alComment.get(e) + " */" ; + + if (index != al.size() - 1) { + str += ","; + } + + Output.add(str); + bodyLineNum++; + + } + + Output.add("}"); + + return Output; + } + + public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) { + int index = len; + + len++; + ExTriplet et = new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx); + + al.add(et); + alComment.put(et, name); + + return index; + } + + private int getTableLen () { + return al.size() == 0 ? 1 : al.size(); + } + + // + // To simplify the algorithm for GetNextToken and GetNextTokenSpace in + // PCD PEIM/Driver, we need to sort the ExMapTable according to the + // following order: + // 1) ExGuid + // 2) ExTokenNumber + // + class ExTripletComp implements Comparator { + public int compare (ExTriplet a, ExTriplet b) { + if (a.guidTableIdx == b.guidTableIdx ) { + // + // exTokenNumber is long, we can't use simple substraction. + // + if (a.exTokenNumber > b.exTokenNumber) { + return 1; + } else if (a.exTokenNumber == b.exTokenNumber) { + return 0; + } else { + return -1; + } + } + + return a.guidTableIdx - b.guidTableIdx; + } + } + + private void sortTable () { + java.util.Comparator comparator = new ExTripletComp(); + java.util.Collections.sort(al, comparator); + } +} + +/** + PcdDatabase + + This class is used to generate C code for Autogen.h and Autogen.c of + a PCD service DXE driver and PCD service PEIM. +**/ +public class PcdDatabase { + + private final static int SkuHeadAlignmentSize = 4; + private final String newLine = "\r\n"; + private final String commaNewLine = ",\r\n"; + private final String tab = "\t"; + public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n"; + public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n"; + public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n"; + public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n"; + public final static String SizeTableDeclaration = "SIZE_INFO SizeTable[%s_SIZE_TABLE_SIZE];\r\n"; + public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n"; + + + public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n"; + public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n"; + public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n"; + public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n"; + public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n"; + public final static String SizeTableSizeMacro = "#define %s_SIZE_TABLE_SIZE %d\r\n"; + public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n"; + public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n"; + + + public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n"; + public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n"; + public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n"; + public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n"; + public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n"; + + public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)"; + public final static String offsetOfVariableEnabledDefault = "offsetof(%s_PCD_DATABASE, %s.%s_VariableDefault_%d)"; + public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)"; + + private final static String skuDataTableTemplate = "SkuDataTable"; + + + private StringTable stringTable; + private GuidTable guidTable; + private LocalTokenNumberTable localTokenNumberTable; + private SkuIdTable skuIdTable; + private SizeTable sizeTable; + private ExMapTable exMapTable; + + private ArrayList alTokens; + private String phase; + private int assignedTokenNumber; + + // + // Use two class global variable to store + // temperary + // + private String privateGlobalName; + private String privateGlobalCCode; + // + // After Major changes done to the PCD + // database generation class PcdDatabase + // Please increment the version and please + // also update the version number in PCD + // service PEIM and DXE driver accordingly. + // + private final int version = 2; + + private String hString; + private String cString; + + /** + Constructor for PcdDatabase class. + +

We have two PCD dynamic(ex) database for the Framework implementation. One + for PEI phase and the other for DXE phase.

+ + @param alTokens A ArrayList of Dynamic(EX) PCD entry. + @param exePhase The phase to generate PCD database for: valid input + is "PEI" or "DXE". + @param startLen The starting Local Token Number for the PCD database. For + PEI phase, the starting Local Token Number starts from 0. + For DXE phase, the starting Local Token Number starts + from the total number of PCD entry of PEI phase. + @return void + **/ + public PcdDatabase (ArrayList alTokens, String exePhase, int startLen) { + phase = exePhase; + + stringTable = new StringTable(phase); + guidTable = new GuidTable(phase); + localTokenNumberTable = new LocalTokenNumberTable(phase); + skuIdTable = new SkuIdTable(phase); + sizeTable = new SizeTable(phase); + exMapTable = new ExMapTable(phase); + + // + // Local token number 0 is reserved for INVALID_TOKEN_NUMBER. + // So we will increment 1 for the startLen passed from the + // constructor. + // + assignedTokenNumber = startLen + 1; + this.alTokens = alTokens; + } + + private void getNonExAndExTokens (ArrayList alTokens, List nexTokens, List exTokens) { + for (int i = 0; i < alTokens.size(); i++) { + Token t = (Token)alTokens.get(i); + if (t.isDynamicEx()) { + exTokens.add(t); + } else { + nexTokens.add(t); + } + } + + return; + } + + private int getDataTypeAlignmentSize (Token token) { + switch (token.datumType) { + case UINT8: + return 1; + case UINT16: + return 2; + case UINT32: + return 4; + case UINT64: + return 8; + case POINTER: + return 1; + case BOOLEAN: + return 1; + default: + return 1; + } + } + + private int getHiiPtrTypeAlignmentSize(Token token) { + switch (token.datumType) { + case UINT8: + return 1; + case UINT16: + return 2; + case UINT32: + return 4; + case UINT64: + return 8; + case POINTER: + if (token.isHiiEnable()) { + if (token.isHiiDefaultValueUnicodeStringType()) { + return 2; + } + } + return 1; + case BOOLEAN: + return 1; + default: + return 1; + } + } + + private int getAlignmentSize (Token token) { + if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) { + return 2; + } + + if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) { + return 4; + } + + if (token.isUnicodeStringType()) { + return 2; + } + + return getDataTypeAlignmentSize(token); + } + + public String getCString () { + return cString; + } + + public String getHString () { + return hString; + } + + private void genCodeWorker(Token t, + ArrayList declaList, + HashMap instTable, String phase) + throws EntityException { + + CStructTypeDeclaration decl; + + // + // Insert SKU_HEAD if isSkuEnable is true + // + if (t.isSkuEnable()) { + int tableIdx; + tableIdx = skuIdTable.add(t); + decl = new CStructTypeDeclaration(t.getPrimaryKeyString(), + SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true); + declaList.add(decl); + instTable.put(t.getPrimaryKeyString(), + getSkuEnabledTypeInstantiaion(t, tableIdx)); + } + + // + // Insert PCD_ENTRY declaration and instantiation + // + getCDeclarationString(t); + + decl = new CStructTypeDeclaration(privateGlobalName, + getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue()); + declaList.add(decl); + + if (t.hasDefaultValue()) { + instTable.put(privateGlobalName, + getTypeInstantiation(t, declaList, instTable, phase) + ); + } + + } + + private void ProcessTokens (List tokens, + ArrayList cStructDeclList, + HashMap cStructInstTable, + String phase + ) + throws EntityException { + + for (int idx = 0; idx < tokens.size(); idx++) { + Token t = tokens.get(idx); + + genCodeWorker (t, cStructDeclList, cStructInstTable, phase); + + sizeTable.add(t); + localTokenNumberTable.add(t); + t.tokenNumber = assignedTokenNumber++; + + // + // Add a mapping if this dynamic PCD entry is a EX type + // + if (t.isDynamicEx()) { + exMapTable.add((int)t.tokenNumber, + t.dynamicExTokenNumber, + guidTable.add(translateSchemaStringToUUID(t.tokenSpaceName), t.getPrimaryKeyString()), + t.getPrimaryKeyString() + ); + } + } + + } + + public void genCode () throws EntityException { + + ArrayList cStructDeclList = new ArrayList(); + HashMap cStructInstTable = new HashMap(); + + List nexTokens = new ArrayList (); + List exTokens = new ArrayList (); + + getNonExAndExTokens (alTokens, nexTokens, exTokens); + + // + // We have to process Non-Ex type PCD entry first. The reason is + // that our optimization assumes that the Token Number of Non-Ex + // PCD entry start from 1 (for PEI phase) and grows continously upwards. + // + // EX type token number starts from the last Non-EX PCD entry and + // grows continously upwards. + // + ProcessTokens (nexTokens, cStructDeclList, cStructInstTable, phase); + ProcessTokens (exTokens, cStructDeclList, cStructInstTable, phase); + + stringTable.genCode(cStructDeclList, cStructInstTable); + skuIdTable.genCode(cStructDeclList, cStructInstTable, phase); + exMapTable.genCode(cStructDeclList, cStructInstTable, phase); + localTokenNumberTable.genCode(cStructDeclList, cStructInstTable, phase); + sizeTable.genCode(cStructDeclList, cStructInstTable, phase); + guidTable.genCode(cStructDeclList, cStructInstTable, phase); + + hString = genCMacroCode (); + + HashMap result; + + result = genCStructCode(cStructDeclList, + cStructInstTable, + phase + ); + + hString += result.get("initDeclStr"); + hString += result.get("uninitDeclStr"); + + hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version); + + cString = newLine + newLine + result.get("initInstStr"); + + } + + private String genCMacroCode () { + String macroStr = ""; + + // + // Generate size info Macro for all Tables + // + macroStr += guidTable.getSizeMacro(); + macroStr += stringTable.getSizeMacro(); + macroStr += skuIdTable.getSizeMacro(); + macroStr += localTokenNumberTable.getSizeMacro(); + macroStr += exMapTable.getSizeMacro(); + macroStr += sizeTable.getSizeMacro(); + + // + // Generate existance info Macro for all Tables + // + macroStr += guidTable.getExistanceMacro(); + macroStr += stringTable.getExistanceMacro(); + macroStr += skuIdTable.getExistanceMacro(); + macroStr += localTokenNumberTable.getExistanceMacro(); + macroStr += exMapTable.getExistanceMacro(); + + macroStr += newLine; + + return macroStr; + } + + private HashMap genCStructCode( + ArrayList declaList, + HashMap instTable, + String phase + ) { + + int i; + HashMap result = new HashMap(); + HashMap > alignmentInitDecl = new HashMap>(); + HashMap > alignmentUninitDecl = new HashMap>(); + HashMap > alignmentInitInst = new HashMap>(); + + // + // Initialize the storage for each alignment + // + for (i = 8; i > 0; i>>=1) { + alignmentInitDecl.put(new Integer(i), new ArrayList()); + alignmentInitInst.put(new Integer(i), new ArrayList()); + alignmentUninitDecl.put(new Integer(i), new ArrayList()); + } + + String initDeclStr = "typedef struct {" + newLine; + String initInstStr = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine; + String uninitDeclStr = "typedef struct {" + newLine; + + // + // Sort all C declaration and instantiation base on Alignment Size + // + for (Object d : declaList) { + CStructTypeDeclaration decl = (CStructTypeDeclaration) d; + + if (decl.initTable) { + alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode); + alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key)); + } else { + alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode); + } + } + + // + // Generate code for every alignment size + // + boolean uinitDatabaseEmpty = true; + for (int align = 8; align > 0; align >>= 1) { + ArrayList declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align)); + ArrayList instListBasedOnAlignment = alignmentInitInst.get(new Integer(align)); + for (i = 0; i < declaListBasedOnAlignment.size(); i++) { + initDeclStr += tab + declaListBasedOnAlignment.get(i); + initInstStr += tab + instListBasedOnAlignment.get(i); + + // + // We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE + // has a least one data memember with alignment size of 1. So we can + // remove the last "," in the C structure instantiation string. Luckily, + // this is true as both data structure has SKUID_TABLE anyway. + // + if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) { + initInstStr += newLine; + } else { + initInstStr += commaNewLine; + } + } + + declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align)); + + if (declaListBasedOnAlignment.size() != 0) { + uinitDatabaseEmpty = false; + } + + for (Object d : declaListBasedOnAlignment) { + String s = (String)d; + uninitDeclStr += tab + s; + } + } + + if (uinitDatabaseEmpty) { + uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8"); + } + + initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine; + initInstStr += "};" + newLine; + uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine; + + result.put("initDeclStr", initDeclStr); + result.put("initInstStr", initInstStr); + result.put("uninitDeclStr", uninitDeclStr); + + return result; + } + + public static String genInstantiationStr (ArrayList alStr) { + String str = ""; + for (int i = 0; i< alStr.size(); i++) { + if (i != 0) { + str += "\t"; + } + str += alStr.get(i); + if (i != alStr.size() - 1) { + str += "\r\n"; + } + } + + return str; + } + + private String getSkuEnabledTypeDeclaration (Token token) { + return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString()); + } + + private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) { + + String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString()); + return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString()); + } + + private String getDataTypeInstantiationForVariableDefault (Token token, String cName, int skuId) { + return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName); + } + + private String getCType (Token t) + throws EntityException { + + if (t.isHiiEnable()) { + return "VARIABLE_HEAD"; + } + + if (t.isVpdEnable()) { + return "VPD_HEAD"; + } + + if (t.isUnicodeStringType()) { + return "STRING_HEAD"; + } + + switch (t.datumType) { + case UINT64: + return "UINT64"; + case UINT32: + return "UINT32"; + case UINT16: + return "UINT16"; + case UINT8: + return "UINT8"; + case BOOLEAN: + return "BOOLEAN"; + case POINTER: + return "UINT8"; + default: + throw new EntityException("Unknown DatumType in getDataTypeCDeclaration"); + } + } + + // + // privateGlobalName and privateGlobalCCode is used to pass output to caller of getCDeclarationString + // + private void getCDeclarationString(Token t) + throws EntityException { + + if (t.isSkuEnable()) { + privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate); + } else { + privateGlobalName = t.getPrimaryKeyString(); + } + + String type = getCType(t); + if ((t.datumType == Token.DATUM_TYPE.POINTER) && (!t.isHiiEnable()) && (!t.isUnicodeStringType())) { + int bufferSize; + if (t.isASCIIStringType()) { + // + // Build tool will add a NULL string at the end of the ASCII string + // + bufferSize = t.datumSize + 1; + } else { + bufferSize = t.datumSize; + } + privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize); + } else { + privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount()); + } + } + + private String getDataTypeDeclarationForVariableDefault (Token token, String cName, int skuId) + throws EntityException { + + String typeStr; + + if (token.datumType == Token.DATUM_TYPE.UINT8) { + typeStr = "UINT8"; + } else if (token.datumType == Token.DATUM_TYPE.UINT16) { + typeStr = "UINT16"; + } else if (token.datumType == Token.DATUM_TYPE.UINT32) { + typeStr = "UINT32"; + } else if (token.datumType == Token.DATUM_TYPE.UINT64) { + typeStr = "UINT64"; + } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) { + typeStr = "BOOLEAN"; + } else if (token.datumType == Token.DATUM_TYPE.POINTER) { + int size; + if (token.isHiiDefaultValueUnicodeStringType()) { + typeStr = "UINT16"; + // + // Include the NULL charactor + // + size = token.datumSize / 2 + 1; + } else { + typeStr = "UINT8"; + if (token.isHiiDefaultValueASCIIStringType()) { + // + // Include the NULL charactor + // + size = token.datumSize + 1; + } else { + size = token.datumSize; + } + } + return String.format("%-20s%s[%d];\r\n", typeStr, cName, size); + } else { + throw new EntityException("Unknown DATUM_TYPE type in when generating code for VARIABLE_ENABLED PCD entry"); + } + + return String.format("%-20s%s;\r\n", typeStr, cName); + } + + private String getTypeInstantiation (Token t, ArrayList declaList, HashMap instTable, String phase) throws EntityException { + + int i; + + String s; + s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine; + s += tab + "{" + newLine; + + for (i = 0; i < t.skuData.size(); i++) { + if (t.isUnicodeStringType()) { + s += tab + tab + String.format("{ %d }", stringTable.add(t.skuData.get(i).value.value, t)); + } else if (t.isHiiEnable()) { + /* VPD_HEAD definition + typedef struct { + UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID. + UINT16 StringIndex; // Offset in String Table in units of UINT16. + UINT16 Offset; // Offset in Variable + UINT16 DefaultValueOffset; // Offset of the Default Value + } VARIABLE_HEAD ; + */ + String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i); + + s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()), + stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t), + t.skuData.get(i).value.variableOffset, + String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName) + ); + // + // We need to support the default value, so we add the declaration and + // the instantiation for the default value. + // + CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName, + getHiiPtrTypeAlignmentSize(t), + getDataTypeDeclarationForVariableDefault(t, variableDefaultName, i), + true + ); + declaList.add(decl); + instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault (t, variableDefaultName, i)); + } else if (t.isVpdEnable()) { + /* typedef struct { + UINT32 Offset; + } VPD_HEAD; + */ + s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset); + } else { + if (t.isByteStreamType()) { + // + // Byte stream type input has their own "{" "}", so we won't help to insert. + // + s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value); + } else { + s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value); + } + } + + if (i != t.skuData.size() - 1) { + s += commaNewLine; + } else { + s += newLine; + } + + } + + s += tab + "}"; + + return s; + } + + public static String getPcdDatabaseCommonDefinitions () { + + String retStr; + + retStr = "//\r\n"; + retStr += "// The following definition will be generated by build tool\r\n"; + retStr += "//\r\n"; + retStr += "\r\n"; + retStr += "//\r\n"; + retStr += "// Common definitions\r\n"; + retStr += "//\r\n"; + retStr += "typedef UINT8 SKU_ID;\r\n"; + retStr += "\r\n"; + retStr += "#define PCD_TYPE_SHIFT 28\r\n"; + retStr += "\r\n"; + retStr += "#define PCD_TYPE_DATA (0x0 << PCD_TYPE_SHIFT)\r\n"; + retStr += "#define PCD_TYPE_HII (0x8 << PCD_TYPE_SHIFT)\r\n"; + retStr += "#define PCD_TYPE_VPD (0x4 << PCD_TYPE_SHIFT)\r\n"; + retStr += "#define PCD_TYPE_SKU_ENABLED (0x2 << PCD_TYPE_SHIFT)\r\n"; + retStr += "#define PCD_TYPE_STRING (0x1 << PCD_TYPE_SHIFT)\r\n"; + retStr += "\r\n"; + retStr += "#define PCD_TYPE_ALL_SET (PCD_TYPE_DATA | PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING)\r\n"; + retStr += "\r\n"; + retStr += "#define PCD_DATUM_TYPE_SHIFT 24\r\n"; + retStr += "\r\n"; + retStr += "#define PCD_DATUM_TYPE_POINTER (0x0 << PCD_DATUM_TYPE_SHIFT)\r\n"; + retStr += "#define PCD_DATUM_TYPE_UINT8 (0x1 << PCD_DATUM_TYPE_SHIFT)\r\n"; + retStr += "#define PCD_DATUM_TYPE_UINT16 (0x2 << PCD_DATUM_TYPE_SHIFT)\r\n"; + retStr += "#define PCD_DATUM_TYPE_UINT32 (0x4 << PCD_DATUM_TYPE_SHIFT)\r\n"; + retStr += "#define PCD_DATUM_TYPE_UINT64 (0x8 << PCD_DATUM_TYPE_SHIFT)\r\n"; + retStr += "\r\n"; + retStr += "#define PCD_DATUM_TYPE_ALL_SET (PCD_DATUM_TYPE_POINTER | \\\r\n"; + retStr += " PCD_DATUM_TYPE_UINT8 | \\\r\n"; + retStr += " PCD_DATUM_TYPE_UINT16 | \\\r\n"; + retStr += " PCD_DATUM_TYPE_UINT32 | \\\r\n"; + retStr += " PCD_DATUM_TYPE_UINT64)\r\n"; + retStr += "\r\n"; + retStr += "\r\n"; + retStr += "#define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_ALL_SET | PCD_DATUM_TYPE_ALL_SET))\r\n"; + retStr += "\r\n"; + retStr += "typedef struct {\r\n"; + retStr += " UINT32 ExTokenNumber;\r\n"; + retStr += " UINT16 LocalTokenNumber; // PCD Number of this particular platform build\r\n"; + retStr += " UINT16 ExGuidIndex; // Index of GuidTable\r\n"; + retStr += "} DYNAMICEX_MAPPING;\r\n"; + retStr += "\r\n"; + retStr += "\r\n"; + retStr += "typedef struct {\r\n"; + retStr += " UINT32 SkuDataStartOffset; //We have to use offsetof MACRO as we don't know padding done by compiler\r\n"; + retStr += " UINT32 SkuIdTableOffset; //Offset from the PCD_DB\r\n"; + retStr += "} SKU_HEAD;\r\n"; + retStr += "\r\n"; + retStr += "\r\n"; + retStr += "typedef struct {\r\n"; + retStr += " UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.\r\n"; + retStr += " UINT16 StringIndex; // Offset in String Table in units of UINT16.\r\n"; + retStr += " UINT16 Offset; // Offset in Variable\r\n"; + retStr += " UINT16 DefaultValueOffset; // Offset of the Default Value\r\n"; + retStr += "} VARIABLE_HEAD ;\r\n"; + retStr += "\r\n"; + retStr += "\r\n"; + retStr += "typedef struct {\r\n"; + retStr += " UINT32 Offset;\r\n"; + retStr += "} VPD_HEAD;\r\n"; + retStr += "\r\n"; + retStr += "typedef UINT16 STRING_HEAD;\r\n"; + retStr += "\r\n"; + retStr += "typedef UINT16 SIZE_INFO;\r\n"; + retStr += "\r\n"; + retStr += "#define offsetof(s,m) (UINT32) (UINTN) &(((s *)0)->m)\r\n"; + retStr += "\r\n"; + retStr += "\r\n"; + retStr += "\r\n"; + + return retStr; + } + + public static String getPcdDxeDatabaseDefinitions () + throws EntityException { + + String retStr = ""; + + retStr += "\r\n"; + retStr += "typedef struct {\r\n"; + retStr += " DXE_PCD_DATABASE_INIT Init;\r\n"; + retStr += " DXE_PCD_DATABASE_UNINIT Uninit;\r\n"; + retStr += "} DXE_PCD_DATABASE;\r\n"; + retStr += "\r\n"; + retStr += "\r\n"; + retStr += "typedef struct {\r\n"; + retStr += " PEI_PCD_DATABASE PeiDb;\r\n"; + retStr += " DXE_PCD_DATABASE DxeDb;\r\n"; + retStr += "} PCD_DATABASE;\r\n"; + retStr += "\r\n"; + retStr += "#define DXE_NEX_TOKEN_NUMBER (DXE_LOCAL_TOKEN_NUMBER - DXE_EX_TOKEN_NUMBER)\r\n"; + retStr += "\r\n"; + retStr += "#define PCD_TOTAL_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER)\r\n"; + retStr += "\r\n"; + retStr += "\r\n"; + + return retStr; + } + + public static String getPcdPeiDatabaseDefinitions () + throws EntityException { + + String retStr = ""; + + retStr += "\r\n"; + retStr += "typedef struct {\r\n"; + retStr += " PEI_PCD_DATABASE_INIT Init;\r\n"; + retStr += " PEI_PCD_DATABASE_UNINIT Uninit;\r\n"; + retStr += "} PEI_PCD_DATABASE;\r\n"; + retStr += "\r\n"; + retStr += "#define PEI_NEX_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER - PEI_EX_TOKEN_NUMBER)\r\n"; + retStr += "\r\n"; + + return retStr; + } + + /** + Translate the schema string to UUID instance. + + In schema, the string of UUID is defined as following two types string: + 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},( + )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})? + + 2) GuidNamingConvention: pattern = + [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12} + + This function will convert string and create uuid instance. + + @param uuidString UUID string in XML file + + @return UUID UUID instance + **/ + private UUID translateSchemaStringToUUID(String uuidString) + throws EntityException { + String temp; + String[] splitStringArray; + int index; + int chIndex; + int chLen; + + if (uuidString == null) { + return null; + } + + if (uuidString.length() == 0) { + return null; + } + + if (uuidString.equals("0") || + uuidString.equalsIgnoreCase("0x0")) { + return new UUID(0, 0); + } + + uuidString = uuidString.replaceAll("\\{", ""); + uuidString = uuidString.replaceAll("\\}", ""); + + // + // If the UUID schema string is GuidArrayType type then need translate + // to GuidNamingConvention type at first. + // + if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) { + splitStringArray = uuidString.split("," ); + if (splitStringArray.length != 11) { + throw new EntityException ("[FPD file error] Wrong format for GUID string: " + uuidString); + } + + // + // Remove blank space from these string and remove header string "0x" + // + for (index = 0; index < 11; index ++) { + splitStringArray[index] = splitStringArray[index].trim(); + splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length()); + } + + // + // Add heading '0' to normalize the string length + // + for (index = 3; index < 11; index ++) { + chLen = splitStringArray[index].length(); + for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) { + splitStringArray[index] = "0" + splitStringArray[index]; + } + } + + // + // construct the final GuidNamingConvention string + // + temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s", + splitStringArray[0], + splitStringArray[1], + splitStringArray[2], + splitStringArray[3], + splitStringArray[4], + splitStringArray[5], + splitStringArray[6], + splitStringArray[7], + splitStringArray[8], + splitStringArray[9], + splitStringArray[10]); + uuidString = temp; + } + + return UUID.fromString(uuidString); + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PlatformPcdPreprocessActionForBuilding.java b/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PlatformPcdPreprocessActionForBuilding.java new file mode 100644 index 0000000000..6d71dd3b37 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PlatformPcdPreprocessActionForBuilding.java @@ -0,0 +1,372 @@ +/** @file + PlatformPcdPreprocessActionForBuilding class. + + This action class is to collect PCD information from MSA, SPD, FPD xml file. + This class will be used for wizard and build tools, So it can *not* inherit + from buildAction or wizardAction. + +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.pcd.action; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; +import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions; +import org.tianocore.PcdBuildDefinitionDocument; +import org.tianocore.PlatformSurfaceAreaDocument; +import org.tianocore.build.exception.PlatformPcdPreprocessBuildException; +import org.tianocore.build.global.GlobalData; +import org.tianocore.build.id.FpdModuleIdentification; +import org.tianocore.pcd.action.PlatformPcdPreprocessAction; +import org.tianocore.pcd.entity.MemoryDatabaseManager; +import org.tianocore.pcd.entity.ModulePcdInfoFromFpd; +import org.tianocore.pcd.entity.Token; +import org.tianocore.pcd.entity.UsageIdentification; +import org.tianocore.pcd.exception.EntityException; +import org.tianocore.pcd.exception.PlatformPcdPreprocessException; + +/** + This action class is to collect PCD information from MSA, SPD, FPD xml file. + This class will be used for wizard and build tools, So it can *not* inherit + from buildAction or UIAction. +**/ +public class PlatformPcdPreprocessActionForBuilding extends PlatformPcdPreprocessAction { + /// + /// FPD file path. + /// + private String fpdFilePath; + + /// + /// Message level for CollectPCDAction. + /// + private int originalMessageLevel; + + /// + /// Cache the fpd docment instance for private usage. + /// + private PlatformSurfaceAreaDocument fpdDocInstance; + + /** + Set FPDFileName parameter for this action class. + + @param fpdFilePath fpd file path + **/ + public void setFPDFilePath(String fpdFilePath) { + this.fpdFilePath = fpdFilePath; + } + + /** + Common function interface for outer. + + @param fpdFilePath The fpd file path of current build or processing. + + @throws PlatformPreprocessBuildException + The exception of this function. Because it can *not* be predict + where the action class will be used. So only Exception can be throw. + + **/ + public void perform(String fpdFilePath) + throws PlatformPcdPreprocessBuildException { + this.fpdFilePath = fpdFilePath; + checkParameter(); + execute(); + } + + /** + Core execution function for this action class. + + This function work flows will be: + 1) Collect and prepocess PCD information from FPD file, all PCD + information will be stored into memory database. + 2) Generate 3 strings for + a) All modules using Dynamic(Ex) PCD entry.(Token Number) + b) PEI PCDDatabase (C Structure) for PCD Service PEIM. + c) DXE PCD Database (C structure) for PCD Service DXE. + + + @throws EntityException Exception indicate failed to execute this action. + + **/ + public void execute() throws PlatformPcdPreprocessBuildException { + String errorMessageHeader = "Failed to initialize the Pcd memory database because: "; + String errorsForPreprocess = null; + + // + // Get memoryDatabaseManager instance from GlobalData. + // The memoryDatabaseManager should be initialized as static variable + // in some Pre-process class. + // + setPcdDbManager(GlobalData.getPCDMemoryDBManager()); + + // + // Collect all PCD information defined in FPD file. + // Evenry token defind in FPD will be created as an token into + // memory database. + // + try { + initPcdMemoryDbWithPlatformInfo(); + } catch (PlatformPcdPreprocessException exp) { + throw new PlatformPcdPreprocessBuildException(errorMessageHeader + exp.getMessage()); + } + errorsForPreprocess = this.getErrorString(); + if (errorsForPreprocess != null) { + throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + errorsForPreprocess); + } + + // + // Generate for PEI, DXE PCD DATABASE's definition and initialization. + // + try { + genPcdDatabaseSourceCode (); + } catch (EntityException exp) { + throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + exp.getMessage()); + } + } + + /** + Override function: implementate the method of get Guid string information from SPD file. + + @param guidCName Guid CName string. + + @return String Guid information from SPD file. + @throws PlatformPcdPreprocessException + Fail to get Guid information from SPD file. + **/ + public String getGuidInfoFromSpd(String guidCName) throws PlatformPcdPreprocessException { + String tokenSpaceStrRet = null; + try { + tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(guidCName); + } catch ( Exception e ) { + throw new PlatformPcdPreprocessException ("Failed to get Guid CName " + guidCName + " from the SPD file!"); + } + return tokenSpaceStrRet; + } + + /** + This function generates source code for PCD Database. + + @throws EntityException If the token does *not* exist in memory database. + + **/ + private void genPcdDatabaseSourceCode() + throws EntityException { + String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions(); + + ArrayList alPei = new ArrayList (); + ArrayList alDxe = new ArrayList (); + + getPcdDbManager().getTwoPhaseDynamicRecordArray(alPei, alDxe); + PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0); + pcdPeiDatabase.genCode(); + MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString() + + PcdDatabase.getPcdPeiDatabaseDefinitions(); + MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString(); + + PcdDatabase pcdDxeDatabase = new PcdDatabase(alDxe, "DXE", alPei.size()); + pcdDxeDatabase.genCode(); + MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString() + + PcdDatabase.getPcdDxeDatabaseDefinitions(); + MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString(); + } + + /** + Override function: Get component array from FPD. + + This function maybe provided by some Global class. + + @return List the component array. + @throws PlatformPcdPreprocessException get all modules in in FPD file. + + **/ + public List getComponentsFromFpd() + throws PlatformPcdPreprocessException { + List allModules = new ArrayList(); + Map pcdBuildDefinitions = null; + UsageIdentification usageId = null; + + pcdBuildDefinitions = GlobalData.getFpdPcdBuildDefinitions(); + if (pcdBuildDefinitions == null) { + return null; + } + + // + // Loop map to retrieve all PCD build definition and Module id + // + Iterator item = pcdBuildDefinitions.keySet().iterator(); + while (item.hasNext()){ + FpdModuleIdentification id = (FpdModuleIdentification) item.next(); + usageId = new UsageIdentification(id.getModule().getName(), + id.getModule().getGuid(), + id.getModule().getPackage().getName(), + id.getModule().getPackage().getGuid(), + id.getArch(), + id.getModule().getVersion(), + id.getModule().getModuleType()); + allModules.add( + new ModulePcdInfoFromFpd( + usageId, + ((PcdBuildDefinitionDocument)pcdBuildDefinitions.get(id)).getPcdBuildDefinition())); + } + return allModules; + } + + /** + Override function: Verify the datum value according its datum size and datum type, this + function maybe moved to FPD verification tools in future. + + @param cName The token name + @param moduleName The module who use this PCD token + @param datum The PCD's datum + @param datumType The PCD's datum type + @param maxDatumSize The max size for PCD's Datum. + + @return String exception strings. + */ + public String verifyDatum(String cName, + String moduleName, + String datum, + Token.DATUM_TYPE datumType, + int maxDatumSize) { + // + // In building system, datum should not be checked, the checking work + // should be done by wizard tools or PCD verification tools. + // + return null; + } + + /** + Override function: Get dynamic information for a dynamic PCD from seciton in FPD file. + + This function should be implemented in GlobalData in future. + + @param token The token instance which has hold module's PCD information + @param moduleName The name of module who will use this Dynamic PCD. + + @return DynamicPcdBuildDefinitions.PcdBuildData + **/ + public DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFpd(Token token, + String moduleName) + throws PlatformPcdPreprocessException { + int index = 0; + String exceptionString = null; + String dynamicPrimaryKey = null; + DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null; + List dynamicPcdBuildDataArray = null; + String tokenSpaceStrRet = null; + + // + // If FPD document is not be opened, open and initialize it. + // BUGBUG: The code should be moved into GlobalData in future. + // + if (fpdDocInstance == null) { + try { + fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath)); + } catch(IOException ioE) { + throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage()); + } catch(XmlException xmlE) { + throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage()); + } + } + + dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions(); + if (dynamicPcdBuildDefinitions == null) { + exceptionString = String.format("[FPD file error] There are no elements in FPD file but there are Dynamic type "+ + "PCD entries %s in module %s!", + token.cName, + moduleName); + putError(exceptionString); + return null; + } + + dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList(); + for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) { + tokenSpaceStrRet = getGuidInfoFromSpd(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName()); + + if (tokenSpaceStrRet == null) { + exceptionString = "Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName(); + putError(exceptionString); + continue; + } + + dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(), + tokenSpaceStrRet); + if (dynamicPrimaryKey.equals(token.getPrimaryKeyString())) { + return dynamicPcdBuildDataArray.get(index); + } + } + + return null; + } + + /** + Override function: get all from FPD file. + + @return List All DYNAMIC PCD list in in FPD file. + @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list. + + **/ + public List + getAllDynamicPcdInfoFromFpd() + throws PlatformPcdPreprocessException { + DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null; + + // + // Open fpd document to get Section. + // BUGBUG: the function should be move GlobalData in furture. + // + if (fpdDocInstance == null) { + try { + fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath)); + } catch(IOException ioE) { + throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage()); + } catch(XmlException xmlE) { + throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage()); + } + } + + dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions(); + if (dynamicPcdBuildDefinitions == null) { + return null; + } + + return dynamicPcdBuildDefinitions.getPcdBuildDataList(); + } + + /** + check parameter for this action. + + @throws PlatformPcdPreprocessBuildException Bad parameter. + **/ + private void checkParameter() throws PlatformPcdPreprocessBuildException { + File file = null; + + if (fpdFilePath == null) { + throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!"); + } + + if (fpdFilePath.length() == 0) { + throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!"); + } + + file = new File(fpdFilePath); + + if(!file.exists()) { + throw new PlatformPcdPreprocessBuildException("FPD File " + fpdFilePath + " does not exist!"); + } + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java new file mode 100644 index 0000000000..fa1fc239f4 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java @@ -0,0 +1,108 @@ +/** @file + ConfigReader class. + + ConfigReader is used to read tool chain config file with flat format. + +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.toolchain; + +import org.tianocore.build.exception.GenBuildException; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.List; + +/** + + ConfigReader is used to read tool chain config file with flat format. Comments + is line starting with character '#'. + + @since GenBuild 1.0 +**/ +public class ConfigReader { + + /** + Parse specified tool chain definition file. + + @param filename The config file name with full path + + @return String[][] The definition array + **/ + public static synchronized String[][] parse(String filename) throws GenBuildException { + return parse(new File(filename)); + } + + /** + Get all definitions in config file. the config file format is flat + with "A=B". If line started with '#' looks as comments. + + @param configFile The config file + + @return String[][] The variables defined in the config file + + @throws GenBuildException + Config file's format is not valid + **/ + public static synchronized String[][] parse(File configFile) throws GenBuildException { + List keyList = new ArrayList(256); + List valueList = new ArrayList(256); + int lines = 0; + + try { + FileReader reader = new FileReader(configFile); + BufferedReader in = new BufferedReader(reader); + String str; + + while ((str = in.readLine()) != null) { + ++lines; + str = str.trim(); + // + // skip empty line, comment (start with '#') + // + if (str.length() == 0 || str.startsWith("#")) { + continue; + } + + // + // stop if the definition line is not in "name=value" form + // + int index; + if ((index = str.indexOf('=')) <= 0) { + throw new GenBuildException("ERROR Processing file [" + + configFile.getAbsolutePath() + + "] (line " + lines + ").\n"); + } + + // + // look as line "A = B" + // + keyList.add(str.substring(0, index).trim()); + valueList.add(str.substring(index + 1).trim()); + } + } catch (Exception ex) { + GenBuildException e = new GenBuildException("ERROR Processing file [" + + configFile.getAbsolutePath() + + "] (line " + lines + ").\n" + ex.getMessage()); + e.setStackTrace(ex.getStackTrace()); + throw e; + } + + String[][] definitions = new String[2][keyList.size()]; + definitions[0] = (String[])keyList.toArray(definitions[0]); + definitions[1] = (String[])valueList.toArray(definitions[1]); + + return definitions; + } +} + + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainAttribute.java b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainAttribute.java new file mode 100644 index 0000000000..491d37c431 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainAttribute.java @@ -0,0 +1,52 @@ +/** @file +ToolChainAttribute class + +This file is to define enumeration value for tool chain attribute names. + +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.toolchain; + +/** + + ToolChainAttribute is used to define the enumeration value for the attributes + used in tool chain definition file. + + **/ +public class ToolChainAttribute { + private static int nextValue = 0; + + /// + /// "NAME", "PATH", "DPATH", "SPATH", "EXT", "FAMILY", "FLAGS" + /// + public final static ToolChainAttribute NAME = new ToolChainAttribute("NAME"); + public final static ToolChainAttribute PATH = new ToolChainAttribute("PATH"); + public final static ToolChainAttribute DPATH = new ToolChainAttribute("DPATH"); + public final static ToolChainAttribute SPATH = new ToolChainAttribute("SPATH"); + public final static ToolChainAttribute EXT = new ToolChainAttribute("EXT"); + public final static ToolChainAttribute FAMILY = new ToolChainAttribute("FAMILY"); + public final static ToolChainAttribute FLAGS = new ToolChainAttribute("FLAGS"); + + private final String name; + public final int value = nextValue++; + + /** + * Default constructor + */ + private ToolChainAttribute(String name) { + this.name = name; + } + + public String toString() { + return name; + } +} + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainConfig.java b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainConfig.java new file mode 100644 index 0000000000..b12c43662c --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainConfig.java @@ -0,0 +1,125 @@ +/** @file + ToolChainConfig class. + + ToolChainConfig class parse all config files and get tool chain information. + +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.toolchain; + +import org.tianocore.build.exception.GenBuildException; +import org.tianocore.build.toolchain.ToolChainKey; +import org.tianocore.build.toolchain.ToolChainMap; + +import java.io.File; +import java.util.Iterator; +import java.util.Set; + + +/** + + ToolChainConfig class parse all config files and get tool chain information. + + **/ +public class ToolChainConfig { + // + // tool chain definitions + // + private ToolChainMap config = null; + // + // tool chain information (how many targets, archs, etc.) + // + private ToolChainInfo info = new ToolChainInfo(); + + /** + Public construct method. + + @param toolChainFile File object representing the tool chain configuration file + **/ + public ToolChainConfig (File toolChainFile) throws GenBuildException { + config = getToolChainConfig(toolChainFile); + parseToolChainDefKey(config.keySet()); + } + + /** + Read tool chain definitions from specified file and put them in + ToolChainMap class. + + @param ConfigFile The file containing tool chain definitions + + @return ToolChainMap + **/ + private ToolChainMap getToolChainConfig(File ConfigFile) throws GenBuildException { + ToolChainMap map = new ToolChainMap(); + String[][] toolChainDef = ConfigReader.parse(ConfigFile); + + for (int i = 0; i < toolChainDef[0].length; ++i) { + map.put(toolChainDef[0][i], toolChainDef[1][i]); + } + + return map; + } + + /** + Collect target, tool chain tag, arch and command information from key part + of configuration + + @param toolChainDefKey The set of keys in tool chain configuration + **/ + private void parseToolChainDefKey (Set toolChainDefKey) { + Iterator it = toolChainDefKey.iterator(); + while (it.hasNext()) { + ToolChainKey key = (ToolChainKey)it.next(); + String[] keySet = key.getKeySet(); + info.addTargets(keySet[ToolChainElement.TARGET.value]); + info.addTagnames(keySet[ToolChainElement.TOOLCHAIN.value]); + info.addArchs(keySet[ToolChainElement.ARCH.value]); + info.addCommands(keySet[ToolChainElement.TOOLCODE.value]); + } + } + + /** + Return the tool chain configuration information in a Map form + + @return ToolChainMap Tool chain configurations in a ToolChainMap + **/ + public ToolChainMap getConfig() { + return config; + } + + /** + Return the tool chain's target, arch, tag and commands information + + @return ToolChainInfo Tool chain information summary + **/ + public ToolChainInfo getConfigInfo() { + return info; + } + + /** + override toString() + + @return String The converted configuration string in name=value form + **/ + public String toString() { + StringBuffer ts = new StringBuffer(10240); + + Iterator it = config.keySet().iterator(); + while (it.hasNext()) { + ToolChainKey key = (ToolChainKey)it.next(); + ts.append(key.toString() + " = "); + ts.append(config.get(key) + "\n"); + } + + return ts.toString(); + } +} + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainElement.java b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainElement.java new file mode 100644 index 0000000000..103b3a6362 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainElement.java @@ -0,0 +1,54 @@ +/** @file +ToolChainElement class + +ToolChainElement class is defining enumeration value of key part names. + +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.toolchain; + +/** + + This class is an enumeration definition for key elements in tool chain definition + file. + + **/ +public class ToolChainElement { + private static int nextValue = 0; + + // + // "TARGET", "TOOLCHAIN", "ARCH", "TOOLCODE", "ATTRIBUTE" + // + public final static ToolChainElement TARGET = new ToolChainElement("TARGET"); + public final static ToolChainElement TOOLCHAIN = new ToolChainElement("TOOLCHAIN"); + public final static ToolChainElement ARCH = new ToolChainElement("ARCH"); + public final static ToolChainElement TOOLCODE = new ToolChainElement("TOOLCODE"); + public final static ToolChainElement ATTRIBUTE = new ToolChainElement("ATTRIBUTE"); + + private final String name; + public final int value = nextValue++; + + /** + * Default constructor + */ + private ToolChainElement(String name) { + this.name = name; + } + + public String toString() { + return name; + } +} + + + + + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainInfo.java b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainInfo.java new file mode 100644 index 0000000000..9952c0beda --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainInfo.java @@ -0,0 +1,347 @@ +/** @file +ToolChainInfo class + +This file is to define ToolChainInfo class. + +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.toolchain; + +import java.util.LinkedHashSet; +import java.util.Set; + +/** + ToolChainInfo collects valid build targets, tool chain tag, ARCHs and commands + information for real build use. + **/ +public class ToolChainInfo { + // + // build target set + // + private Set targets = new LinkedHashSet(); + // + // tool chain tag name set + // + private Set tagnames = new LinkedHashSet(); + // + // build archs set + // + private Set archs = new LinkedHashSet(); + // + // build commands set + // + private Set commands = new LinkedHashSet(); + + /** + Add a list of targets in the form of string separated by space + + @param targetList target list string + **/ + public void addTargets(String targetList) { + // + // targetList some targets separated by space " " + // + if (targetList == null || targetList.length() == 0) { + targets.add("*"); + } else { + addTargets(targetList.split(" ")); + } + } + + /** + Add a list of targets in the form of string array + + @param targetArray target string array + **/ + public void addTargets(String[] targetArray) { + if (targetArray != null ) { + for (int i = 0; i < targetArray.length; i++) { + targets.add(targetArray[i]); + } + } + } + + /** + Add a list of target in the form of set + + @param targetSet target string set + **/ + public void addTargets(Set targetSet) { + if (targetSet != null) { + targets.addAll(targetSet); + } + } + + /** + Add a list of tool chain tag name in the form of string separated by space + + @param tagnameList Tool chain tag name list string + **/ + public void addTagnames(String tagnameList) { + // + // tagnameList some tagnames separated by space " " + // + if (tagnameList == null || tagnameList.length() == 0) { + tagnames.add("*"); + } else { + addTagnames(tagnameList.split(" ")); + } + } + + /** + Add a list of tool chain tag name in the form of string array + + @param tagnameArray Tool chain tag names array + **/ + public void addTagnames(String[] tagnameArray) { + if (tagnameArray != null ) { + for (int i = 0; i < tagnameArray.length; i++) { + tagnames.add(tagnameArray[i]); + } + } + } + + /** + Add a list of tool chain tag name in the form of Set + + @param tagnameSet Tool chain tag names set + **/ + public void addTagnames(Set tagnameSet) { + if (tagnameSet != null) { + tagnames.addAll(tagnameSet); + } + } + + /** + Add a list of ARCH in the form of string + + @param archList ARCH string + **/ + public void addArchs(String archList) { + // + // archList some archs separated by space " " + // + if (archList == null || archList.length() == 0) { + archs.add("*"); + } else { + addArchs(archList.split(" ")); + } + } + + /** + Add a list of ARCH in the form of string array + + @param archArray ARCH array + **/ + public void addArchs(String[] archArray) { + if (archArray != null ) { + for (int i = 0; i < archArray.length; i++) { + archs.add(archArray[i]); + } + } + } + + /** + Add a list of ARCH in the form of set + + @param archSet ARCH set + **/ + public void addArchs(Set archSet) { + if (archSet != null) { + archs.addAll(archSet); + } + } + + /** + Add a list of command in the form of string + + @param commandList Command list string + **/ + public void addCommands(String commandList) { + // + // archList some archs separated by space " " + // + if (commandList == null || commandList.length() == 0) { + commands.add("*"); + } else { + addCommands(commandList.split(" ")); + } + } + + /** + Add a list of ARCH in the form of array + + @param commandArray Commands array + **/ + public void addCommands(String[] commandArray) { + if (commandArray != null ) { + for (int i = 0; i < commandArray.length; i++) { + commands.add(commandArray[i]); + } + } + } + + /** + Add a list of ARCH in the form of set + + @param commandSet Commands set + **/ + public void addCommands(Set commandSet) { + if (commandSet != null) { + commands.addAll(commandSet); + } + } + + /** + Make a union operation on this ToolChainInfo and the given one. + + @param info Another ToolChainInfo object to merge with + + @return ToolChainInfo Merged ToolChainInfo object + **/ + public ToolChainInfo union(ToolChainInfo info) { + ToolChainInfo result = new ToolChainInfo(); + result.addTargets(union(this.targets, info.targets)); + result.addTagnames(union(this.tagnames, info.tagnames)); + result.addArchs(union(this.archs, info.archs)); + return result; + } + + /** + Make a intersection operation on this ToolChainInfo and the given one + + @param info Another ToolChainInfo object to intersect with + + @return ToolChainInfo Intersected ToolChainInfo object + **/ + public ToolChainInfo intersection(ToolChainInfo info) { + ToolChainInfo result = new ToolChainInfo(); + result.addTargets(intersection(this.targets, info.targets)); + result.addTagnames(intersection(this.tagnames, info.tagnames)); + result.addArchs(intersection(this.archs, info.archs)); + return result; + } + + /** + Make a union operation on two Sets + + @param set1 One Set + @param set2 Another Set + + @return Set Merged Set object + **/ + private Set union(Set set1, Set set2) { + Set result = new LinkedHashSet(); + result.addAll(set1); + result.addAll(set2); + result.remove("*"); + return result; + } + + /** + Make a intersection operation on two Sets with the consideration of wildcard. + + @param set1 One Set + @param set2 Another Set + + @return Set The intersected Set object + **/ + private Set intersection(Set set1, Set set2) { + Set result = new LinkedHashSet(); + boolean set1HasWildcard = set1.contains("*"); + boolean set2HasWildcard = set2.contains("*"); + + if (set1HasWildcard && set2HasWildcard) { + // + // Both Sets have wildcard, the result will have all elements in them + // + result.addAll(set1); + result.addAll(set2); + } else if (set1HasWildcard) { + // + // Only set1 has wildcard, then result will have only set2 elements. + // + result.addAll(set2); + } else if (set2HasWildcard) { + // + // Only set2 has wildcard, then result will have only set1 elements. + // + result.addAll(set1); + } else { + // + // No wildcard in both Sets, the result will have the elements in both Sets. + // + result.addAll(set1); + result.retainAll(set2); + } + + return result; + } + + /** + Get target array. + + @return String[] + **/ + public String[] getTargets() { + return (String[])targets.toArray(new String[targets.size()]); + } + + /** + Get tool chain tag name array. + + @return String[] + **/ + public String[] getTagnames() { + return (String[])tagnames.toArray(new String[tagnames.size()]); + } + + /** + Get ARCH array. + + @return String[] + **/ + public String[] getArchs() { + return (String[])archs.toArray(new String[archs.size()]); + } + + /** + Get command name array. + + @return String[] + **/ + public String[] getCommands() { + return (String[])commands.toArray(new String[commands.size()]); + } + + /** + Override the Object's toString(). + + @return String + **/ + public String toString() { + return " TARGET :" + targets + "\n" + + " TAGNAME:" + tagnames + "\n" + + " ARCH :" + archs + "\n" + + " COMMAND:" + commands; + } + + /** + Remove the wildcard element in the tool chain information because they + are useless when retrieved. + **/ + public void normalize() { + targets.remove("*"); + tagnames.remove("*"); + archs.remove("*"); + commands.remove("*"); + } +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainKey.java b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainKey.java new file mode 100644 index 0000000000..1bedf3c685 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainKey.java @@ -0,0 +1,278 @@ +/** @file +ToolChainKey class + +ToolChainKey class is representing the "name" part of tool chain definition. + +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.toolchain; + +import org.tianocore.build.exception.GenBuildException; + +/** + ToolChainKey class is the java class form of the "name" of tool chain definition. + It's primarily for the key of a Map data structure. + **/ +public class ToolChainKey implements java.io.Serializable, Comparable { + static final long serialVersionUID = -8034897190740066933L; + + /// + /// The part number of key. Currently we only support fixed five parts. + /// + public final static int keyLength = 5; + + // + // Default delimiter which is used for concatenating the parts of key + // + private String delimiter = "_"; + + // + // Key value in string array form + // + private String[] keySet = null; + + // + // Key value in one string form + // + private String keyString = null; + + // + // Key hash value used for hash table + // + private int hashValue = 0; + + /** + Public constructor which can override default delimiter. + + @param keyString The key string value + @param delimiter Delimiter charater concatenating the key parts + **/ + public ToolChainKey(String keyString, String delimiter) throws GenBuildException { + setKey(keyString, delimiter); + } + + /** + Public constructor which uses default delimiter. + + @param keyString The key string value + **/ + public ToolChainKey(String keyString) throws GenBuildException { + setKey(keyString); + } + + /** + Public constructor which doesn't use any delimiter. + + @param keySet + **/ + public ToolChainKey(String[] keySet) throws GenBuildException { + setKey(keySet); + } + + /** + Calculate hash value of the key string (without the delimiter). It's used + for Hash Table kind of Map. + + @return int The hash value + **/ + public int hashCode() { + if (hashValue != 0) { + return hashValue; + } + + for (int i = 0; i < keySet.length; ++i) { + char[] keyStringValue = new char[keySet[i].length()]; + this.keySet[i].getChars(0, keyStringValue.length, keyStringValue, 0); + + for (int j = 0; j < keyStringValue.length; ++j) { + hashValue = keyStringValue[j] + hashValue * 31; + } + } + + return hashValue; + } + + /** + Compare the string value of two keys . It's used for Tree kind of Map. + + @param dstKey Another key to compare to. + + @retval 0 Two keys are equal + @retval >0 This key is after the given key + @retval <0 This key is before the given key + **/ + public int compareTo(ToolChainKey dstKey) { + String[] dstKeySet = dstKey.getKeySet(); + int result = 0; + for (int i = 0; i < ToolChainKey.keyLength; ++i) { + result = this.keySet[i].compareToIgnoreCase(dstKeySet[i]); + if (result != 0) { + break; + } + } + + return result; + } + + /** + Check if this key is the same as the given key. + + @param o Another key to compare to + + @return boolean + **/ + public boolean equals(Object o) { + ToolChainKey dstKey = (ToolChainKey)o; + String[] dstKeySet = dstKey.getKeySet(); + + if (this == dstKey) { + return true; + } + + if (dstKeySet.length != ToolChainKey.keyLength) { + return false; + } + + for (int i = 0; i < ToolChainKey.keyLength; ++i) { + if (!this.keySet[i].equalsIgnoreCase(dstKeySet[i])) { + return false; + } + } + + return true; + } + + /** + Set the key value in form of string array. + + @param keySet The string array of key value + **/ + public void setKey(String[] keySet) throws GenBuildException { + if (keySet.length != ToolChainKey.keyLength) { + throw new GenBuildException("Invalid ToolChain key"); + } + + // + // Clone the string array because we don't want to change original one + // + this.keySet = new String[ToolChainKey.keyLength]; + System.arraycopy(keySet, 0, this.keySet, 0, ToolChainKey.keyLength); + for (int i = 0; i < ToolChainKey.keyLength; ++i) { + if (this.keySet[i] == null || this.keySet[i].length() == 0) { + this.keySet[i] = "*"; + } + } + + // + // We need to re-generate the single key string and hash value. + // + this.keyString = null; + this.hashValue = 0; + } + + /** + Set key value at the specified key part . + + @param keySetString The new value of "index" part of key + @param index The key part index + **/ + public void setKey(String keySetString, int index) throws GenBuildException { + if (index >= ToolChainKey.keyLength) { + throw new GenBuildException("Invalid ToolChain key index"); + } + + // + // Allow wildcard in key string + // + if (keySetString == null || keySetString.length() == 0) { + keySetString = "*"; + } + this.keySet[index] = keySetString; + + // + // We need to re-generate the single key string and hash value. + // + this.keyString = null; + this.hashValue = 0; + } + + /** + Set key value in the form of single string. + + @param keyString The key value string + **/ + public void setKey(String keyString) throws GenBuildException { + this.keySet = keyString.split(this.delimiter); + + if (this.keySet.length != ToolChainKey.keyLength) { + throw new GenBuildException("Invalid ToolChain key"); + } + + this.keyString = keyString; + // + // We need to re-generate hash value. + // + this.hashValue = 0; + } + + /** + Set key value in the form of single string with specified delimiter. + + @param keyString The key value string + @param delimiter The delimiter concatenating the key string + **/ + public void setKey(String keyString, String delimiter) throws GenBuildException { + this.keySet = keyString.split(delimiter); + + if (this.keySet.length != ToolChainKey.keyLength) { + throw new GenBuildException("Invalid ToolChain key"); + } + + this.keyString = keyString; + this.delimiter = delimiter; + // + // We need to re-generate hash value. + // + this.hashValue = 0; + } + + /** + Return the string array form of key + + @return String[] + **/ + public String[] getKeySet() { + return keySet; + } + + /** + Return the single string form of key. + + @return String + **/ + public String toString() { + if (this.keyString == null) { + StringBuffer keyStringBuf = new StringBuffer(64); + + keyStringBuf.append(this.keySet[0]); + for (int i = 1; i < ToolChainKey.keyLength; ++i) { + keyStringBuf.append(this.delimiter); + keyStringBuf.append(this.keySet[i]); + } + + this.keyString = keyStringBuf.toString(); + } + + return this.keyString; + } +} + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainMap.java b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainMap.java new file mode 100644 index 0000000000..b9d24eb0b9 --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/toolchain/ToolChainMap.java @@ -0,0 +1,326 @@ +/** @file +ToolChainMap class + +ToolChainMap class is used for storing tool chain configurations. + +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.toolchain; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + ToolChainMap is a wrapper class for a generic Map class which uses ToolChainKey + class as its key. It's used to store and retrieve tool chain configuration + information. + **/ +public class ToolChainMap { + // + // From which part of key can be used to match "*" + // + private int matchLevel = ToolChainKey.keyLength - 2; + + // + // A Map object in which tool chain configuration information will be stored + // + private Map map = null; + + /** + Public constructor. It just initializes the private Map object. + **/ + public ToolChainMap() { + this.map = new HashMap(); + } + + /** + Wrapper function for Map.put(). It's used when default delimiter of + ToolChainKey is not wanted and will be overrided by "delimiter" parameter. + + @param key Key string which is concatenated with "delimiter" + @param delimiter The delimiter string in the key string + @param value Value string associated with the "key" + + @retval String The "value" string if the "key" is valid. + @retval null if the "key" is invalid + **/ + public String put(String key, String delimiter, String value) { + ToolChainKey toolChainKey; + + try { + toolChainKey = new ToolChainKey(key, delimiter); + } catch (Exception e) { + return null; + } + return (String)map.put(toolChainKey, value); + } + + /** + Wrapper function for Map.put(). + + @param key Key string which is concatenated with default "delimiter" + @param value Value string associated with the "key" + + @retval String The "value" string if the "key" is valid. + @retval null if the "key" is invalid + **/ + public String put(String key, String value) { + ToolChainKey toolChainKey; + + try { + toolChainKey = new ToolChainKey(key); + } catch (Exception e) { + return null; + } + return (String)map.put(toolChainKey, value); + } + + /** + Wrapper function for Map.put(). The key is given in the form of string + array. + + @param key Key string array + @param value Value string associated with the "key" + + @retval String The "value" string if the "key" is valid. + @retval null if the "key" is invalid + **/ + public String put(String[] key, String value) { + ToolChainKey toolChainKey; + + try { + toolChainKey = new ToolChainKey(key); + } catch (Exception e) { + return null; + } + return (String)map.put(toolChainKey, value); + } + + /** + Wrapper function for Map.put(). The key is given in ToolChainKey class. + + @param key ToolChainKey class + @param value Value string associated with the "key" + + @retval String The "value" string if the "key" is valid. + @retval null if the "key" is invalid + **/ + public String put(ToolChainKey key, String value) { + return (String)map.put(key, value); + } + + /** + Wrapper function for Map.get(). + + @param key Key string which is concatenated with default "delimiter" + + @return String + **/ + public String get(String key) { + ToolChainKey toolChainKey; + + try { + toolChainKey = new ToolChainKey(key); + } catch (Exception e) { + return null; + } + return get(toolChainKey); + } + + /** + Wrapper function for Map.get(). It's used when default delimiter of + ToolChainKey is not wanted and will be overrided by "delimiter" parameter. + + @param key Key string which is concatenated with "delimiter" + @param delimiter The delimiter string in the key string + + @return String + **/ + public String get(String key, String delimiter) { + ToolChainKey toolChainKey; + + try { + toolChainKey = new ToolChainKey(key, delimiter); + } catch (Exception e) { + return null; + } + return get(toolChainKey); + } + + /** + Wrapper function for Map.get(). The key is given in the form of string + array. + + @param key Key string array + + @return String + **/ + public String get(String[] key) { + ToolChainKey toolChainKey; + + try { + toolChainKey = new ToolChainKey(key); + } catch (Exception e) { + return null; + } + return get(toolChainKey); + } + + /** + Wrapper function for Map.get(). The key is given in ToolChainKey class. + All other form of get() method will eventually call this form of get. It + will do real job of finding the value associated with the given key. Most + of the job is to try to match the key with "wildcard". + + @param key ToolChainKey class + + @return String The value associated with the key + **/ + public String get(ToolChainKey key) { + /// + /// First, we'll try to get the value through the exact given key + /// + String result = map.get(key); + if (result != null || map.containsKey(key)) { + return result; + } + + /// + /// If nothing is found, then, we'll try all possible keys combined with + /// wildcard "*". In order not to change the original key value, we have + /// to clone one for later use. + /// + String[] keySet = key.getKeySet(); + ToolChainKey tmpKey; + try { + tmpKey = new ToolChainKey(keySet); + } catch (Exception e) { + return null; + } + + /// + /// In the current tool chain definition format (in name/value pair), + /// there're five parts in the "name". The last part of the "name" must + /// not be "wildcard". So we should start combining "*" from the fourth part. + /// We'll try all the possible combinations until the value can be fetched. + /// + /// The following code implements the logic which will try to use, for example, + /// following key parts combinations sequentially to get the value. + /// + /// TARGET_TOOLCHAIN_ARCH_TOOLCODE_ATTRIBUTE + /// TARGET_TOOLCHAIN_ARCH_*_ATTRIBUTE + /// TARGET_TOOLCHAIN_*_TOOLCODE_ATTRIBUTE + /// TARGET_TOOLCHAIN_*_*_ATTRIBUTE + /// TARGET_*_ARCH_TOOLCODE_ATTRIBUTE + /// TARGET_*_ARCH_*_ATTRIBUTE + /// TARGET_*_*_TOOLCODE_ATTRIBUTE + /// TARGET_*_*_*_ATTRIBUTE + /// *_TOOLCHAIN_ARCH_TOOLCODE_ATTRIBUTE + /// *_TOOLCHAIN_ARCH_*_ATTRIBUTE + /// *_TOOLCHAIN_*_TOOLCODE_ATTRIBUTE + /// *_TOOLCHAIN_*_*_ATTRIBUTE + /// *_*_ARCH_TOOLCODE_ATTRIBUTE + /// *_*_ARCH_*_ATTRIBUTE + /// *_*_*_TOOLCODE_ATTRIBUTE + /// *_*_*_*_ATTRIBUTE + /// + + // + // level is used to control if all parts of "name" have been "wildcarded" + // + int level = matchLevel; + while (level >= 0) { + // + // tmplevel is used to control if all parts of "name" between first + // "*" and fourth name part have been "wildcarded". + // + int tmpLevel = level; + while (tmpLevel >= level) { + String[] tmpKeySet = tmpKey.getKeySet(); + try { + if (!tmpKeySet[tmpLevel].equals("*")) { + // + // If "tmplevel" part is not "*", set it to "*". + // For example, at first loop, the key will become + // TARGET_TOOLCHAIN_ARCH_*_ATTRIBUTE, and at next loop, + // become TARGET_TOOLCHAIN_*_ARCH_ATTRIBUTE + // + tmpKey.setKey("*", tmpLevel); + // + // We'll try all possible combinations between current + // part and the fourth part. + // + tmpLevel = matchLevel; + } else { + // + // Restore original value of key if "*" at "tmplevel" + // part of "name" has been checked + // + tmpKey.setKey(keySet[tmpLevel], tmpLevel); + // + // Try "*" at part left to "tmplevel" part of "name" + // + --tmpLevel; + continue; + } + } catch (Exception e) { + return null; + } + + // + // Try get the value from the map + // + result = map.get(tmpKey); + if (result != null) { + // + // The map actually has no exact key as the given "key", + // putting it back into map can speed up the get() next time + // + map.put(key, result); + return result; + } + } + /// + /// If all possible combinations of "wildcard" between "level" and + /// the fourth part of "name" have been tried, try the left part + /// + --level; + } + + // + // The map actually has no exact key as the given "key", putting it back + // into map can speed up the get() next time even we got nothing. + // + map.put(key, result); + return result; + } + + /** + Wrapper function for Map.size(). + + @return int The size of map + **/ + public int size() { + return map.size(); + } + + /** + Wrapper function for Map.keySet(). + + @return Set A set of ToolChainKey objects + */ + public Set keySet() { + return (Set)map.keySet(); + } +} + diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/tools/ModuleItem.java b/Tools/Java/Source/GenBuild/org/tianocore/build/tools/ModuleItem.java new file mode 100644 index 0000000000..04223cd8fd --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/tools/ModuleItem.java @@ -0,0 +1,140 @@ +/** @file + +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.tools; + +import org.apache.tools.ant.BuildException; +/** + Ant element for module. + + @since GenBuild 1.0 +**/ +public class ModuleItem { + + private String moduleName = null; + + private String moduleGuid = null; + + private String moduleVersion = null; + + private String packageName = null; + + private String packageGuid = null; + + private String packageVersion = null; + + public ModuleItem(){ + + } + + public void execute() throws BuildException { + + } + + /** + Get module Guid. + @return Module Guid + **/ + public String getModuleGuid() { + return moduleGuid; + } + + /** + Set module Guid + @param moduleGuid Module Guid + **/ + public void setModuleGuid(String moduleGuid) { + this.moduleGuid = moduleGuid; + } + + /** + Get Module Name. + @return Module Name + **/ + public String getModuleName() { + return moduleName; + } + + /** + Set Module Name. + @param moduleName Module Name + **/ + public void setModuleName(String moduleName) { + this.moduleName = moduleName; + } + + /** + Get Module Version. + @return Module Version + **/ + public String getModuleVersion() { + return moduleVersion; + } + + /** + Set Module Version. + @param moduleVersion Module version + **/ + public void setModuleVersion(String moduleVersion) { + this.moduleVersion = moduleVersion; + } + + /** + Get Package Guid. + @return Package Guid + **/ + public String getPackageGuid() { + return packageGuid; + } + + /** + Set Package Guid. + @param packageGuid Package Guid + **/ + public void setPackageGuid(String packageGuid) { + this.packageGuid = packageGuid; + } + + /** + Get Package Name. + @return Package Name + **/ + public String getPackageName() { + return packageName; + } + + /** + Set Package Name. + @param packageName Package Name + **/ + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + /** + Get Package Version. + @return Package Version + **/ + public String getPackageVersion() { + return packageVersion; + } + + /** + Set Package Version. + @param packageVersion Package Version + **/ + public void setPackageVersion(String packageVersion) { + this.packageVersion = packageVersion; + } + + +} diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/tools/PackageItem.java b/Tools/Java/Source/GenBuild/org/tianocore/build/tools/PackageItem.java new file mode 100644 index 0000000000..f61782ddbd --- /dev/null +++ b/Tools/Java/Source/GenBuild/org/tianocore/build/tools/PackageItem.java @@ -0,0 +1,88 @@ +/** @file + +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.tools; + +import org.apache.tools.ant.BuildException; + +/** + Ant element for Package. + + @since GenBuild 1.0 +**/ +public class PackageItem { + + private String packageName = null; + + private String packageGuid = null; + + private String packageVersion = null; + + public PackageItem(){ + + } + + public void execute() throws BuildException { + + } + + public String toString(){ + return "[" + packageName + packageGuid + "]"; + } + /** + Get Package Guid. + @return Package Guid + **/ + public String getPackageGuid() { + return packageGuid; + } + + /** + Set Package Guid. + @param packageGuid Package Guid + **/ + public void setPackageGuid(String packageGuid) { + this.packageGuid = packageGuid; + } + + /** + Get Package Name. + @return Package Name + **/ + public String getPackageName() { + return packageName; + } + + /** + Set Package Name. + @param packageName Package Name + **/ + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + /** + Get Package Version. + @return Package Version + **/ + public String getPackageVersion() { + return packageVersion; + } + + /** + Set Package Version. + @param packageVersion Package Version + **/ + public void setPackageVersion(String packageVersion) { + this.packageVersion = packageVersion; + } +} -- cgit v1.2.3