diff options
Diffstat (limited to 'Tools/Java/Source/GenBuild/org')
44 files changed, 16467 insertions, 0 deletions
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;
+
+/**
+ <p><code>FfsProcess</code> is a class to find the corresponding FFS layout. </p>
+
+ <p>The FFS Layout is like following: </p>
+
+ <pre>
+ <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>
+ </pre>
+
+ @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 <code>FPD</code>.
+
+ @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<String> sectionList = new Vector<String>();
+ 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:
+
+ <pre>
+ Before change: FFS_ATTRIB_CHECKSUM
+ After change: ffsATTRIBCHECKSUM
+ </pre>
+
+ @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<String> 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;
+ //
+ // <gensection sectiontype="EFI_SECTION_COMPRESSION">
+ //
+ ele = doc.createElement("gensection");
+ ele.setAttribute("sectionType", "EFI_SECTION_COMPRESSION");
+
+ } else {
+ mode = MODE_GUID_DEFINED;
+ //
+ // <gensection sectiontype="EFI_SECTION_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);
+ }
+ //
+ // <tool toolName="${OEMTOOLPATH}\toolname"
+ // outputPath = "${DEST_DIR_OUTPUT}">
+ //
+ 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 <Tool> element exist, add sub element under <tool> .
+ //
+ 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<String> 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) {
+ //
+ // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>
+ //
+ 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 {
+ //
+ // <sectFile fileName= "..."/>
+ //
+ 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;
+
+/**
+ <p><code>FileProcess</code> is class to generate ANT script to build source
+ files.</p>
+
+ <p>If file does not specify file type, <code>FileProcess</code> will judge
+ by its extension. Following is the current supported extensions. </p>
+
+ <pre>
+ 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
+ </pre>
+
+ @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 <code>unicodeFirst</code> is true, then build all
+ unicode files firstly.
+
+ <p>Note that AutoGen.c is processed specially. It's output path is always
+ <code>${DEST_DIR_OUTPUT}</code>, others are <code>${DEST_DIR_OUTPUT}</code>
+ and relative to module path. </p>
+
+ @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);
+ }
+ }
+ // <Build_filetype FILEPATH="" FILENAME="" />
+ 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;
+
+/**
+ <p>
+ <code>FrameworkBuildTask</code> is an Ant task. The main function is finding
+ and processing a FPD or MSA file, then building a platform or stand-alone
+ module.
+
+ <p>
+ 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:
+
+ <pre>
+ 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.
+ </pre>
+
+ <p>
+ Framework build task also parse target file [${WORKSPACE_DIR}/Tools/Conf/target.txt].
+ And load all system environment variables to Ant properties.
+
+ <p>
+ The usage for this task is :
+
+ <pre>
+ <FrameworkBuild type="cleanall" />
+ </pre>
+
+ @since GenBuild 1.0
+**/
+public class FrameworkBuildTask extends Task{
+
+ private Set<File> buildFiles = new LinkedHashSet<File>();
+
+ private Set<File> fpdFiles = new LinkedHashSet<File>();
+
+ private Set<File> msaFiles = new LinkedHashSet<File>();
+
+ //
+ // This is only for none-multi-thread build to reduce overriding message
+ //
+ public static Hashtable<String, String> originalProperties = new Hashtable<String, String>();
+
+ 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<String, String> sysProperties = System.getenv();
+ Iterator<String> 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<File> 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;
+
+/**
+ <p>
+ <code>GenBuildTask</code> is an ANT task that can be used in ANT build
+ system.
+
+ <p>The main function of this task is to parse module's surface area (MSA),
+ then generate the corresponding <em>BaseName_build.xml</em> (the real ANT
+ build script) and call this to build the module. The whole process including:
+
+ <pre>
+ 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.
+ </pre>
+
+
+ <p>
+ The usage is (take module <em>HelloWorld</em> for example):
+ </p>
+
+ <pre>
+ <GenBuild
+ msaFile="${PACKAGE_DIR}/Application/HelloWorld/HelloWorld.msa"
+ type="cleanall" />
+ </pre>
+
+ <p>
+ This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and
+ <em>AutoGen.h</em>.
+ </p>
+
+ <p>
+ 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).
+ </p>
+
+ @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<Property> properties = new Vector<Property>();
+
+ 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<Property> 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<String, XmlObject> doc = GlobalData.getNativeMsa(moduleId);
+ saq = new SurfaceAreaQuery(doc);
+ } else {
+ Map<String, XmlObject> 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<String> archListSupByToolChain = new LinkedHashSet<String>();
+ String[] archs = GlobalData.getToolChainInfo().getArchs();
+
+ for (int i = 0; i < archs.length; i ++) {
+ archListSupByToolChain.add(archs[i]);
+ }
+
+ Set<String> archSet = new LinkedHashSet<String>();
+
+ 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.
+
+ <p>In Single Module Build mode, platform-related information is not ready.
+ The method read the system environment variable <code>ACTIVE_PLATFORM</code>
+ and search in the Framework Database. Note that platform name in the Framework
+ Database must be unique. </p>
+
+ **/
+ 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<String, String> passdownProperties = FrameworkBuildTask.originalProperties;
+ Iterator<String> 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<String> addset = new LinkedHashSet<String>();
+// Set<String> subset = new LinkedHashSet<String>();
+// 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.
+
+ <p> String is separated by Java Regulation Expression
+ "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
+
+ <p>For example: </p>
+
+ <pre>
+ "/nologo", "/W3", "/WX"
+ "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
+ </pre>
+
+ @param set store the separated string
+ @param str string to separate
+ **/
+ private void putFlagsToSet(Set<String> 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<String> add, Set<String> 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<String> includes = new LinkedHashSet<String>();
+ 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<String> 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<Property> 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<FpdModuleIdentification> dependencies = new LinkedHashSet<FpdModuleIdentification>();
+
+ 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<Property> properties = new Vector<Property>();
+ 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<FpdModuleIdentification> 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<FpdModuleIdentification> 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<FpdModuleIdentification> 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 <em>build.xml</em>.
+ ///
+ 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.
+ <ul>
+ <li> ANT properties; </li>
+ <li> Dependent module (dependent library instances in most case); </li>
+ <li> Source files; </li>
+ <li> Sections if module is not library; </li>
+ <li> Output (different for library module and driver module); </li>
+ <li> Clean; </li>
+ <li> Clean all. </li>
+ </ul>
+
+ @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) {
+ //
+ // <delete includeemptydirs="true">
+ // <fileset dir="${DEST_DIR_OUTPUT}" includes="" excludes="" />
+ // </delete>
+ //
+ 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) {
+ //
+ // <delete includeemptydirs="true">
+ // <fileset dir="${DEST_DIR_OUTPUT}" includes="" excludes="" />
+ // </delete>
+ //
+ 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);
+
+ //
+ // <delete includeemptydirs="true">
+ // <fileset dir="${DEST_DIR_DEBUG}" includes="" />
+ // </delete>
+ //
+ 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<String, String> passDownMap = new LinkedHashMap<String, String>();
+ 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 <em>LIB</em> command, else call the <em>GenFfs</em> 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<String> mProtocolList = new HashSet<String>();
+
+ ///
+ /// The Ppi list which recorded in module or library surface area and its
+ /// dependency on library instance surface area.
+ ///
+ private Set<String> mPpiList = new HashSet<String>();
+
+ ///
+ /// The Guid list which recoreded in module or library surface area and it's
+ /// dependence on library instance surface area.
+ ///
+ private Set<String> mGuidList = new HashSet<String>();
+
+ ///
+ /// The dependence package list which recoreded in module or library surface
+ /// area and it's dependence on library instance surface area.
+ ///
+ private List<PackageIdentification> mDepPkgList = new LinkedList<PackageIdentification>();
+
+ ///
+ /// 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<String[]> libConstructList = new ArrayList<String[]>();
+ private List<String[]> libDestructList = new ArrayList<String[]>();
+
+ ///
+ /// List to store SetVirtalAddressMapCallBack, ExitBootServiceCallBack
+ ///
+ private List<String> setVirtalAddList = new ArrayList<String>();
+ private List<String> exitBootServiceList = new ArrayList<String>();
+
+ 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<String> libClassIncludeH;
+ String moduleType;
+ // List<String> headerFileList;
+ List<String> 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 <AutoGen.h> at beginning of AutoGen.c
+ //
+ fileBuffer.append(CommonDefinition.INCLUDEAUTOGENH);
+
+ //
+ // Get the native MSA file infomation. Since before call autogen,
+ // the MSA native <Externs> information were overrided. So before
+ // process <Externs> it should be set the DOC as the Native MSA info.
+ //
+ Map<String, XmlObject> doc = GlobalData.getNativeMsa(this.moduleId);
+ saq.push(doc);
+ //
+ // Write <Extern>
+ // 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<String> libClassIncludeH;
+ String moduleType;
+ List<String> 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<String> LibraryClassToAutogenH(String[] libClassList)
+ throws EdkException {
+ Set<String> includeStrList = new LinkedHashSet<String>();
+ 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<String> depPkgToAutogenH(PackageIdentification[] packageNameList,
+ String moduleType) throws AutoGenException {
+
+ List<String> includeStrList = new LinkedList<String>();
+ 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 <ModuleEntryPoint> & <ModuleUnloadImage>
+ 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 <PPIs> 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 <Protocol>
+ 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 <Guids> 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<String[]> 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<String[]> 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 <SetVirtualAddressMapCallBack> and
+ <ExitBootServicesCallBack> infomation to AutoGen.c
+
+ @param fileBuffer
+ String buffer for AutoGen.c
+ @throws BuildException
+ **/
+ void ExternCallBackToAutoGenC(StringBuffer fileBuffer)
+ throws EdkException {
+ //
+ // Collect module's <SetVirtualAddressMapCallBack> and
+ // <ExitBootServiceCallBack> 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 <SetVirtualAddressMapCallBack>
+ // and <ExitBootServicesCallBack>
+ //
+ 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<ModuleIdentification> 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<String, XmlObject> libDoc = GlobalData.getDoc(libInstanceId, this.arch);
+ saq.push(libDoc);
+ //
+ // Get <PPis>, <Protocols>, <Guids> 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<String, ModuleIdentification> libClassMap = new HashMap<String, ModuleIdentification>();
+
+ ///
+ /// The map of library instance and its implemet libraryClass.
+ ///
+ private Map<ModuleIdentification, String[]> libInstanceMap = new HashMap<ModuleIdentification, String[]>();
+
+ ///
+ /// 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<LibraryInstanceNode> libInstanceList = new ArrayList<LibraryInstanceNode>();
+
+ /**
+ 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<String, XmlObject> 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<ModuleIdentification> orderLibInstance() {
+ List<ModuleIdentification> orderList = new ArrayList<ModuleIdentification>();
+ //
+ // Stack of node which track the library instance name ant its visiting
+ // flag.
+ //
+ List<Node> stackList = new ArrayList<Node>();
+ 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<ModuleIdentification> 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<Node> 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
+ + " <AutoGen.h>"
+ + 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<String> strList = new LinkedHashSet<String>();
+ 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<FpdModuleIdentification, GenBuildThread> allThreads = new LinkedHashMap<FpdModuleIdentification, GenBuildThread>();
+
+ List<String> queueList = new ArrayList<String>();
+
+ 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<String> 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<FpdModuleIdentification> currentQueueModules = fvs.get(queueList.get(currentQueueCode));
+
+ if (currentQueueModules == null) {
+ ++currentQueueCode;
+ continue ;
+ }
+ Iterator<FpdModuleIdentification> 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<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = saq.getFpdModules();
+
+ //
+ // For every Module lists in FPD file.
+ //
+ Set<FpdModuleIdentification> keys = moduleSAs.keySet();
+ Iterator<FpdModuleIdentification> 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<FpdModuleIdentification> dependencies = new LinkedHashSet<FpdModuleIdentification>();
+
+ 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;
+
+/**
+ <code>FpdParserTask</code> is an ANT task. The main function is parsing Framework
+ Platform Descritpion (FPD) XML file and generating its ANT build script for
+ corresponding platform.
+
+ <p>The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR
+ and BUILD_DIR. </p>
+
+ <p>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). </p>
+
+ <p>FpdParserTask task stores all FPD information to GlobalData. And parse
+ tools definition file to set up compiler options for different Target and
+ different ToolChainTag. </p>
+
+ <p>The method parseFpdFile is also prepared for single module build. </p>
+
+ @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<FpdModuleIdentification, String> outfiles = new LinkedHashMap<FpdModuleIdentification, String>();
+
+ ///
+ /// Mapping from FV name to its modules
+ ///
+ Map<String, Set<FpdModuleIdentification>> fvs = new HashMap<String, Set<FpdModuleIdentification>>();
+
+ ///
+ /// FpdParserTask can specify some ANT properties.
+ ///
+ private Vector<Property> properties = new Vector<Property>();
+
+ 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:
+
+ <ul>
+ <li>Initialize global information (Framework DB, SPD files and all MSA files
+ listed in SPD). This step will execute only once in whole build process;</li>
+ <li>Parse specified FPD file; </li>
+ <li>Generate FV.inf files; </li>
+ <li>Generate PlatformName_build.xml file for Flatform build; </li>
+ <li>Collect PCD information. </li>
+ </ul>
+
+ @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<FpdModuleIdentification> moduleSeqSet = getModuleSequenceForFv(validFv[i]);
+
+ Set<FpdModuleIdentification> 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<FpdModuleIdentification> 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<String, XmlObject> map = new HashMap<String, XmlObject>();
+ 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<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = saq.getFpdModules();
+
+ //
+ // For every Module lists in FPD file.
+ //
+ Set<FpdModuleIdentification> 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<FpdModuleIdentification> set = fvs.get(fvNameArray[i]);
+ set.add(fpdModuleId);
+ } else {
+ Set<FpdModuleIdentification> set = new LinkedHashSet<FpdModuleIdentification>();
+ set.add(fpdModuleId);
+ fvs.put(fvNameArray[i], set);
+ }
+ }
+ }
+
+ /**
+ Get the suffix based on module type. Current relationship are listed:
+
+ <pre>
+ <b>ModuleType</b> <b>Suffix</b>
+ 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
+ </pre>
+
+ @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<FpdModuleIdentification> iter = outfiles.keySet().iterator();
+ while (iter.hasNext()) {
+ FpdModuleIdentification fpdModuleId = iter.next();
+
+ if (fpdModuleId.getModule().equals(moduleId)) {
+ archs += fpdModuleId.getArch() + " ";
+ }
+ }
+
+ return archs;
+ }
+
+ private Set<FpdModuleIdentification> getModuleSequenceForFv(String fvName) throws EdkException {
+ Node node = saq.getFpdModuleSequence(fvName);
+ Set<FpdModuleIdentification> result = new LinkedHashSet<FpdModuleIdentification>();
+
+ 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<FpdModuleIdentification> 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<FpdModuleIdentification, String> outfiles;
+
+ ///
+ /// Mapping from FV name to its modules
+ ///
+ private Map<String, Set<FpdModuleIdentification>> fvs = new HashMap<String, Set<FpdModuleIdentification>>();
+
+
+ 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<FpdModuleIdentification, String> outfiles, Map<String, Set<FpdModuleIdentification>> 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<FpdModuleIdentification> set = fvs.get(validFv[i]);
+ Iterator<FpdModuleIdentification> iter = set.iterator();
+ while (iter.hasNext()) {
+ FpdModuleIdentification fpdModuleId = iter.next();
+ applySingleModule(document, ele, fpdModuleId);
+ }
+ }
+ }
+
+ //
+ // Get all other modules
+ //
+ Iterator<String> fvsNameIter = fvs.keySet().iterator();
+
+ while (fvsNameIter.hasNext()) {
+ String fvName = fvsNameIter.next();
+ if (!isContain(validFv, fvName)) {
+ Set<FpdModuleIdentification> 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<String> nameList = new ArrayList<String>();
+
+ /**
+ 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<String> 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<String> nameList = new ArrayList<String>();
+
+ /**
+ 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<FpdModuleIdentification, List<String>> map = new LinkedHashMap<FpdModuleIdentification, List<String> >(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<String> 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<FpdModuleIdentification> iter = map.keySet().iterator();
+ List<String> 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<String> 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<String> list = new Vector<String>(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.
+
+ <p>Note that all global information are initialized incrementally. All data will
+ parse and record only of necessary during build time. </p>
+
+ @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<PackageIdentification> packageList = new HashSet<PackageIdentification>();
+
+ private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();
+
+ ///
+ /// Every detail SPD informations: Module list, Library class definition,
+ /// Package header file, GUID/PPI/Protocol definitions
+ ///
+ private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();
+
+ ///
+ /// Build informations are divided into three parts:
+ /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA
+ ///
+ private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();
+
+ private static Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
+
+ private static Map<String, XmlObject> fpdBuildOptionsMap = new HashMap<String, XmlObject>();
+
+ private static XmlObject fpdBuildOptions;
+
+ private static XmlObject fpdDynamicPcds;
+
+ ///
+ /// Parsed modules list
+ ///
+ private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
+
+ ///
+ /// built modules list with ARCH, TARGET, TOOLCHAIN
+ ///
+ private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();
+
+ ///
+ /// 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<FpdModuleIdentification, ToolChainMap> moduleToolChainOption = new HashMap<FpdModuleIdentification, ToolChainMap>();
+ private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainFamilyOption = new HashMap<FpdModuleIdentification, ToolChainMap>();
+
+ /**
+ 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<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();
+ Iterator<DbPathAndFilename> 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<DbPathAndFilename> platforms = db.getFrameworkDatabase().getPlatformList().getFilenameList();
+ Iterator<DbPathAndFilename> 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<String, XmlObject> fpdDocMap = new HashMap<String, XmlObject>();
+ 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<String, XmlObject> doc) throws EdkException{
+ Map<String, XmlObject> result = new HashMap<String, XmlObject>();
+ 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.
+
+ <p>Note that surface area parsing is incremental. That means the method will
+ only parse the MSA files if necessary. </p>
+
+ @param fpdModuleId Module ID with arch
+ @return ModuleSA info and MSA info for fpdModuleId
+ @throws BuildException Can't find MSA
+ **/
+ public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws EdkException{
+ if (parsedModules.containsKey(fpdModuleId)) {
+ return parsedModules.get(fpdModuleId);
+ }
+ Map<String, XmlObject> doc = new HashMap<String, XmlObject>();
+ 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<String, XmlObject> 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.
+
+ <p>Note that MSA parsing is incremental. That means the method will
+ only to parse the MSA files when never parsed before. </p>
+
+ @param moduleName the base name of the module
+ @return the native MSA information
+ @throws BuildException
+ MSA file is not valid
+ **/
+ public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws EdkException {
+ if (nativeMsa.containsKey(moduleId)) {
+ return nativeMsa.get(moduleId);
+ }
+ File msaFile = getMsaFile(moduleId);
+ Map<String, XmlObject> msaMap = getNativeMsa(msaFile);
+ nativeMsa.put(moduleId, msaMap);
+ return msaMap;
+ }
+
+ public synchronized static Map<String, XmlObject> 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<String, XmlObject> msaMap = new HashMap<String, XmlObject>();
+ 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<String, XmlObject> 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<ModuleIdentification> getModules(PackageIdentification packageId){
+ Spd spd = spdTable.get(packageId);
+ if (spd == null ) {
+ Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();
+ 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<PackageIdentification> 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<PackageIdentification> 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<PackageIdentification> 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<ModuleIdentification> modules = spd.getModules();
+ Iterator<ModuleIdentification> 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<PackageIdentification> 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<FpdModuleIdentification, XmlObject>
+ getFpdModuleSaXmlObject(String xmlObjectName) {
+ Set<FpdModuleIdentification> fpdModuleSASet = fpdModuleSA.keySet();
+ Iterator item = fpdModuleSASet.iterator();
+
+
+ Map<FpdModuleIdentification, XmlObject> SAPcdBuildDef = new HashMap<FpdModuleIdentification, XmlObject>();
+ Map<String, XmlObject> SANode = new HashMap<String, XmlObject>();
+ 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<FpdModuleIdentification,XmlObject> getFpdPcdBuildDefinitions() {
+ Map<FpdModuleIdentification,XmlObject> 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:
+
+ <p>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.
+
+ <p>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.
+
+ <p>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.
+
+ <p>Then, BIN_DIR is BUILD_DIR/TARGET/TOOLCHAIN/ARCH;
+
+ <p>FV_DIR is BUILD_DIR/TARGET/TOOLCHAIN/FV;
+
+ <p>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<HashMap<String, String>> propertyTableStack = new Stack<HashMap<String, String>>();
+ //
+ // The very original properties
+ //
+ private static HashMap<String, String> orgPropertyTable = null;
+ //
+ // The last changes of properties
+ //
+ private static HashMap<String, String> oldPropertyTable = null;
+ //
+ // The current changes of properties
+ //
+ private static HashMap<String, String> 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<String, String>();
+
+ 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<String, String>();
+ }
+
+ /**
+ 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<String, String>)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<String, String>)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<ModuleIdentification, File> msaInfo = new HashMap<ModuleIdentification, File>();
+
+ ///
+ /// Map of module info.
+ /// Key : moduletype
+ /// Value: moduletype related include file
+ ///
+ Map<String, String> packageHeaderInfo = new HashMap<String, String>();
+
+ ///
+ /// Map of PPI info.
+ /// Key : PPI name
+ /// value: String[] a. PPI C_NAME; b. PPI GUID;
+ ///
+ Map<String, String[]> ppiInfo = new HashMap<String, String[]>();
+
+ ///
+ /// Map of Protocol info.
+ /// Key : Protocol name
+ /// value: String[] a. Protocol C_NAME; b. Protocol GUID;
+ ///
+ Map<String, String[]> protocolInfo = new HashMap<String, String[]>();
+
+ ///
+ /// Map of Guid info.
+ /// Key : Guid name
+ /// value: String[] a. Guid C_NAME; b. Guid's GUID;
+ ///
+ Map<String, String[]> guidInfo = new HashMap<String, String[]>();
+
+ ///
+ /// Map of Guid info
+ /// Key: GuidCName
+ /// value: String Guid's GUID
+ ///
+ Map<String, String> guidCnameInfo = new HashMap<String, String>();
+
+ /// Map of library class and its exposed header file.
+ /// Key : library class name
+ /// value : library class corresponding header file
+ ///
+ Map<String, String[]> libClassHeaderList = new HashMap<String, String[]>();
+
+ ///
+ /// 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<String, XmlObject> spdDocMap = new HashMap<String, XmlObject>();
+ 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<String, XmlObject> 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<String, String> 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<String> 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<String, String[]> 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<ModuleIdentification> 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<String, XmlObject> map = null;
+
+ //
+ // mapStack is used to do nested query
+ //
+ private Stack<Map<String, XmlObject>> mapStack = new Stack<Map<String, XmlObject>>();
+
+ //
+ // 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<String, XmlObject> 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<String, XmlObject> 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<Object> result = new ArrayList<Object>();
+ 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<String[]> outputList = new ArrayList<String[]>();
+ 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<String> archList = null;
+ String cmd = null;
+ String optionName = null;
+
+ Object[] returns = get(from, xPath);
+ if (returns == null) {
+ return new String[0][5];
+ }
+
+ List<String[]> optionList = new ArrayList<String[]>();
+ 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<String>();
+ 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 <xxxHeader>/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<PackageIdentification> packageIdList = new ArrayList<PackageIdentification>();
+ 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<String> libraryClassName = new ArrayList<String>();
+ 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<String> protocolList = new ArrayList<String>();
+
+ 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<String> protocolNotifyList = new ArrayList<String>();
+
+ 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<String> ppiNotifyList = new ArrayList<String>();
+ 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<String> ppiList = new ArrayList<String>();
+ 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<String> guidList = new ArrayList<String>();
+ 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<Extern> externList = new ArrayList<Extern>();
+ 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<FpdModuleIdentification, Map<String, XmlObject>> 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<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleMap = new LinkedHashMap<FpdModuleIdentification, Map<String, XmlObject>>();
+
+ if (result == null) {
+ return fpdModuleMap;
+ }
+
+ for (int i = 0; i < result.length; i++) {
+ //
+ // Get Fpd SA Module element node and add to ObjectMap.
+ //
+ Map<String, XmlObject> ObjectMap = new HashMap<String, XmlObject>();
+ 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<FpdModuleIdentification, Map<String,
+ // Object>>.
+ //
+ 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<String[]> list = new ArrayList<String[]>();
+ for (int i = 0; i < queryResult.length; i++) {
+ FvImagesDocument.FvImages.FvImage.FvImageOptions item = (FvImagesDocument.FvImages.FvImage.FvImageOptions) queryResult[i];
+ List<FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue> 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<String[]> list = new ArrayList<String[]>();
+ for (int i = 0; i < queryResult.length; i++) {
+
+ FvImagesDocument.FvImages.FvImage.FvImageOptions item = (FvImagesDocument.FvImages.FvImage.FvImageOptions) queryResult[i];
+ List<FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue> 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<String[]> list = new ArrayList<String[]>();
+ for (int i = 0; i < queryResult.length; i++) {
+ FvImagesDocument.FvImages.FvImage.FvImageOptions item = (FvImagesDocument.FvImages.FvImage.FvImageOptions) queryResult[i];
+ List<FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue> 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 <extern> String[0]
+ * If no specification element in the <extern>
+ *
+ */
+
+ 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<String> filenameList = ((MsaFilesDocument.MsaFiles) returns[0])
+ .getFilenameList();
+ return filenameList.toArray(new String[filenameList.size()]);
+ }
+
+ /**
+ * Reteive
+ */
+ public Map<String, String[]> getSpdLibraryClasses() {
+ String[] xPath = new String[] { "/LibraryClassDeclarations/LibraryClass" };
+
+ Object[] returns = get("PackageSurfaceArea", xPath);
+
+ //
+ // Create Map, Key - LibraryClass, String[] - LibraryClass Header file.
+ //
+ Map<String, String[]> libClassHeaderMap = new HashMap<String, String[]>();
+
+ 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<String, String> getSpdPackageHeaderFiles() {
+ String[] xPath = new String[] { "/PackageHeaders/IncludePkgHeader" };
+
+ Object[] returns = get("PackageSurfaceArea", xPath);
+
+ //
+ // Create Map, Key - ModuleType, String - PackageInclude Header file.
+ //
+ Map<String, String> packageIncludeMap = new HashMap<String, String>();
+
+ 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<String, String[]> getSpdGuid() {
+ String[] xPath = new String[] { "/GuidDeclarations/Entry" };
+
+ Object[] returns = get("PackageSurfaceArea", xPath);
+
+ //
+ // Create Map, Key - GuidName, String[] - C_NAME & GUID value.
+ //
+ Map<String, String[]> guidDeclMap = new HashMap<String, String[]>();
+ 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<String, String[]> getSpdProtocol() {
+ String[] xPath = new String[] { "/ProtocolDeclarations/Entry" };
+
+ Object[] returns = get("PackageSurfaceArea", xPath);
+
+ //
+ // Create Map, Key - protocolName, String[] - C_NAME & GUID value.
+ //
+ Map<String, String[]> protoclMap = new HashMap<String, String[]>();
+
+ 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<String, String[2]> 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<String, String[]> getSpdPpi() {
+ String[] xPath = new String[] { "/PpiDeclarations/Entry" };
+
+ Object[] returns = get("PackageSurfaceArea", xPath);
+
+ //
+ // Create Map, Key - protocolName, String[] - C_NAME & GUID value.
+ //
+ Map<String, String[]> ppiMap = new HashMap<String, String[]>();
+
+ 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.
+
+ <p>Currently, use BaseName and ARCH to identify a module. It will enhance
+ in the next version. </p>
+
+ @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 <PcdCoded> 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<UsageInstance> 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<UsageInstance>();
+
+ //
+ // Try to find all PCD defined in library's PCD in all <PcdEntry> in module's
+ // <ModuleSA> 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 <ModuleSA> 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 <ModuleSA> 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<UsageInstance>();
+
+ //
+ // Try to find all PCD defined in library's PCD in all <PcdEntry> in module's
+ // <ModuleSA> 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 <ModuleSA> 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 <ModuleSA> 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
+ // <VariableName>0x0053 0x0065 0x0074 0x0075 0x0070</VariableName>.
+ // 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<UnicodeString> al;
+ private ArrayList<String> alComments;
+ private String phase;
+ int stringTableCharNum;
+
+ public StringTable (String phase) {
+ this.phase = phase;
+ al = new ArrayList<UnicodeString>();
+ alComments = new ArrayList<String>();
+ 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<CStructTypeDeclaration> declaList, HashMap<String, String> 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<ArrayList<Integer>> al;
+ private ArrayList<String> alComments;
+ private int len;
+ private String phase;
+
+ public SizeTable (String phase) {
+ al = new ArrayList<ArrayList<Integer>>();
+ alComments = new ArrayList<String>();
+ 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<CStructTypeDeclaration> declaList, HashMap<String, String> 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<String> getInstantiation () {
+ final String comma = ",";
+ ArrayList<String> Output = new ArrayList<String>();
+
+ Output.add("/* SizeTable */");
+ Output.add("{");
+ if (al.size() == 0) {
+ Output.add("\t0");
+ } else {
+ for (int index = 0; index < al.size(); index++) {
+ ArrayList<Integer> 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<Integer> 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<UUID> al;
+ private ArrayList<String> alComments;
+ private String phase;
+ private int len;
+ private int bodyLineNum;
+
+ public GuidTable (String phase) {
+ this.phase = phase;
+ al = new ArrayList<UUID>();
+ alComments = new ArrayList<String>();
+ 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<CStructTypeDeclaration> declaList, HashMap<String, String> 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<String> getInstantiation () {
+ ArrayList<String> Output = new ArrayList<String>();
+
+ 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<Integer[]> al;
+ private ArrayList<String> alComment;
+ private String phase;
+ private int len;
+
+ public SkuIdTable (String phase) {
+ this.phase = phase;
+ al = new ArrayList<Integer[]>();
+ alComment = new ArrayList<String>();
+ 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<CStructTypeDeclaration> declaList, HashMap<String, String> 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<String> getInstantiation () {
+ ArrayList<String> Output = new ArrayList<String> ();
+
+ 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<String> al;
+ private ArrayList<String> alComment;
+ private String phase;
+ private int len;
+
+ public LocalTokenNumberTable (String phase) {
+ this.phase = phase;
+ al = new ArrayList<String>();
+ alComment = new ArrayList<String>();
+
+ 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<CStructTypeDeclaration> declaList, HashMap<String, String> 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<String> getInstantiation () {
+ ArrayList<String> output = new ArrayList<String>();
+
+ 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<ExTriplet> al;
+ private Map<ExTriplet, String> alComment;
+ private String phase;
+ private int len;
+ private int bodyLineNum;
+
+ public ExMapTable (String phase) {
+ this.phase = phase;
+ al = new ArrayList<ExTriplet>();
+ alComment = new HashMap<ExTriplet, String>();
+ 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<CStructTypeDeclaration> declaList, HashMap<String, String> 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<String> getInstantiation () {
+ ArrayList<String> Output = new ArrayList<String>();
+
+ 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<ExTriplet> {
+ 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<ExTriplet> 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<Token> 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.
+
+ <p>We have two PCD dynamic(ex) database for the Framework implementation. One
+ for PEI phase and the other for DXE phase. </p>
+
+ @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<Token> 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<Token> alTokens, List<Token> nexTokens, List<Token> 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<CStructTypeDeclaration> declaList,
+ HashMap<String, String> 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<Token> tokens,
+ ArrayList<CStructTypeDeclaration> cStructDeclList,
+ HashMap<String, String> 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<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();
+ HashMap<String, String> cStructInstTable = new HashMap<String, String>();
+
+ List<Token> nexTokens = new ArrayList<Token> ();
+ List<Token> exTokens = new ArrayList<Token> ();
+
+ 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 <String, String> 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 <String, String> genCStructCode(
+ ArrayList<CStructTypeDeclaration> declaList,
+ HashMap<String, String> instTable,
+ String phase
+ ) {
+
+ int i;
+ HashMap <String, String> result = new HashMap<String, String>();
+ HashMap <Integer, ArrayList<String>> alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();
+ HashMap <Integer, ArrayList<String>> alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();
+ HashMap <Integer, ArrayList<String>> alignmentInitInst = new HashMap<Integer, ArrayList<String>>();
+
+ //
+ // Initialize the storage for each alignment
+ //
+ for (i = 8; i > 0; i>>=1) {
+ alignmentInitDecl.put(new Integer(i), new ArrayList<String>());
+ alignmentInitInst.put(new Integer(i), new ArrayList<String>());
+ alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());
+ }
+
+ 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<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));
+ ArrayList<String> 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<String> 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<CStructTypeDeclaration> declaList, HashMap<String, String> 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<Token> alPei = new ArrayList<Token> ();
+ ArrayList<Token> alDxe = new ArrayList<Token> ();
+
+ 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<ModuleInfo> the component array.
+ @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.
+
+ **/
+ public List<ModulePcdInfoFromFpd> getComponentsFromFpd()
+ throws PlatformPcdPreprocessException {
+ List<ModulePcdInfoFromFpd> allModules = new ArrayList<ModulePcdInfoFromFpd>();
+ Map<FpdModuleIdentification, XmlObject> 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 <DynamicPcdBuildDefinition> 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<DynamicPcdBuildDefinitions.PcdBuildData> 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 <PcdDynamicBuildDescriptions> 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 <DynamicPcdBuildDefinition> from FPD file.
+
+ @return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.
+ @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.
+
+ **/
+ public List<DynamicPcdBuildDefinitions.PcdBuildData>
+ getAllDynamicPcdInfoFromFpd()
+ throws PlatformPcdPreprocessException {
+ DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;
+
+ //
+ // Open fpd document to get <DynamicPcdBuildDefinition> 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<String> keyList = new ArrayList<String>(256);
+ List<String> valueList = new ArrayList<String>(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<ToolChainKey> 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<String> targets = new LinkedHashSet<String>();
+ //
+ // tool chain tag name set
+ //
+ private Set<String> tagnames = new LinkedHashSet<String>();
+ //
+ // build archs set
+ //
+ private Set<String> archs = new LinkedHashSet<String>();
+ //
+ // build commands set
+ //
+ private Set<String> commands = new LinkedHashSet<String>();
+
+ /**
+ 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<String> 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<String> 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<String> 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<String> 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<String> Merged Set object
+ **/
+ private Set<String> union(Set<String> set1, Set<String> set2) {
+ Set<String> result = new LinkedHashSet<String>();
+ 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<String> The intersected Set object
+ **/
+ private Set<String> intersection(Set<String> set1, Set<String> set2) {
+ Set<String> result = new LinkedHashSet<String>();
+ 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<ToolChainKey> {
+ 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<ToolChainKey, String> map = null;
+
+ /**
+ Public constructor. It just initializes the private Map object.
+ **/
+ public ToolChainMap() {
+ this.map = new HashMap<ToolChainKey, String>();
+ }
+
+ /**
+ 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<ToolChainKey> A set of ToolChainKey objects
+ */
+ public Set<ToolChainKey> keySet() {
+ return (Set<ToolChainKey>)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;
+ }
+}
|