summaryrefslogtreecommitdiff
path: root/Tools/Source/GenBuild
diff options
context:
space:
mode:
authorbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-04-21 22:54:32 +0000
committerbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-04-21 22:54:32 +0000
commit878ddf1fc3540a715f63594ed22b6929e881afb4 (patch)
treec56c44dac138137b510e1fba7c3efe5e4d84bea2 /Tools/Source/GenBuild
downloadedk2-platforms-878ddf1fc3540a715f63594ed22b6929e881afb4.tar.xz
Initial import.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'Tools/Source/GenBuild')
-rw-r--r--Tools/Source/GenBuild/GenBuild.tasks11
-rw-r--r--Tools/Source/GenBuild/build.xml51
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java52
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java390
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/FileProcess.java225
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java1170
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java190
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java2006
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java306
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java257
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/fpd/FpdModuleIdentification.java131
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java808
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/DpFile.java129
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/DpFileList.java50
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java637
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java178
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java412
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java55
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/OnDependency.java121
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/OutputManager.java176
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java354
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/Spd.java414
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java218
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java1109
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/global/VariableTask.java71
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/action/ActionMessage.java129
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/action/BuildAction.java114
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java669
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java452
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java130
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/action/UIAction.java83
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java306
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/entity/SkuInstance.java40
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java641
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java471
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/exception/BuildActionException.java33
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java31
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/exception/UIException.java31
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java184
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java218
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java529
-rw-r--r--Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java60
42 files changed, 13642 insertions, 0 deletions
diff --git a/Tools/Source/GenBuild/GenBuild.tasks b/Tools/Source/GenBuild/GenBuild.tasks
new file mode 100644
index 0000000000..c767cfb1dd
--- /dev/null
+++ b/Tools/Source/GenBuild/GenBuild.tasks
@@ -0,0 +1,11 @@
+FPDParser = org.tianocore.build.fpd.FpdParserTask
+bl = org.tianocore.build.global.VariableTask
+bf = org.tianocore.build.global.LibBuildFileGenerator
+GenBuild = org.tianocore.build.GenBuildTask
+ToolChainSetup = org.tianocore.build.toolchain.ToolChainTask
+Expand = org.tianocore.build.ExpandTask
+OutputDirSetup = org.tianocore.build.OutputDirSetupTask
+OnDependency = org.tianocore.build.global.OnDependency
+sourcefiles = org.tianocore.build.global.DpFileList
+targetfiles = org.tianocore.build.global.DpFileList
+file = org.tianocore.build.global.DpFile
diff --git a/Tools/Source/GenBuild/build.xml b/Tools/Source/GenBuild/build.xml
new file mode 100644
index 0000000000..38801f1495
--- /dev/null
+++ b/Tools/Source/GenBuild/build.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<project name="GenBuild" default="all" basedir=".">
+
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+ <property environment="env"/>
+ <property name="WORKSPACE" value="${env.WORKSPACE}"/>
+ <path id="classpath">
+ <fileset dir="${WORKSPACE}/Tools/Jars" includes="SurfaceArea.jar"/>
+ <fileset dir="${WORKSPACE}/Tools/bin/xmlbeans/lib" includes="*.jar"/>
+ </path>
+ <property name="buildDir" value="build"/>
+ <property name="installLocation" value="${WORKSPACE}/Tools/Jars"/>
+ <target name="all" depends="install"/>
+ <target name="source">
+ <mkdir dir="${buildDir}"/>
+ <javac srcdir="." destdir="${buildDir}">
+ <classpath refid="classpath"/>
+ <compilerarg value="-Xlint"/>
+ </javac>
+ </target>
+ <target name="clean">
+ <delete dir="${buildDir}"/>
+ </target>
+ <target name="cleanall">
+ <delete dir="${buildDir}"/>
+ <if>
+ <available file="${installLocation}/GenBuild.jar"/>
+ <then>
+ <echo message="You must manually remove the file: ${installLocation}/GenBuild.jar"/>
+ <echo message="Java has already loaded the file, and cannot remove it within ANT!"/>
+ </then>
+ </if>
+ </target>
+ <target name="install" depends="source">
+ <copy file="GenBuild.tasks" toDir="${buildDir}"/>
+ <jar destfile="${installLocation}/GenBuild.jar"
+ basedir="${buildDir}"
+ includes="**"
+ />
+ </target>
+</project>
diff --git a/Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java b/Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java
new file mode 100644
index 0000000000..d3df8cf7a6
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java
@@ -0,0 +1,52 @@
+/** @file
+ This file is ANT task Expand.
+
+ Expand task is used to prepare ANT properties for further build.
+
+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 org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+import org.tianocore.build.global.GlobalData;
+
+/**
+ Expand task is used to prepare ANT properties for further build.
+ <p>Current, prepare the dependent Library instance list for <code>LIBS</code></p>
+
+ @since GenBuild 1.0
+**/
+public class ExpandTask extends Task {
+
+ /**
+ Public construct method. It is necessary for ANT task.
+ **/
+ public ExpandTask () {
+ }
+
+ /**
+ ANT task's entry point, will be called after init().
+
+ Set <code>LIBS</code> for further build usage.
+ **/
+ public void execute() throws BuildException {
+
+ String[] libraries = GlobalData.getModuleLibrary(getProject().getProperty("BASE_NAME"));
+ String str = "";
+ for (int i = 0; i < libraries.length; i ++){
+ str += " " + GlobalData.getLibrary(libraries[i]);
+ }
+ getProject().setProperty("LIBS", str);
+
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java b/Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java
new file mode 100644
index 0000000000..dbbddba3db
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java
@@ -0,0 +1,390 @@
+/** @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.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Vector;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlObject;
+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;
+
+/**
+ <p><code>FfsProcess</code> is a class to find the corresponding FFS layout. </p>
+
+ <p>Property <code>COMMON_FILE</code> specified which file to search. The element
+ in <code>COMMON_FILE</code> is like following: </p>
+
+ <pre>
+ &lt;Ffs type="APPLICATION"&gt;
+ &lt;Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_APPLICATION" /&gt;
+ &lt;Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" /&gt;
+ &lt;Sections EncapsulationType="Compress"&gt;
+ &lt;Sections EncapsulationType="Guid-Defined"&gt;
+ &lt;Section SectionType="EFI_SECTION_PE32" /&gt;
+ &lt;Section SectionType="EFI_SECTION_USER_INTERFACE" /&gt;
+ &lt;Section SectionType="EFI_SECTION_VERSION" /&gt;
+ &lt;/Sections&gt;
+ &lt;/Sections&gt;
+ &lt;/Ffs&gt;
+ </pre>
+
+ @since GenBuild 1.0
+**/
+public class FfsProcess {
+
+ ///
+ /// Xml Document Node for corresponding FFS layout
+ ///
+ private Node ffs;
+
+ ///
+ /// 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 = { { "EFI_SECTION_FREEFORM_SUBTYPE_GUID", ".sec" },
+ { "EFI_SECTION_VERSION", ".ver" },
+ { "EFI_SECTION_USER_INTERFACE", ".ui" },
+ { "EFI_SECTION_DXE_DEPEX", ".dpx" },
+ { "EFI_SECTION_PEI_DEPEX", ".dpx" },
+ { "EFI_SECTION_PE32", ".pe32" },
+ { "EFI_SECTION_PIC", ".pic" },
+ { "EFI_SECTION_TE", ".tes" },
+ { "EFI_SECTION_RAW", ".sec" },
+ { "EFI_SECTION_COMPRESSION", ".sec" },
+ { "EFI_SECTION_GUID_DEFINED", ".sec" },
+ { "EFI_SECTION_COMPATIBILITY16", ".sec" },
+ { "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", ".sec" } };
+
+ /**
+ 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>COMMON_FILE</code> if it
+ does not specify in module's surface area.
+
+ @param buildType Current module's component type
+ @param project Ant project
+ @return whether find the corresponding FFS layout
+ @throws BuildException
+ If specified COMMON_FILE XML file is not valide.
+ **/
+ public boolean initSections(String buildType, Project project) throws BuildException {
+ //
+ // first try to sections defined in PLATFORM level
+ //
+
+ //
+ // if module specify sections itself, it's okay
+ // otherwise find sections from WORKSPACE default setting with
+ // ComponentType
+ //
+ if (ffs == null) {
+ File file = new File(project.getProperty("COMMON_FILE"));
+ //
+ // if common file is not existed, just return
+ //
+ if (!file.exists()) {
+ return false;
+ }
+ DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
+ try {
+ DocumentBuilder dombuilder = domfac.newDocumentBuilder();
+ InputStream is = new FileInputStream(file);
+ Document doc = dombuilder.parse(is);
+ Element root = doc.getDocumentElement();
+ NodeList items = root.getChildNodes();
+ for (int i = 0; i < items.getLength(); i++) {
+ Node node = items.item(i);
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ String nodeName = node.getNodeName();
+ if (nodeName.equalsIgnoreCase("Ffs")) {
+ NamedNodeMap attr = node.getAttributes();
+ Node type = attr.getNamedItem("type");
+ if (type != null) {
+ if (isMatch(type.getTextContent(), buildType)) {
+ ffs = node;
+ return true;
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new BuildException("Parse COMMON_FILE [" + file.getPath() + "] error!\n" + e.getMessage());
+ }
+ }
+ if (ffs == null) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ 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 (ffs == null) {
+ return new String[0];
+ }
+ Vector<String> sectionList = new Vector<String>();
+ XmlCursor cursor = null;
+ try {
+ cursor = XmlObject.Factory.parse(ffs).newCursor();
+ } catch (Exception e) {
+ return null;
+ }
+ int mode = MODE_NONE;
+ Element root = document.createElement("genffsfile");
+ root.setAttribute("outputDir", "${BIN_DIR}");
+ root.setAttribute("BaseName", basename);
+ root.setAttribute("fileGuid", guid);
+ cursor.toFirstChild();
+ if (cursor.toFirstChild()) {
+ do {
+ if (cursor.getName().getLocalPart().equalsIgnoreCase("Attribute")) {
+ String name = cursor.getAttributeText(new QName("Name"));
+ String value = cursor.getAttributeText(new QName("Value"));
+ root.setAttribute(changeAttributeName(name), value);
+ } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {
+ cursor.push();
+ dealSection(mode, document, root, cursor, sectionList);
+ cursor.pop();
+ } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {
+ cursor.push();
+ dealSections(mode, document, root, 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}\\" + targetFilename);
+ targetEle.appendChild(fileEle);
+ outofdateEle.appendChild(targetEle);
+ Element sequentialEle = document.createElement("sequential");
+ sequentialEle.appendChild(root);
+ 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"));
+ if (type == 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;
+ if (type.equalsIgnoreCase("COMPRESS")) {
+ mode = MODE_COMPRESS;
+ //
+ // <compress compressName = "dummy">
+ //
+ ele = doc.createElement("compress");
+ ele.setAttribute("compressName", "dummy");
+ } else {
+ mode = MODE_GUID_DEFINED;
+ //
+ // <tool toolName="${OEMTOOLPATH}\toolname"
+ // outputPath = "${DEST_DIR_OUTPUT}">
+ //
+ ele = doc.createElement("tool");
+ ele.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "Bin"
+ + File.separatorChar + "GenCRC32Section");
+ ele.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");
+ }
+ if (cursor.toFirstChild()) {
+ do {
+ if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {
+ cursor.push();
+ dealSection(mode, doc, ele, cursor, list);
+ cursor.pop();
+ } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {
+ cursor.push();
+ dealSections(mode, doc, ele, 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"));
+ list.addElement(type);
+ if (mode == MODE_GUID_DEFINED) {
+ //
+ // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>
+ //
+ Element ele = doc.createElement("input");
+ ele.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));
+ root.appendChild(ele);
+ } else {
+ //
+ // <sectFile fileName= "..."/>
+ //
+ Element ele = doc.createElement("sectFile");
+ ele.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));
+ 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/Source/GenBuild/org/tianocore/build/FileProcess.java b/Tools/Source/GenBuild/org/tianocore/build/FileProcess.java
new file mode 100644
index 0000000000..87650af827
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/FileProcess.java
@@ -0,0 +1,225 @@
+/** @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 java.util.Set;
+
+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>
+ .c | C_Code
+ .asm | Assembly
+ .s | IPF_Assembly_Code
+ .h | Header
+ .lib | Static_Library
+ .i | IPF_PP_Code
+ .vfr | Vfr
+ .uni | Unicode
+ .dxs | Dependency_File
+ .bmp | Graphics
+ .efi | EFI
+ </pre>
+
+ @since GenBuild 1.0
+**/
+public class FileProcess {
+ ///
+ /// The mapping information about source suffix, result suffix, file type.
+ ///
+ public final String[][] fileTypes = { { ".c", ".obj", "C_Code" }, { ".asm", ".obj", "Assembly" },
+ { ".s", ".obj", "IPF_Assembly_Code" }, { ".h", "", "Header" },
+ { ".lib", "", "Static_Library" }, { ".src", ".c", "" },
+ { ".i", ".obj", "IPF_PP_Code" }, { ".vfr", ".obj", "Vfr" },
+ { ".uni", "", "Unicode" }, { ".dxs", "", "Dependency_File" },
+ { ".bmp", "", "Graphics" }, { ".efi", "", "EFI" } };
+
+ ///
+ /// Current ANT context.
+ ///
+ private Project project;
+
+ ///
+ /// Current module's include pathes
+ ///
+ private Set<String> includes;
+
+ ///
+ /// Current source files.
+ ///
+ private Set<String> sourceFiles;
+
+ ///
+ /// 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, Set<String> includes, Set<String> sourceFiles, Document document) {
+ this.document = document;
+ this.includes = includes;
+ this.project = project;
+ this.sourceFiles = sourceFiles;
+ }
+
+ /**
+ 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) {
+ boolean flag = false;
+ for (int i = 0; i < fileTypes.length; i++) {
+ if (filename.toLowerCase().endsWith(fileTypes[i][0])) {
+ flag = true;
+ parseFile(filename, fileTypes[i][2], root);
+ }
+ }
+ if (!flag) {
+ System.out.println("Warning: File " + filename + " is not known from its suffix.");
+ }
+ }
+
+ /**
+ 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("Unicode")){
+ return ;
+ }
+ unicodeExist= true;
+ } else {
+ if (filetype.equalsIgnoreCase("Unicode")){
+ return ;
+ }
+ }
+ sourceFiles.add(filename);
+ if (filetype.equalsIgnoreCase("Header")) {
+ return;
+ }
+ if (filetype.equalsIgnoreCase("IPF_PP_Code")) {
+ 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;
+ if (sourceFile.getPath().endsWith("AutoGen.c")) {
+ sourceFilepath = ".";
+ sourceFilename = "AutoGen";
+ 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);
+ }
+ }
+ // <Build_filetype FILEPATH="" FILENAME="" />
+ Element ele = document.createElement("Build_" + filetype);
+ ele.setAttribute("FILEPATH", sourceFilepath);
+ ele.setAttribute("FILENAME", sourceFilename);
+ String[] includePaths = includes.toArray(new String[includes.size()]);
+ Element includesEle = document.createElement("EXTRA.INC");
+ for (int i = 0; i < includePaths.length; i++) {
+ Element includeEle = document.createElement("includepath");
+ includeEle.setAttribute("path", includePaths[i]);
+ includesEle.appendChild(includeEle);
+ }
+ ele.appendChild(includesEle);
+ root.appendChild(ele);
+ }
+} \ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java b/Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java
new file mode 100644
index 0000000000..2d91991b8a
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java
@@ -0,0 +1,1170 @@
+/** @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.HashMap;
+import java.util.HashSet;
+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 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.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Ant;
+import org.apache.xmlbeans.XmlObject;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.tianocore.build.autogen.AutoGen;
+import org.tianocore.build.autogen.CommonDefinition;
+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.toolchain.ToolChainFactory;
+import org.tianocore.FilenameDocument;
+import org.tianocore.MsaHeaderDocument;
+import org.tianocore.MsaLibHeaderDocument;
+
+/**
+ <p>
+ <code>GenBuildTask</code> is an ANT task that can be used in ANT build
+ system. The main function of this task is to parse module's surface area,
+ then generate the corresponding <em>BaseName_build.xml</em> (the real ANT
+ build script) and call this to build the module.
+ </p>
+
+ <p>
+ The usage is (take module <em>HelloWorld</em> for example):
+ </p>
+
+ <pre>
+ &lt;GenBuild baseName=&quot;HelloWorld&quot;
+ mbdFilename=&quot;${MODULE_DIR}/HelloWorld.mbd&quot;
+ msaFilename=&quot;${MODULE_DIR}/HelloWorld.msa&quot;/&gt;
+ </pre>
+
+ <p>
+ This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and
+ <em>AutoGen.h</em>. The task also parses the development environment
+ configuration files, such as collecting package information, setting compiler
+ flags and so on.
+ </p>
+
+
+ @since GenBuild 1.0
+**/
+public class GenBuildTask extends Task {
+
+ ///
+ /// Module surface area file.
+ ///
+ File msaFilename;
+
+ ///
+ /// Module build description file.
+ ///
+ File mbdFilename;
+
+ ///
+ /// Module surface area information after overrided.
+ ///
+ public Map<String, XmlObject> map = new HashMap<String, XmlObject>();
+
+ ///
+ /// Module's base name.
+ ///
+ private String baseName;
+
+ ///
+ /// Current build Arch, such as IA32, X64, IPF and so on.
+ ///
+ private String arch;
+
+ ///
+ /// Module's GUID (Globally Unique Identifier).
+ ///
+ private String guid;
+
+ ///
+ /// Module's component type, such as SEC, LIBRARY, BS_DRIVER and so on.
+ ///
+ private String componentType;
+
+ ///
+ /// This value is used in build time. Override module's component type. When
+ /// search FFS (Sections information) in common file, buildtype instead of
+ /// component type.
+ ///
+ private String buildType;
+
+ ///
+ /// List all required includes for current build module.
+ ///
+ public Set<String> includes = new LinkedHashSet<String>();
+
+ ///
+ /// List all libraries for current build module.
+ ///
+ public Set<String> libraries = new LinkedHashSet<String>();
+
+ ///
+ /// List all source files for current build module.
+ ///
+ public Set<String> sourceFiles = new LinkedHashSet<String>();
+
+ ///
+ /// Flag to identify what surface area files are specified. Current value is
+ /// <em>NO_SA</em>, <em>ONLY_MSA</em>, <em>ONLY_LIBMSA</em>,
+ /// <em>MSA_AND_MBD</em> or <em>LIBMSA_AND_LIBMBD</em>.
+ ///
+ /// @see org.tianocore.build.global.GlobaData
+ ///
+ private int flag = GlobalData.NO_SA;
+
+ ///
+ /// The information at the header of <em>build.xml</em>.
+ ///
+ private String info = "====================================================================\n"
+ + "DO NOT EDIT \n"
+ + "File auto-generated by build utility\n"
+ + "\n"
+ + "Abstract:\n"
+ + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"
+ + "=====================================================================";
+
+ /**
+ Public construct method. It is necessary for ANT task.
+ **/
+ public GenBuildTask() {
+ }
+
+ /**
+ ANT task's entry point, will be called after init(). The main steps is described
+ as following:
+ <ul>
+ <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute
+ only once in whole build process; </li>
+ <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> Restore some important ANT property. If current build is single module
+ build, here will set many default values; </li>
+ <li> Get the current module's overridded surface area information from
+ global data; </li>
+ <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and
+ DEST_DIR_DEBUG; </li>
+ <li> Get module dependent library instances and include pathes; </li>
+ <li> Judge whether current module is built. If yes, skip it; </li>
+ <li> Call AutoGen and PCD to generate AutoGen.c & AutoGen.h </li>
+ <li> Set up the compile flags; </li>
+ <li> Generate BaseName_build.xml; </li>
+ <li> Call to BaseName_build.xml, and build the current module. </li>
+ </ul>
+
+ <p>Build is dependent on BuildMacro.xml which define many macro. </p>
+
+ @throws BuildException
+ From module build, exception from module surface area invalid.
+ **/
+ public void execute() throws BuildException {
+ System.out.println("Module [" + baseName + "] start.");
+ OutputManager.update(getProject());
+ GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db",
+ getProject().getProperty("WORKSPACE_DIR"));
+ recallFixedProperties();
+ arch = getProject().getProperty("ARCH");
+ arch = arch.toUpperCase();
+ map = GlobalData.getDoc(baseName);
+ //
+ // Initialize SurfaceAreaQuery
+ //
+ SurfaceAreaQuery.setDoc(map);
+ //
+ // Setup Output Management
+ //
+ String[] outdir = SurfaceAreaQuery.getOutputDirectory();
+ OutputManager.update(getProject(), outdir[1], outdir[0]);
+
+ updateIncludesAndLibraries();
+
+ if (GlobalData.isModuleBuilt(baseName, arch)) {
+ return;
+ } else {
+ GlobalData.registerBuiltModule(baseName, arch);
+ }
+ //
+ // Call AutoGen
+ //
+ AutoGen autogen = new AutoGen(getProject().getProperty("DEST_DIR_DEBUG"), baseName, arch);
+ autogen.genAutogen();
+ //
+ // Update parameters
+ //
+ updateParameters();
+ //
+ // Update flags like CC_FLAGS, LIB_FLAGS etc.
+ //
+ flagsSetup();
+ GlobalData.addLibrary(baseName, getProject().getProperty("BIN_DIR") + File.separatorChar + baseName + ".lib");
+ GlobalData.addModuleLibrary(baseName, libraries);
+ //
+ // If ComponentType is USER_DEFINED,
+ // then call the exist BaseName_build.xml directly.
+ //
+ if (buildType.equalsIgnoreCase("CUSTOM_BUILD")) {
+ System.out.println("Call user-defined " + baseName + "_build.xml");
+ Ant ant = new Ant();
+ ant.setProject(getProject());
+ ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + baseName + "_build.xml");
+ ant.setInheritAll(true);
+ ant.init();
+ ant.execute();
+ return;
+ }
+ //
+ // Generate ${BASE_NAME}_build.xml file
+ //
+ System.out.println("Generate " + baseName + "_build.xml");
+ genBuildFile();
+ System.out.println("Call the " + baseName + "_build.xml");
+ Ant ant = new Ant();
+ ant.setProject(getProject());
+ ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName + "_build.xml");
+ ant.setInheritAll(true);
+ ant.init();
+ ant.execute();
+ }
+
+ /**
+ Get the dependent library instances and include package name from
+ surface area, and initialize module include pathes.
+
+ **/
+ private void updateIncludesAndLibraries() {
+ List<String> rawIncludes = SurfaceAreaQuery.getIncludePackageName(arch);
+ if (rawIncludes != null) {
+ Iterator iter = rawIncludes.iterator();
+ while (iter.hasNext()) {
+ String packageName = (String) iter.next();
+ includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)
+ + File.separatorChar + "Include");
+ includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)
+ + File.separatorChar + "Include" + File.separatorChar + "${ARCH}");
+ }
+ }
+ includes.add("${DEST_DIR_DEBUG}");
+ List<String> rawLibraries = SurfaceAreaQuery.getLibraryInstance(this.arch, CommonDefinition.AlwaysConsumed);
+ if (rawLibraries != null) {
+ Iterator iter = rawLibraries.iterator();
+ while (iter.hasNext()) {
+ libraries.add((String) iter.next());
+ }
+ }
+ normalize();
+ }
+
+ /**
+ Normalize all dependent library instance and include pathes' format.
+
+ **/
+ private void normalize() {
+ String[] includesArray = includes.toArray(new String[includes.size()]);
+ includes.clear();
+ for (int i = 0; i < includesArray.length; i++) {
+ includes.add((new File(includesArray[i])).getPath());
+ }
+ String[] librariesArray = libraries.toArray(new String[libraries.size()]);
+ libraries.clear();
+ for (int i = 0; i < librariesArray.length; i++) {
+ libraries.add((new File(librariesArray[i])).getPath());
+ }
+ }
+
+ /**
+ Restore some important ANT property. If current build is single module
+ build, here will set many default values.
+
+ <p> If current build is single module build, then the default <code>ARCH</code>
+ is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>,
+ <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>
+
+ <p> Note that for package build, package name is stored in <code>PLATFORM</code>
+ and package directory is stored in <code>PLATFORM_DIR</code>. </p>
+
+ @see org.tianocore.build.global.OutputManager
+ **/
+ private void recallFixedProperties() {
+ //
+ // If build is for module build
+ //
+ if (getProject().getProperty("PACKAGE_DIR") == null) {
+ ToolChainFactory toolChainFactory = new ToolChainFactory(getProject());
+ toolChainFactory.setupToolChain();
+ //
+ // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO
+ //
+ if (getProject().getProperty("ARCH") == null) {
+ getProject().setProperty("ARCH", "IA32");
+ }
+ String packageName = GlobalData.getPackageNameForModule(baseName);
+ getProject().setProperty("PACKAGE", packageName);
+
+ String packageDir = GlobalData.getPackagePath(packageName);
+ getProject().setProperty("PACKAGE_DIR",
+ getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + packageDir);
+
+ getProject().setProperty("TARGET", toolChainFactory.getCurrentTarget());
+
+ getProject().setProperty("MODULE_DIR",
+ getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));
+ }
+ if (OutputManager.PLATFORM != null) {
+ getProject().setProperty("PLATFORM", OutputManager.PLATFORM);
+ }
+ if (OutputManager.PLATFORM_DIR != null) {
+ getProject().setProperty("PLATFORM_DIR", OutputManager.PLATFORM_DIR);
+ }
+ }
+
+ /**
+ 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.
+ **/
+ private void genBuildFile() throws BuildException {
+ 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", base_name);
+ //
+ root.setAttribute("default", "main");
+ root.setAttribute("basedir", ".");
+ //
+ // element for External ANT tasks
+ //
+ root.appendChild(document.createComment("Apply external ANT tasks"));
+ Element ele = document.createElement("taskdef");
+ ele.setAttribute("resource", "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);
+ //
+ // elements for Properties
+ //
+ root.appendChild(document.createComment("All Properties"));
+ ele = document.createElement("property");
+ ele.setAttribute("name", "BASE_NAME");
+ ele.setAttribute("value", baseName);
+ 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", "main");
+ 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
+ //
+ 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(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName
+ + "_build.xml");
+ //
+ // generate all directory path
+ //
+ (new File(file.getParent())).mkdirs();
+ Result result = new StreamResult(file);
+ //
+ // Write the DOM document to the file
+ //
+ Transformer xformer = TransformerFactory.newInstance().newTransformer();
+ xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+ xformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ xformer.transform(source, result);
+ } catch (Exception ex) {
+ throw new BuildException("Module [" + baseName + "] generating build file failed.\n" + ex.getMessage());
+ }
+ }
+
+ /**
+ 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) {
+ String[] libinstances = libraries.toArray(new String[libraries.size()]);
+ for (int i = 0; i < libinstances.length; i++) {
+ File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");
+
+ Element ifEle = document.createElement("if");
+ Element availableEle = document.createElement("available");
+ availableEle.setAttribute("file", file.getPath());
+ ifEle.appendChild(availableEle);
+ Element elseEle = document.createElement("then");
+
+ Element ele = document.createElement("ant");
+ ele.setAttribute("antfile", file.getPath());
+ ele.setAttribute("inheritAll", "false");
+ ele.setAttribute("target", libinstances[i] + "_clean");
+ //
+ // Workspace_DIR
+ //
+ Element property = document.createElement("property");
+ property.setAttribute("name", "WORKSPACE_DIR");
+ property.setAttribute("value", "${WORKSPACE_DIR}");
+ ele.appendChild(property);
+ //
+ // Package Dir
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE_DIR");
+ property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
+ + GlobalData.getPackagePathForModule(libinstances[i]));
+ ele.appendChild(property);
+ //
+ // ARCH
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "ARCH");
+ property.setAttribute("value", "${ARCH}");
+ ele.appendChild(property);
+ //
+ // TARGET
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "TARGET");
+ property.setAttribute("value", "${TARGET}");
+ ele.appendChild(property);
+ //
+ // PACKAGE
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE");
+ property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));
+ ele.appendChild(property);
+
+ elseEle.appendChild(ele);
+ ifEle.appendChild(elseEle);
+ root.appendChild(ifEle);
+ }
+ }
+
+ /**
+ 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) {
+ String[] libinstances = libraries.toArray(new String[libraries.size()]);
+ for (int i = 0; i < libinstances.length; i++) {
+ File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");
+
+ Element ifEle = document.createElement("if");
+ Element availableEle = document.createElement("available");
+ availableEle.setAttribute("file", file.getPath());
+ ifEle.appendChild(availableEle);
+ Element elseEle = document.createElement("then");
+
+ Element ele = document.createElement("ant");
+ ele.setAttribute("antfile", file.getPath());
+ ele.setAttribute("inheritAll", "false");
+ ele.setAttribute("target", libinstances[i] + "_cleanall");
+ //
+ // Workspace_DIR
+ //
+ Element property = document.createElement("property");
+ property.setAttribute("name", "WORKSPACE_DIR");
+ property.setAttribute("value", "${WORKSPACE_DIR}");
+ ele.appendChild(property);
+ //
+ // Package Dir
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE_DIR");
+ property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
+ + GlobalData.getPackagePathForModule(libinstances[i]));
+ ele.appendChild(property);
+ //
+ // ARCH
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "ARCH");
+ property.setAttribute("value", "${ARCH}");
+ ele.appendChild(property);
+ //
+ // TARGET
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "TARGET");
+ property.setAttribute("value", "${TARGET}");
+ ele.appendChild(property);
+ //
+ // PACKAGE
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE");
+ property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));
+ ele.appendChild(property);
+
+ elseEle.appendChild(ele);
+ ifEle.appendChild(elseEle);
+ root.appendChild(ifEle);
+ }
+ }
+
+ /**
+ 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) {
+ String[] libinstances = libraries.toArray(new String[libraries.size()]);
+ for (int i = 0; i < libinstances.length; i++) {
+ Element ele = document.createElement("ant");
+ File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");
+ ele.setAttribute("antfile", file.getPath());
+ ele.setAttribute("inheritAll", "false");
+ ele.setAttribute("target", libinstances[i]);
+ //
+ // Workspace_DIR
+ //
+ Element property = document.createElement("property");
+ property.setAttribute("name", "WORKSPACE_DIR");
+ property.setAttribute("value", "${WORKSPACE_DIR}");
+ ele.appendChild(property);
+ //
+ // Package Dir
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE_DIR");
+ property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
+ + GlobalData.getPackagePathForModule(libinstances[i]));
+ ele.appendChild(property);
+ //
+ // ARCH
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "ARCH");
+ property.setAttribute("value", "${ARCH}");
+ ele.appendChild(property);
+ //
+ // TARGET
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "TARGET");
+ property.setAttribute("value", "${TARGET}");
+ ele.appendChild(property);
+ //
+ // PACKAGE
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE");
+ property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));
+ ele.appendChild(property);
+ root.appendChild(ele);
+ }
+ Element expand = document.createElement("Expand");
+ root.appendChild(expand);
+ }
+
+ /**
+ 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) {
+ FileProcess fileProcess = new FileProcess();
+ fileProcess.init(getProject(), includes, sourceFiles, document);
+ Node[] files = this.getSourceFiles();
+ //
+ // Parse all unicode files
+ //
+ for (int i = 0; i < files.length; i++) {
+ String filetype = getFiletype(files[i]);
+ if (filetype != null) {
+ fileProcess.parseFile(getFilename(files[i]), filetype, root, true);
+ } else {
+ fileProcess.parseFile(getFilename(files[i]), root, true);
+ }
+ }
+ if (fileProcess.isUnicodeExist()) {
+ Element ele = document.createElement("Build_Unicode_Database");
+ ele.setAttribute("FILEPATH", ".");
+ ele.setAttribute("FILENAME", "${BASE_NAME}");
+ root.appendChild(ele);
+ }
+
+ //
+ // Parse AutoGen.c & AutoGen.h
+ //
+ if (!baseName.equalsIgnoreCase("Shell")) {
+ fileProcess.parseFile(getProject().getProperty("DEST_DIR_DEBUG") + File.separatorChar + "AutoGen.c", root,
+ false);
+ }
+ //
+ // Parse all source files
+ //
+ for (int i = 0; i < files.length; i++) {
+ String filetype = getFiletype(files[i]);
+ if (filetype != null) {
+ fileProcess.parseFile(getFilename(files[i]), filetype, root, false);
+ } else {
+ fileProcess.parseFile(getFilename(files[i]), root, false);
+ }
+ }
+ //
+ // root.appendChild(parallelEle);
+ //
+ Iterator iter = sourceFiles.iterator();
+ String str = "";
+ while (iter.hasNext()) {
+ str += " " + (String) iter.next();
+ }
+ getProject().setProperty("SOURCE_FILES", str);
+ }
+
+ /**
+ 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 (fp.initSections(buildType, getProject())) {
+ String targetFilename = guid + "-" + baseName + FpdParserTask.getSuffix(componentType);
+ String[] list = fp.getGenSectionElements(document, baseName, guid, 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 (flag == GlobalData.ONLY_LIBMSA || flag == GlobalData.LIBMSA_AND_LIBMBD) {
+ //
+ // call Lib command
+ //
+ Element cc = document.createElement("Build_Library");
+ cc.setAttribute("FILENAME", baseName);
+ root.appendChild(cc);
+ }
+ //
+ // if it is a module but library
+ //
+ else {
+ if (fp.getFfsNode() != null) {
+ root.appendChild(fp.getFfsNode());
+ }
+ }
+ }
+
+ /**
+ Get file name from node. If some wrong, return string with zero length.
+
+ @param node Filename node of MSA/MBD or specified in each Section
+ @return File name
+ **/
+ private String getFilename(Node node) {
+ String path = null;
+ String filename = "${MODULE_DIR}" + File.separatorChar;
+ String str = "";
+ try {
+ FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);
+ str = file.getFilename().getStringValue().trim();
+ path = file.getFilename().getPath();
+ } catch (Exception e) {
+ str = "";
+ }
+ if (path != null) {
+ filename += path + File.separatorChar + str;
+ } else {
+ filename += str;
+ }
+ return getProject().replaceProperties(filename);
+ }
+
+ /**
+ Get file type from node. If some wrong or not specified, return
+ <code>null</code>.
+
+ @param node Filename node of MSA/MBD or specified in each Section
+ @return File type
+ **/
+ private String getFiletype(Node node) {
+ String str = null;
+ try {
+ FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);
+ str = file.getFilename().getFileType();
+ } catch (Exception e) {
+ str = null;
+ }
+ return str;
+ }
+
+ /**
+ Return all source files but AutoGen.c.
+
+ @return source files Node array
+ **/
+ public Node[] getSourceFiles() {
+ XmlObject[] files = SurfaceAreaQuery.getSourceFiles(arch);
+ if (files == null) {
+ return new Node[0];
+ }
+ Vector<Node> vector = new Vector<Node>();
+ for (int i = 0; i < files.length; i++) {
+ vector.addElement(files[i].getDomNode());
+ }
+ //
+ // To be consider sourcefiles from Sections
+ //
+ return vector.toArray(new Node[vector.size()]);
+ }
+
+ /**
+ Get current module's base name.
+
+ @return base name
+ **/
+ public String getBaseName() {
+ return baseName;
+ }
+
+ /**
+ Set MBD surface area file. For ANT use.
+
+ @param mbdFilename Surface Area file
+ **/
+ public void setMbdFilename(File mbdFilename) {
+ this.mbdFilename = mbdFilename;
+ }
+
+ /**
+ Set MSA surface area file. For ANT use.
+
+ @param msaFilename Surface Area file
+ **/
+ public void setMsaFilename(File msaFilename) {
+ this.msaFilename = msaFilename;
+ }
+
+ /**
+ Compile flags setup.
+
+ <p> Take command <code>CC</code> and arch <code>IA32</code> for example,
+ Those flags are from <code>ToolChainFactory</code>: </p>
+ <ul>
+ <li> IA32_CC </li>
+ <li> IA32_CC_STD_FLAGS </li>
+ <li> IA32_CC_GLOBAL_FLAGS </li>
+ <li> IA32_CC_GLOBAL_ADD_FLAGS </li>
+ <li> IA32_CC_GLOBAL_SUB_FLAGS </li>
+ </ul>
+ Those flags can user-define:
+ <ul>
+ <li> IA32_CC_PROJ_FLAGS </li>
+ <li> IA32_CC_PROJ_ADD_FLAGS </li>
+ <li> IA32_CC_PROJ_SUB_FLAGS </li>
+ <li> CC_PROJ_FLAGS </li>
+ <li> CC_PROJ_ADD_FLAGS </li>
+ <li> CC_PROJ_SUB_FLAGS </li>
+ <li> CC_FLAGS </li>
+ <li> IA32_CC_FLAGS </li>
+ </ul>
+
+ <p> The final flags is composed of STD, GLOBAL and PROJ. If CC_FLAGS or
+ IA32_CC_FLAGS is specified, STD, GLOBAL and PROJ will not affect. </p>
+
+ Note that the <code>ToolChainFactory</code> executes only once
+ during whole build process.
+ **/
+ private void flagsSetup() {
+ Project project = getProject();
+ //
+ // If ToolChain has been set up before, do nothing.
+ //
+ ToolChainFactory toolChainFactory = new ToolChainFactory(project);
+ toolChainFactory.setupToolChain();
+
+ String[] cmd = ToolChainFactory.commandType;
+ Set<String> addSet = new HashSet<String>(40);
+ Set<String> subSet = new HashSet<String>(40);
+ for (int i = 0; i < cmd.length; i++) {
+ String str = ToolChainFactory.getValue(arch + "_" + cmd[i]);
+ //
+ // Command line path+command name
+ //
+ if (str != null) {
+ project.setProperty(cmd[i], str);
+ }
+ //
+ // ARCH_CMD_STD_FLAGS
+ //
+ str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_STD_FLAGS");
+ if (str != null) {
+ putFlagsToSet(addSet, str);
+ project.setProperty(cmd[i] + "_STD_FLAGS", str);
+ }
+ //
+ // ARCH_CMD_GLOBAL_FLAGS
+ //
+ str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_FLAGS");
+ if (str != null) {
+ putFlagsToSet(addSet, str);
+ }
+ //
+ // ARCH_CMD_GLOBAL_ADD_FLAGS
+ //
+ str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_ADD_FLAGS");
+ if (str != null) {
+ putFlagsToSet(addSet, str);
+ }
+ //
+ // ARCH_CMD_GLOBAL_SUB_FLAGS
+ //
+ str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_SUB_FLAGS");
+ if (str != null) {
+ putFlagsToSet(subSet, str);
+ }
+ //
+ // ARCH_CMD_PROJ_FLAGS
+ //
+ str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_FLAGS");
+ if (str != null) {
+ putFlagsToSet(addSet, str);
+ }
+ //
+ // ARCH_CMD_PROG_FLAGS
+ //
+ str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_ADD_FLAGS");
+ if (str != null) {
+ putFlagsToSet(addSet, str);
+ }
+ //
+ // ARCH_CMD_PROG_FLAGS
+ //
+ str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_SUB_FLAGS");
+ if (str != null) {
+ putFlagsToSet(subSet, str);
+ }
+ //
+ // CMD_PROJ_FLAGS
+ //
+ str = project.getProperty(cmd[i] + "_PROJ_FLAGS");
+ if (str != null) {
+ putFlagsToSet(addSet, str);
+ }
+ //
+ // CMD_PROG_FLAGS
+ //
+ str = project.getProperty(cmd[i] + "_PROJ_ADD_FLAGS");
+ if (str != null) {
+ putFlagsToSet(addSet, str);
+ }
+ //
+ // CMD_PROG_FLAGS
+ //
+ str = project.getProperty(cmd[i] + "_PROJ_SUB_FLAGS");
+ if (str != null) {
+ putFlagsToSet(subSet, str);
+ }
+ //
+ // If IA32_CC_FLAGS or IA32_LIB_FLAGS .. has defined in BuildOptions
+ //
+ if ((str = project.getProperty(arch + "_" + cmd[i] + "_FLAGS")) != null) {
+ project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));
+ addSet.clear();
+ subSet.clear();
+ putFlagsToSet(addSet, project.replaceProperties(str));
+ project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));
+ addSet.clear();
+ subSet.clear();
+ }
+ //
+ // If CC_FLAGS or LIB_FLAGS .. has defined in BuildOptions
+ //
+ else if ((str = project.getProperty(cmd[i] + "_FLAGS")) != null) {
+ project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));
+ addSet.clear();
+ subSet.clear();
+ putFlagsToSet(addSet, project.replaceProperties(str));
+ project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));
+ addSet.clear();
+ subSet.clear();
+ } else {
+ project.setProperty(cmd[i] + "_FLAGS", getFlags(addSet, subSet));
+ addSet.clear();
+ subSet.clear();
+ }
+ }
+ project.setProperty("C_FLAGS", project.getProperty("CC_FLAGS"));
+ }
+
+ /**
+ Initialize some properties will be used in current module build, including
+ user-defined option from <em>Option</em> of <em>BuildOptions</em> in
+ surface area.
+ **/
+ private void updateParameters() {
+ getProject().setProperty("OBJECTS", "");
+ getProject().setProperty("SDB_FILES", "");
+ getProject().setProperty("BASE_NAME", baseName);
+ if (map.get("MsaHeader") != null) {
+ flag = GlobalData.MSA_AND_MBD;
+ MsaHeaderDocument.MsaHeader header = ((MsaHeaderDocument) map.get("MsaHeader")).getMsaHeader();
+ guid = header.getGuid().getStringValue();
+ componentType = header.getComponentType().toString();
+ }
+
+ else if (map.get("MsaLibHeader") != null) {
+ flag = GlobalData.LIBMSA_AND_LIBMBD;
+ MsaLibHeaderDocument.MsaLibHeader header = ((MsaLibHeaderDocument) map.get("MsaLibHeader"))
+ .getMsaLibHeader();
+ guid = header.getGuid().getStringValue();
+ componentType = header.getComponentType().toString();
+ }
+
+ if (componentType != null) {
+ getProject().setProperty("COMPONENT_TYPE", componentType);
+ }
+
+ if (guid != null) {
+ getProject().setProperty("FILE_GUID", guid);
+ }
+ //
+ // Get all options and set to properties
+ //
+ String[][] options = SurfaceAreaQuery.getOptions(arch);
+ for (int i = 0; i < options.length; i++) {
+ if (options[i][0] != null && options[i][1] != null) {
+ getProject().setProperty(options[i][0], getProject().replaceProperties(options[i][1]));
+ }
+ }
+
+ buildType = getProject().getProperty("BUILD_TYPE");
+ if (buildType == null) {
+ buildType = componentType;
+ }
+
+ }
+
+ /**
+ 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) {
+ Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
+ Matcher matcher = myPattern.matcher(str + " ");
+ while (matcher.find()) {
+ String item = str.substring(matcher.start(1), matcher.end(1));
+ if (!set.contains(item)) {
+ 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 = getProject().replaceProperties((String) iter.next());
+ result += str.substring(1, str.length() - 1) + " ";
+ }
+ return result;
+ }
+
+ /**
+ Generate the flags string with original format. The format is defined by
+ Java Regulation Expression "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
+
+ <p>For example: </p>
+
+ <pre>
+ "/nologo", "/W3", "/WX"
+ "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
+ </pre>
+
+ @param add the add flags set
+ @param sub the sub flags set
+ @return flags with original format
+ **/
+ private String getRawFlags(Set<String> add, Set<String> sub) {
+ String result = "";
+ add.removeAll(sub);
+ Iterator iter = add.iterator();
+ while (iter.hasNext()) {
+ String str = getProject().replaceProperties((String) iter.next());
+ result += "\"" + str.substring(1, str.length() - 1) + "\", ";
+ }
+ return result;
+ }
+
+ /**
+ Set base name. For ANT use.
+
+ @param baseName Base name
+ **/
+ public void setBaseName(String baseName) {
+ this.baseName = baseName;
+ }
+
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java b/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java
new file mode 100644
index 0000000000..c2b7cc997b
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java
@@ -0,0 +1,190 @@
+/** @file
+
+ This file is an ANT task OutputDirSetupTask.
+
+ This task main purpose is to setup some necessary properties for Package,
+ Platform or Module clean.
+
+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.HashMap;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.xmlbeans.XmlObject;
+
+import org.tianocore.build.global.GlobalData;
+import org.tianocore.build.global.OutputManager;
+import org.tianocore.build.global.SurfaceAreaQuery;
+import org.tianocore.build.toolchain.ToolChainFactory;
+
+/**
+ <code>OutputDirSetupTask</code> is an ANT task that can be used in ANT build
+ system. The main function of this task is to initialize some basic information
+ for Package|Platform|Module clean or cleanall usage.
+
+ <p>Here is an example: </p>
+ <pre>
+ &lt;OutputDirSetup baseName="HelloWorld"
+ mbdFilename="${MODULE_DIR}\HelloWorld.mbd"
+ msaFilename="${MODULE_DIR}\HelloWorld.msa" /&gt;
+ </pre>
+
+ <p>Note that all this task doing is part of GenBuildTask. </p>
+
+ @since GenBuild 1.0
+ @see org.tianocore.build.GenBuildTask
+**/
+public class OutputDirSetupTask extends Task {
+
+ ///
+ /// Module surface area file.
+ ///
+ File msaFilename;
+
+ ///
+ /// Module build description file.
+ ///
+ File mbdFilename;
+
+ ///
+ /// Module surface area information after overrided.
+ ///
+ public Map<String, XmlObject> map = new HashMap<String, XmlObject>();
+
+ ///
+ /// Module's base name.
+ ///
+ private String baseName;
+
+ /**
+ Public construct method. It is necessary for ANT task.
+ **/
+ public OutputDirSetupTask () {
+ }
+
+ /**
+ ANT task's entry point, will be called after init(). The main steps is described
+ as following:
+ <ul>
+ <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute
+ only once in whole build process; </li>
+ <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> Restore some important ANT property. If current build is single module
+ build, here will set many default values; </li>
+ <li> Get the current module's overridded surface area information from
+ global data; </li>
+ <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and
+ DEST_DIR_DEBUG; </li>
+ </ul>
+
+ @throws BuildException
+ From module build, exception from module surface area invalid.
+ **/
+ public void execute() throws BuildException {
+ System.out.println("Deleting module [" + baseName + "] start.");
+ OutputManager.update(getProject());
+ GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db", getProject()
+ .getProperty("WORKSPACE_DIR"));
+ recallFixedProperties();
+ map = GlobalData.getDoc(baseName);
+ //
+ // Initialize SurfaceAreaQuery
+ //
+ SurfaceAreaQuery.setDoc(map);
+ //
+ // Setup Output Management
+ //
+ String[] outdir = SurfaceAreaQuery.getOutputDirectory();
+ OutputManager.update(getProject(), outdir[1], outdir[0]);
+ }
+
+ /**
+ Get current module's base name.
+
+ @return base name
+ **/
+ public String getBaseName() {
+ return baseName;
+ }
+
+ /**
+ Set base name. For ANT use.
+
+ @param baseName Base name
+ **/
+ public void setBaseName(String baseName) {
+ this.baseName = baseName;
+ }
+
+ /**
+ Set MBD surface area file. For ANT use.
+
+ @param mbdFilename Surface Area file
+ **/
+ public void setMbdFilename(File mbdFilename) {
+ this.mbdFilename = mbdFilename;
+ }
+
+ /**
+ Set MSA surface area file. For ANT use.
+
+ @param msaFilename Surface Area file
+ **/
+ public void setMsaFilename(File msaFilename) {
+ this.msaFilename = msaFilename;
+ }
+
+ /**
+ Restore some important ANT property. If current build is single module
+ build, here will set many default values.
+
+ <p> If current build is single module build, then the default <code>ARCH</code>
+ is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>,
+ <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>
+
+ <p> Note that for package build, package name is stored in <code>PLATFORM</code>
+ and package directory is stored in <code>PLATFORM_DIR</code>. </p>
+
+ @see org.tianocore.build.global.OutputManager
+ **/
+ private void recallFixedProperties(){
+ //
+ // If build is for module build
+ //
+ if (getProject().getProperty("PACKAGE_DIR") == null) {
+ ToolChainFactory toolChainFactory = new ToolChainFactory(getProject());
+ toolChainFactory.setupToolChain();
+ //
+ // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO
+ //
+ if (getProject().getProperty("ARCH") == null){
+ getProject().setProperty("ARCH", "IA32");
+ }
+ String packageName = GlobalData.getPackageNameForModule(baseName);
+ getProject().setProperty("PACKAGE", packageName);
+ String packageDir = GlobalData.getPackagePath(packageName);
+ getProject().setProperty("PACKAGE_DIR", getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + packageDir);
+ getProject().setProperty("TARGET", toolChainFactory.getCurrentTarget());
+ getProject().setProperty("MODULE_DIR", getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));
+ }
+ if (OutputManager.PLATFORM != null) {
+ getProject().setProperty("PLATFORM", OutputManager.PLATFORM);
+ }
+ if (OutputManager.PLATFORM_DIR != null) {
+ getProject().setProperty("PLATFORM_DIR", OutputManager.PLATFORM_DIR);
+ }
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java b/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
new file mode 100644
index 0000000000..f1e9c5b4ec
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
@@ -0,0 +1,2006 @@
+/** @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 org.tianocore.build.global.GlobalData;
+import org.tianocore.build.global.Spd;
+import org.tianocore.build.global.SurfaceAreaQuery;
+import org.tianocore.GuidsDocument;
+import org.tianocore.LibraryClassDocument.LibraryClass;
+import org.tianocore.PPIsDocument;
+import org.tianocore.ProtocolsDocument;
+import org.tianocore.build.pcd.action.PCDAutoGenAction;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.xmlbeans.XmlObject;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ 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 base name of module or library.
+ ///
+ private String baseName;
+
+ ///
+ /// The build architecture
+ ///
+ private String arch;
+
+ ///
+ /// PcdAutogen instance which is used to manage how to generate the PCD
+ /// information.
+ ///
+ private PCDAutoGenAction myPcdAutogen;
+
+ ///
+ /// The protocl list which records in module or library surface area and
+ /// it's dependence on library instance surface area.
+ ///
+ private List<String> mProtocolList = new ArrayList<String>();
+
+ ///
+ /// The Ppi list which recorded in module or library surface area and its
+ /// dependency on library instance surface area.
+ ///
+ private List<String> mPpiList = new ArrayList<String>();
+
+ ///
+ /// The Guid list which recoreded in module or library surface are and it's
+ /// dependence on library instance surface area.
+ ///
+ private List<GuidsDocument.Guids.GuidEntry> mGuidList = new ArrayList<GuidsDocument.Guids.GuidEntry>();
+
+ /**
+ Construct function
+
+ This function mainly initialize some member variable.
+
+ @param outputPath Output path of AutoGen file.
+ @param baseName Module base name.
+ @param arch Target architecture.
+ **/
+ public AutoGen(String outputPath, String baseName, String arch) {
+ this.outputPath = outputPath;
+ this.baseName = baseName;
+ this.arch = arch;
+
+ }
+
+ /**
+ 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 "true" successful, "false" failed.
+ **/
+ private boolean saveFile(String fileName, StringBuffer fileBuffer) {
+ try {
+ File autoGenH = new File(fileName);
+
+ //
+ // if the file exists, compare their content
+ //
+ if (autoGenH.exists()) {
+ FileReader fIn = new FileReader(autoGenH);
+ char[] oldFileBuffer = new char[(int) autoGenH.length()];
+ fIn.read(oldFileBuffer, 0, (int) autoGenH.length());
+ fIn.close();
+
+ //
+ // 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;
+ }
+ }
+ FileWriter fOut = new FileWriter(autoGenH);
+ fOut.write(fileBuffer.toString());
+ fOut.close();
+ } catch (Exception e) {
+ 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 BuildException {
+ try {
+ //
+ // If outputPath do not exist, create it.
+ //
+ File path = new File(outputPath);
+ path.mkdirs();
+
+ //
+ // Check current is library or not, then call the corresponding
+ // function.
+ //
+ if (SurfaceAreaQuery.getComponentType().equalsIgnoreCase(
+ CommonDefinition.LibraryStr)) {
+ libGenAutogen();
+ } else {
+ moduleGenAutogen();
+ }
+
+ } catch (Exception e) {
+ throw new BuildException(
+ "Failed to create AutoGen.c & AutoGen.h!\n"
+ + e.getMessage());
+ }
+ }
+
+ /**
+ moduleGenAutogen function
+
+ This function generates AutoGen.c & AutoGen.h for module.
+
+ @throws BuildException Faile to create module AutoGen.c & AutoGen.h.
+ **/
+ void moduleGenAutogen() throws BuildException {
+
+ try {
+ moduleGenAutogenC();
+ moduleGenAutogenH();
+ } catch (Exception e) {
+ throw new BuildException(
+ "Faile to create module AutoGen.c & AutoGen.h!\n"
+ + e.getMessage());
+ }
+ }
+
+ /**
+ libGenAutogen function
+
+ This function generates AutoGen.c & AutoGen.h for library.
+
+ @throws BuildException
+ Faile to create library AutoGen.c & AutoGen.h
+ **/
+ void libGenAutogen() throws BuildException {
+ try {
+ libGenAutogenC();
+ libGenAutogenH();
+ } catch (Exception e) {
+ throw new BuildException(
+ "Faile to create library AutoGen.c & AutoGen.h!\n"
+ + e.getMessage());
+ }
+ }
+
+ /**
+ moduleGenAutogenH
+
+ This function generates AutoGen.h for module.
+
+ @throws BuildException
+ Failed to generate AutoGen.h.
+ **/
+ void moduleGenAutogenH() throws BuildException {
+
+ List<String> libClassIncludeH;
+ String moduleType;
+ List<String> headerFileList;
+
+ StringBuffer fileBuffer = new StringBuffer(8192);
+
+ //
+ // Write Autogen.h header notation
+ //
+ fileBuffer.append(CommonDefinition.autogenHNotation);
+
+ //
+ // Add #ifndef ${BaseName}_AUTOGENH
+ // #def ${BseeName}_AUTOGENH
+ //
+ fileBuffer.append("#ifndef " + this.baseName.toUpperCase() + "_AUTOGENH\r\n");
+ fileBuffer.append("#define " + this.baseName.toUpperCase() + "_AUTOGENH\r\n\r\n");
+
+ //
+ // 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 = SurfaceAreaQuery.getModuleType();
+ switch (CommonDefinition.getModuleType(moduleType)) {
+ case CommonDefinition.ModuleTypeDxeCore:
+ case CommonDefinition.ModuleTypeDxeDriver:
+ case CommonDefinition.ModuleTypeDxeRuntimeDriver:
+ case CommonDefinition.ModuleTypeDxeSmmDriver:
+ case CommonDefinition.ModuleTypeDxeSalDriver:
+ case CommonDefinition.ModuleTypeUefiDriver:
+ case CommonDefinition.ModuleTypeUefiApplication:
+ fileBuffer.append(CommonDefinition.autoGenHLine1);
+ break;
+ default:
+ fileBuffer.append(CommonDefinition.autoGenHVersionDefault);
+ break;
+ }
+ switch (CommonDefinition.getModuleType(moduleType)) {
+ case CommonDefinition.ModuleTypeUefiDriver:
+ case CommonDefinition.ModuleTypeUefiApplication:
+ fileBuffer.append(CommonDefinition.autoGenHReleaseDefault);
+ break;
+ default:
+ fileBuffer.append(CommonDefinition.autoGenHLine2);
+ break;
+ }
+
+ //
+ // Add "extern int __make_me_compile_correctly;" at begin of
+ // AutoGen.h.
+ //
+ fileBuffer.append(CommonDefinition.autoGenHbegin);
+
+ //
+ // Write consumed package's mdouleInfo related .h file to autogen.h
+ //
+ List<String> consumedPkgList = SurfaceAreaQuery
+ .getIncludePackageName(this.arch);
+ if (consumedPkgList != null) {
+ headerFileList = IncludesToAutogenH(consumedPkgList, moduleType);
+ for (int i = 0; i < headerFileList.size(); i++) {
+ fileBuffer.append(headerFileList.get(i));
+ }
+ }
+
+ //
+ // Write library class's related *.h file to autogen.h.
+ //
+ LibraryClass[] libClassList = SurfaceAreaQuery
+ .getLibraryClassArray(CommonDefinition.AlwaysConsumed);
+ if (libClassList != null) {
+ libClassIncludeH = LibraryClassToAutogenH(libClassList);
+ for (int i = 0; i < libClassIncludeH.size(); i++) {
+ fileBuffer.append(libClassIncludeH.get(i));
+ }
+ }
+
+ libClassList = SurfaceAreaQuery
+ .getLibraryClassArray(CommonDefinition.AlwaysProduced);
+ if (libClassList != null) {
+ libClassIncludeH = LibraryClassToAutogenH(libClassList);
+ for (int i = 0; i < libClassIncludeH.size(); i++) {
+ fileBuffer.append(libClassIncludeH.get(i));
+ }
+ }
+ fileBuffer.append("\r\n");
+
+ //
+ // Write PCD autogen information to AutoGen.h.
+ //
+ if (this.myPcdAutogen != null) {
+ fileBuffer.append(this.myPcdAutogen.OutputH());
+ }
+
+ //
+ // 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 BuildException("Failed to generate AutoGen.h !!!");
+ }
+ }
+
+ /**
+ moduleGenAutogenC
+
+ This function generates AutoGen.c for module.
+
+ @throws BuildException
+ Failed to generate AutoGen.c.
+ **/
+ void moduleGenAutogenC() throws BuildException {
+
+ 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);
+
+ //
+ // Write DriverBinding/ComponentName/DriverConfiguration/DriverDialog
+ // to AutoGen.c
+ //
+ ExternsDriverBindingToAutoGenC(fileBuffer);
+
+ //
+ // Write DriverExitBootServicesEvent/DriverSetVirtualAddressMapEvent
+ // to Autogen.c
+ //
+ ExternCallBackToAutoGenC(fileBuffer);
+
+ //
+ // Write EntryPoint to autgoGen.c
+ //
+ String[] entryPointList = SurfaceAreaQuery.getModuleEntryPointArray();
+ if (entryPointList != null) {
+ EntryPointToAutoGen(entryPointList, fileBuffer);
+ }
+
+ //
+ // Write Guid to autogen.c
+ //
+ String guid = SurfaceAreaQuery.getModuleGuid();
+ fileBuffer
+ .append("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiCallerIdGuid = {");
+ if (guid == null) {
+ throw new BuildException("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(Spd.formatGuidName(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);
+
+ //
+ // Write consumed ppi, guid, protocol to autogen.c
+ //
+ ProtocolGuidToAutogenC(fileBuffer);
+ PpiGuidToAutogenC(fileBuffer);
+ GuidGuidToAutogenC(fileBuffer);
+
+ //
+ // Call pcd autogen. PCDAutoGenAction tool only need module name and
+ // isPcdEmulatedDriver as parameter. Library inherits PCD and module's
+ // PCD information has been collected in FPDParser task by
+ // CollectPCDAction.
+ // Note : when PCD image tool ready,
+ // isPCDEmulatedDriver parameter will be removed.
+ //
+ try {
+ this.myPcdAutogen = new PCDAutoGenAction(baseName,
+ baseName.equalsIgnoreCase("PcdEmulatorPeim"));
+ this.myPcdAutogen.execute();
+ } catch (Exception e) {
+ throw new BuildException("PCD Autogen failed:" + e.getMessage());
+ }
+
+ if (this.myPcdAutogen != null) {
+ fileBuffer.append(this.myPcdAutogen.OutputC());
+ }
+
+ if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {
+ throw new BuildException("Failed to generate AutoGen.c !!!");
+ }
+
+ }
+
+ /**
+ libGenAutogenH
+
+ This function generates AutoGen.h for library.
+
+ @throws BuildException
+ Failed to generate AutoGen.c.
+ **/
+ void libGenAutogenH() throws BuildException {
+
+ List<String> libClassIncludeH;
+ String moduleType;
+ List<String> headerFileList;
+ StringBuffer fileBuffer = new StringBuffer(10240);
+
+ //
+ // Write Autogen.h header notation
+ //
+ fileBuffer.append(CommonDefinition.autogenHNotation);
+
+ //
+ // Add #ifndef ${BaseName}_AUTOGENH
+ // #def ${BseeName}_AUTOGENH
+ //
+ fileBuffer.append("#ifndef " + this.baseName.toUpperCase() + "_AUTOGENH\r\n");
+ fileBuffer.append("#define " + this.baseName.toUpperCase() + "_AUTOGENH\r\n\r\n");
+
+ //
+ // 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);
+ fileBuffer.append(CommonDefinition.autoGenHLine1);
+ fileBuffer.append(CommonDefinition.autoGenHLine2);
+
+ //
+ // Write consumed package's mdouleInfo related *.h file to autogen.h.
+ //
+ moduleType = SurfaceAreaQuery.getModuleType();
+ List<String> cosumedPkglist = SurfaceAreaQuery
+ .getIncludePackageName(this.arch);
+ headerFileList = IncludesToAutogenH(cosumedPkglist, moduleType);
+ for (int i = 0; i < headerFileList.size(); i++) {
+ fileBuffer.append(headerFileList.get(i));
+ }
+
+ //
+ // Write library class's related *.h file to autogen.h
+ //
+ LibraryClass[] libClassList = SurfaceAreaQuery
+ .getLibraryClassArray(CommonDefinition.AlwaysConsumed);
+ if (libClassList != null) {
+ libClassIncludeH = LibraryClassToAutogenH(libClassList);
+ for (int i = 0; i < libClassIncludeH.size(); i++) {
+ fileBuffer.append(libClassIncludeH.get(i));
+ }
+ }
+
+ libClassList = SurfaceAreaQuery
+ .getLibraryClassArray(CommonDefinition.AlwaysProduced);
+ if (libClassList != null) {
+ libClassIncludeH = LibraryClassToAutogenH(libClassList);
+ for (int i = 0; i < libClassIncludeH.size(); i++) {
+ fileBuffer.append(libClassIncludeH.get(i));
+ }
+ }
+ fileBuffer.append("\r\n");
+
+ //
+ // Write PCD information to library AutoGen.h.
+ //
+ if (this.myPcdAutogen != null) {
+ fileBuffer.append(this.myPcdAutogen.OutputH());
+ }
+
+ //
+ // 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 BuildException("Failed to generate AutoGen.h !!!");
+ }
+ }
+
+ /**
+ libGenAutogenC
+
+ This function generates AutoGen.h for library.
+
+ @throws BuildException
+ Failed to generate AutoGen.c.
+ **/
+ void libGenAutogenC() throws BuildException {
+ StringBuffer fileBuffer = new StringBuffer(10240);
+
+ //
+ // Write Autogen.c header notation
+ //
+ fileBuffer.append(CommonDefinition.autogenCNotation);
+
+ fileBuffer.append(CommonDefinition.autoGenCLine1);
+ fileBuffer.append("\r\n");
+
+ //
+ // Call pcd autogen. PCDAutoGenAction tool only need module name and
+ // isPcdEmulatedDriver as parameter. Library inherit PCD and module's
+ // PCD information has been collected in FPDParser task by
+ // CollectPCDAction.
+ // Note : when PCD image tool ready,
+ // isPCDEmulatedDriver parameter will be removed.
+ //
+ try {
+ this.myPcdAutogen = new PCDAutoGenAction(baseName, baseName
+ .equalsIgnoreCase("PcdEmulatorPeim"));
+ this.myPcdAutogen.execute();
+ } catch (Exception e) {
+ throw new BuildException(e.getMessage());
+ }
+
+ if (this.myPcdAutogen != null) {
+ fileBuffer.append(this.myPcdAutogen.OutputC());
+ }
+
+ if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {
+ throw new BuildException("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.
+ **/
+ List<String> LibraryClassToAutogenH(LibraryClass[] libClassList) {
+ List<String> includStrList = new ArrayList<String>();
+ String includerName;
+ String str = "";
+
+ //
+ // Get include file from GlobalData's SPDTable according to
+ // library class name.
+ //
+ for (int i = 0; i < libClassList.length; i++) {
+ includerName = GlobalData.getLibClassIncluder(libClassList[i]
+ .getStringValue());
+ if (includerName != null) {
+ str = CommonDefinition.include + " " + "<";
+ str = str + includerName + ">\r\n";
+ includStrList.add(str);
+ includerName = null;
+ }
+ }
+ return includStrList;
+ }
+
+ /**
+ IncludesToAutogenH
+
+ This function add include file in AutoGen.h file.
+ @param packageNameList List of module depended package.
+ @param moduleType Module type.
+ @return
+ **/
+ List<String> IncludesToAutogenH(List<String> packageNameList,
+ String moduleType) {
+
+ List<String> includeStrList = new ArrayList<String>();
+ String packageName = "";
+ String includeStr = "";
+
+ //
+ // Get include file from moduleInfo file
+ //
+ for (int i = 0; i < packageNameList.size(); i++) {
+ packageName = packageNameList.get(i);
+ includeStr = GlobalData.getModuleInfoByPackageName(packageName,
+ moduleType);
+ 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, StringBuffer fileBuffer)
+ throws BuildException {
+
+ String typeStr = SurfaceAreaQuery.getModuleType();
+
+ //
+ // The parameters and return value of entryPoint is difference
+ // for difference module type.
+ //
+ switch (CommonDefinition.getModuleType(typeStr)) {
+
+ case CommonDefinition.ModuleTypePeiCore:
+ if (entryPointList.length != 1 || entryPointList[0].equals("")) {
+ throw new BuildException(
+ "Module type = 'PEI_CORE', only have one module entry point!");
+ } else {
+ fileBuffer.append("EFI_STATUS\r\n");
+ fileBuffer.append("EFIAPI\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.length != 1 || entryPointList[0].equals("")) {
+ throw new BuildException(
+ "Module type = 'DXE_CORE', only have one module entry point!");
+ } else {
+
+ fileBuffer.append("VOID\r\n");
+ fileBuffer.append("EFIAPI\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:
+ int entryPointCount = 0;
+ fileBuffer
+ .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;\r\n");
+ for (int i = 0; i < entryPointList.length; i++) {
+ if (!entryPointList[i].equals("")) {
+ fileBuffer.append("EFI_STATUS\r\n");
+ fileBuffer.append("EFIAPI\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++;
+ } else {
+ break;
+ }
+ }
+
+ 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 == 0) {
+ fileBuffer.append(" return EFI_SUCCESS;\r\n");
+ } else 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;
+ for (int i = 0; i < entryPointList.length; i++) {
+ if (!entryPointList[i].equals("")) {
+ fileBuffer.append("EFI_STATUS\r\n");
+ fileBuffer.append("EFIAPI\r\n");
+ fileBuffer.append(entryPointList[i]);
+ fileBuffer.append(" (\r\n");
+ fileBuffer.append(" EFI_HANDLE ImageHandle,\r\n");
+ fileBuffer.append(" EFI_SYSTEM_TABLE *SystemTable\r\n");
+ fileBuffer.append(" );\r\n");
+ entryPointCount++;
+ } else {
+ break;
+ }
+ }
+ 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(" EFI_HANDLE ImageHandle,\r\n");
+ fileBuffer.append(" EFI_SYSTEM_TABLE *SystemTable\r\n");
+ fileBuffer.append(" )\r\n\r\n");
+ fileBuffer.append("{\r\n");
+
+ 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\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();
+ entryPointCount = 0;
+ if (entryPointList != null) {
+ for (int i = 0; i < entryPointList.length; i++) {
+ if (!entryPointList[i].equals("")) {
+ fileBuffer.append("EFI_STATUS\r\n");
+ fileBuffer.append("EFIAPI\r\n");
+ fileBuffer.append(entryPointList[i]);
+ fileBuffer.append(" (\r\n");
+ fileBuffer
+ .append(" EFI_HANDLE ImageHandle\r\n");
+ fileBuffer.append(" );\r\n");
+ entryPointCount++;
+ } else {
+ break;
+ }
+ }
+ }
+
+ fileBuffer
+ .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ");
+ fileBuffer.append(Integer.toString(entryPointCount));
+ fileBuffer.append(";\r\n\r\n");
+
+ if (entryPointList != null) {
+ for (int i = 0; i < entryPointList.length; i++) {
+ if (!entryPointList[i].equals("")) {
+ fileBuffer.append("EFI_STATUS\r\n");
+ fileBuffer.append("EFIAPI\r\n");
+ fileBuffer.append(entryPointList[i]);
+ fileBuffer.append(" (\r\n");
+ fileBuffer
+ .append(" EFI_HANDLE ImageHandle\r\n");
+ fileBuffer.append(" );\r\n");
+ } else {
+ break;
+ }
+ }
+ }
+
+ fileBuffer.append("EFI_STATUS\r\n");
+ fileBuffer.append("EFIAPI\r\n");
+ fileBuffer.append("ProcessModuleUnloadList (\r\n");
+ fileBuffer.append(" EFI_HANDLE ImageHandle\r\n");
+ fileBuffer.append(" )\r\n");
+ fileBuffer.append("{\r\n");
+
+ if (entryPointCount == 0) {
+ fileBuffer.append(" return EFI_SUCCESS;\r\n");
+ } else if (entryPointCount == 1) {
+ fileBuffer.append(" return ");
+ fileBuffer.append(entryPointList[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 < entryPointList.length; i++) {
+ if (!entryPointList[i].equals("")) {
+ fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n");
+ fileBuffer.append(" ");
+ fileBuffer.append(entryPointList[i]);
+ fileBuffer.append("(ImageHandle);\r\n");
+ fileBuffer.append(" } else {\r\n");
+ fileBuffer.append(" Status = ");
+ fileBuffer.append(entryPointList[i]);
+ fileBuffer.append("(ImageHandle);\r\n");
+ fileBuffer.append(" }\r\n");
+ } else {
+ break;
+ }
+ }
+ 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");
+ for (int i = 0; i < entryPointList.length; i++) {
+ if (!entryPointList[i].equals("")) {
+ fileBuffer.append("EFI_STATUS\r\n");
+ fileBuffer.append("EFIAPI\r\n");
+ fileBuffer.append(entryPointList[i]);
+ fileBuffer.append(" (\r\n");
+ fileBuffer.append(" EFI_HANDLE ImageHandle,\r\n");
+ fileBuffer.append(" EFI_SYSTEM_TABLE *SystemTable\r\n");
+ fileBuffer.append(" );\r\n");
+ entryPointCount++;
+ } else {
+ break;
+ }
+ }
+
+ 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(" EFI_HANDLE ImageHandle,\r\n");
+ fileBuffer.append(" EFI_SYSTEM_TABLE *SystemTable\r\n");
+ fileBuffer.append(" )\r\n\r\n");
+ fileBuffer.append("{\r\n");
+
+ if (entryPointCount == 0) {
+ fileBuffer.append(" return EFI_SUCCESS;\r\n");
+ } else 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\n");
+ fileBuffer.append("EFIAPI\n");
+ fileBuffer.append("ExitDriver (\r\n");
+ fileBuffer.append(" IN EFI_STATUS Status\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();
+ entryPointCount = 0;
+ if (entryPointList != null) {
+ for (int i = 0; i < entryPointList.length; i++) {
+ if (!entryPointList[i].equals("")) {
+ fileBuffer.append("EFI_STATUS\r\n");
+ fileBuffer.append("EFIAPI\r\n");
+ fileBuffer.append(entryPointList[i]);
+ fileBuffer.append(" (\r\n");
+ fileBuffer
+ .append(" EFI_HANDLE ImageHandle\r\n");
+ fileBuffer.append(" );\r\n");
+ entryPointCount++;
+ } else {
+ break;
+ }
+ }
+ }
+
+ fileBuffer
+ .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ");
+ fileBuffer.append(Integer.toString(entryPointCount));
+ fileBuffer.append(";\r\n\r\n");
+
+ if (entryPointList != null) {
+ for (int i = 0; i < entryPointList.length; i++) {
+ if (!entryPointList[i].equals("")) {
+ fileBuffer.append("EFI_STATUS\r\n");
+ fileBuffer.append("EFIAPI\r\n");
+ fileBuffer.append(entryPointList[i]);
+ fileBuffer.append(" (\r\n");
+ fileBuffer
+ .append(" EFI_HANDLE ImageHandle\r\n");
+ fileBuffer.append(" );\r\n");
+ } else {
+ break;
+ }
+ }
+ }
+
+ fileBuffer.append("EFI_STATUS\n");
+ fileBuffer.append("EFIAPI\n");
+ fileBuffer.append("ProcessModuleUnloadList (\r\n");
+ fileBuffer.append(" EFI_HANDLE ImageHandle\r\n");
+ fileBuffer.append(" )\r\n");
+ fileBuffer.append("{\r\n");
+
+ if (entryPointCount == 0) {
+ fileBuffer.append(" return EFI_SUCCESS;\r\n");
+ } else if (entryPointCount == 1) {
+ fileBuffer.append(" return ");
+ fileBuffer.append(entryPointList[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 < entryPointList.length; i++) {
+ if (!entryPointList[i].equals("")) {
+ fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n");
+ fileBuffer.append(" ");
+ fileBuffer.append(entryPointList[i]);
+ fileBuffer.append("(ImageHandle);\r\n");
+ fileBuffer.append(" } else {\r\n");
+ fileBuffer.append(" Status = ");
+ fileBuffer.append(entryPointList[i]);
+ fileBuffer.append("(ImageHandle);\r\n");
+ fileBuffer.append(" }\r\n");
+ } else {
+ break;
+ }
+ }
+ 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 BuildException {
+ String[] cNameGuid = null;
+ boolean isEqual = false;
+
+ PPIsDocument.PPIs.Ppi[] ppiList = SurfaceAreaQuery.getPpiArray(null);
+ if (ppiList != null) {
+ for (int i = 0; i < ppiList.length; i++) {
+ isEqual = false;
+ for (int j = 0; j < this.mPpiList.size(); j++) {
+ if (this.mPpiList.get(j).equalsIgnoreCase(
+ ppiList[i].getStringValue())) {
+ isEqual = true;
+ }
+ }
+ if (!isEqual) {
+ this.mPpiList.add(ppiList[i].getStringValue());
+ }
+ }
+ }
+
+ PPIsDocument.PPIs.PpiNotify[] ppiNotifyList = SurfaceAreaQuery
+ .getPpiNotifyArray(null);
+ if (ppiNotifyList != null) {
+ for (int i = 0; i < ppiNotifyList.length; i++) {
+ isEqual = false;
+ for (int j = 0; j < this.mPpiList.size(); j++) {
+ if (this.mPpiList.get(j).equalsIgnoreCase(
+ ppiNotifyList[i].getStringValue())) {
+ isEqual = true;
+ }
+ }
+ if (!isEqual) {
+ this.mPpiList.add(ppiNotifyList[i].getStringValue());
+ }
+ }
+ }
+
+ for (int i = 0; i < this.mPpiList.size(); i++) {
+ if (this.mPpiList.get(i) != null) {
+ cNameGuid = GlobalData.getPpiInfoGuid(this.mPpiList.get(i));
+ if (cNameGuid != null) {
+ fileBuffer
+ .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
+ fileBuffer.append(cNameGuid[0]);
+ fileBuffer.append(" = { ");
+ fileBuffer.append(cNameGuid[1]);
+ fileBuffer.append(" } ;");
+ }
+ } else {
+ throw new BuildException("Guid must set value!");
+ }
+ }
+ }
+
+ /**
+ 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 BuildException {
+ String[] cNameGuid = null;
+ boolean isEqual = false;
+
+ ProtocolsDocument.Protocols.Protocol[] protocolList = SurfaceAreaQuery
+ .getProtocolArray(null);
+ if (protocolList != null) {
+ for (int i = 0; i < protocolList.length; i++) {
+ isEqual = false;
+ for (int j = 0; j < this.mProtocolList.size(); j++) {
+ if (this.mProtocolList.get(j).equalsIgnoreCase(
+ protocolList[i].getStringValue())) {
+ isEqual = true;
+ }
+ }
+ if (!isEqual) {
+ this.mProtocolList.add(protocolList[i].getStringValue());
+
+ }
+ }
+ }
+
+ ProtocolsDocument.Protocols.ProtocolNotify[] protocolNotifyList = SurfaceAreaQuery
+ .getProtocolNotifyArray(null);
+ if (protocolNotifyList != null) {
+ for (int i = 0; i < protocolNotifyList.length; i++) {
+ isEqual = false;
+ for (int j = 0; j < this.mProtocolList.size(); j++) {
+ if (this.mProtocolList.get(j).equalsIgnoreCase(
+ protocolNotifyList[i].getStringValue())) {
+ isEqual = true;
+ }
+ }
+ if (!isEqual) {
+ this.mProtocolList.add(protocolNotifyList[i]
+ .getStringValue());
+
+ }
+ }
+ }
+ if (this.mProtocolList.size() > 0) {
+ for (int i = 0; i < this.mProtocolList.size(); i++) {
+ if (this.mProtocolList.get(i) != null) {
+ cNameGuid = GlobalData
+ .getProtocolInfoGuid(this.mProtocolList.get(i));
+ if (cNameGuid != null) {
+ fileBuffer
+ .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
+ fileBuffer.append(cNameGuid[0]);
+ fileBuffer.append(" = { ");
+ fileBuffer.append(cNameGuid[1]);
+ fileBuffer.append(" } ;");
+ }
+ } else {
+ throw new BuildException("Protocol name must set!");
+ }
+ }
+ }
+ }
+
+ /**
+ 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) {
+ String[] cNameGuid = null;
+ boolean isEqual = false;
+ GuidsDocument.Guids.GuidEntry[] guidList = SurfaceAreaQuery
+ .getGuidEntryArray(null);
+
+ if (guidList != null) {
+ for (int i = 0; i < guidList.length; i++) {
+ for (int j = 0; j < this.mGuidList.size(); j++) {
+ isEqual = false;
+ if (this.mGuidList.get(j).getCName().equalsIgnoreCase(
+ guidList[i].getCName().toString())) {
+ isEqual = true;
+ break;
+ }
+ }
+ if (!isEqual) {
+ this.mGuidList.add(guidList[i]);
+
+ }
+
+ }
+ }
+
+ for (int i = 0; i < this.mGuidList.size(); i++) {
+ if (this.mGuidList.get(i).getCName() != null) {
+ cNameGuid = GlobalData.getGuidInfoGuid(this.mGuidList.get(i)
+ .getCName());
+ if (cNameGuid != null) {
+ fileBuffer
+ .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
+ fileBuffer.append(cNameGuid[0]);
+ fileBuffer.append(" = { ");
+ fileBuffer.append(cNameGuid[1]);
+ fileBuffer.append("} ;");
+ }
+ }
+ }
+ }
+
+ /**
+ 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 BuildException {
+ int index;
+ boolean isEqual = false;
+
+ String moduleType = SurfaceAreaQuery.getModuleType();
+ List<String> libConstructList = new ArrayList<String>();
+ List<String> libDestructList = new ArrayList<String>();
+
+ String libConstructName = null;
+ String libDestructName = null;
+ List<String> libraryList = SurfaceAreaQuery.getLibraryInstance(
+ this.arch, CommonDefinition.AlwaysConsumed);
+
+ try {
+ if (libraryList != null) {
+ //
+ // Reorder library instance sequence.
+ //
+ AutogenLibOrder libOrder = new AutogenLibOrder(libraryList);
+ List orderList = libOrder.orderLibInstance();
+
+ if (orderList != null) {
+ //
+ // Process library instance one by one.
+ //
+ for (int i = 0; i < orderList.size(); i++) {
+
+ //
+ // Get library instance basename.
+ //
+ String libInstanceName = orderList.get(i).toString();
+
+ //
+ // Get override map
+ //
+ Map<String, XmlObject> libDoc = GlobalData
+ .getDoc(libInstanceName);
+ SurfaceAreaQuery.push(libDoc);
+
+ //
+ // Get <PPis>, <Protocols>, <Guids> list of this library
+ // instance.
+ //
+ PPIsDocument.PPIs.Ppi[] ppiList = SurfaceAreaQuery
+ .getPpiArray(null);
+ PPIsDocument.PPIs.PpiNotify[] ppiNotifyList = SurfaceAreaQuery
+ .getPpiNotifyArray(null);
+ ProtocolsDocument.Protocols.Protocol[] protocolList = SurfaceAreaQuery
+ .getProtocolArray(null);
+ ProtocolsDocument.Protocols.ProtocolNotify[] protocolNotifyList = SurfaceAreaQuery
+ .getProtocolNotifyArray(null);
+ GuidsDocument.Guids.GuidEntry[] guidList = SurfaceAreaQuery
+ .getGuidEntryArray(null);
+
+ //
+ // Add those ppi, protocol, guid in global ppi, protocol, guid
+ // list.
+ //
+ if (ppiList != null) {
+ for (index = 0; index < ppiList.length; index++) {
+ isEqual = false;
+ for (int j = 0; j < this.mPpiList.size(); j++) {
+ if (this.mPpiList.get(j).equalsIgnoreCase(
+ ppiList[index].getStringValue())) {
+ isEqual = true;
+ }
+ }
+ if (!isEqual) {
+ this.mPpiList.add(ppiList[index]
+ .getStringValue());
+ }
+ }
+ }
+ if (ppiNotifyList != null) {
+ for (index = 0; index < ppiNotifyList.length; index++) {
+ isEqual = false;
+ for (int j = 0; j < this.mPpiList.size(); j++) {
+ if (this.mPpiList.get(j).equalsIgnoreCase(
+ ppiNotifyList[index]
+ .getStringValue())) {
+ isEqual = true;
+ }
+ }
+ if (!isEqual) {
+ this.mPpiList.add(ppiNotifyList[index]
+ .getStringValue());
+ }
+ }
+ }
+ if (protocolList != null) {
+ for (index = 0; index < protocolList.length; index++) {
+ isEqual = false;
+ for (int j = 0; j < this.mProtocolList.size(); j++) {
+ if (this.mProtocolList.get(j)
+ .equalsIgnoreCase(
+ protocolList[index]
+ .getStringValue())) {
+ isEqual = true;
+ }
+ }
+ if (!isEqual) {
+ this.mProtocolList.add(protocolList[index]
+ .getStringValue());
+ }
+ }
+ }
+ if (protocolNotifyList != null) {
+ for (index = 0; index < protocolNotifyList.length; index++) {
+ isEqual = false;
+ for (int j = 0; j < this.mProtocolList.size(); j++) {
+ if (this.mProtocolList.get(j)
+ .equalsIgnoreCase(
+ protocolNotifyList[index]
+ .getStringValue())) {
+ isEqual = true;
+ }
+ }
+ if (!isEqual) {
+ this.mProtocolList
+ .add(protocolNotifyList[index]
+ .getStringValue());
+ }
+ }
+ }
+ if (guidList != null) {
+ for (index = 0; index < guidList.length; index++) {
+ isEqual = false;
+ for (int j = 0; j < this.mGuidList.size(); j++) {
+ if (this.mGuidList.get(j).getCName()
+ .equalsIgnoreCase(
+ guidList[index].getCName())) {
+ isEqual = true;
+ }
+ }
+ if (!isEqual) {
+ this.mGuidList.add(guidList[index]);
+ }
+ }
+ }
+
+ //
+ // If not yet parse this library instance's constructor
+ // element,parse it.
+ //
+ if (!GlobalData.isHaveLibInstance(libInstanceName)) {
+ libConstructName = SurfaceAreaQuery
+ .getLibConstructorName();
+ libDestructName = SurfaceAreaQuery
+ .getLibDestructorName();
+
+ GlobalData.setLibInstanceInfo(libInstanceName,
+ libConstructName, libDestructName);
+ } else {
+ libConstructName = GlobalData
+ .getLibInstanceConstructor(libInstanceName);
+ libDestructName = GlobalData
+ .getLibInstanceDestructor(libInstanceName);
+ }
+ SurfaceAreaQuery.pop();
+ //
+ // Add dependent library instance constructor function.
+ //
+ if (libConstructName != null) {
+ libConstructList.add(libConstructName);
+ }
+ //
+ // Add dependent library instance destructor fuction.
+ //
+ if (libDestructName != null) {
+ libDestructList.add(libDestructName);
+ }
+ }
+
+ }
+
+ //
+ // Add library constructor to AutoGen.c
+ //
+ LibConstructorToAutogenC(libConstructList, moduleType,
+ fileBuffer/* autogenC */);
+ //
+ // Add library destructor to AutoGen.c
+ //
+ LibDestructorToAutogenC(libDestructList, moduleType,
+ fileBuffer/* autogenC */);
+ }
+
+ } catch (Exception e) {
+ throw new BuildException(e.getMessage());
+ }
+ }
+
+
+ /**
+ 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 Exception {
+ boolean isFirst = true;
+
+ //
+ // The library constructor's parameter and return value depend on
+ // module type.
+ //
+ for (int i = 0; i < libInstanceList.size(); i++) {
+ switch (CommonDefinition.getModuleType(moduleType)) {
+ case CommonDefinition.ModuleTypeBase:
+ fileBuffer.append("RETURN_STATUS\r\n");
+ fileBuffer.append(libInstanceList.get(i));
+ 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(libInstanceList.get(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");
+ 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(libInstanceList.get(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");
+ break;
+ }
+ }
+
+ //
+ // Add ProcessLibraryConstructorList in AutoGen.c
+ //
+ fileBuffer.append("VOID\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");
+
+ for (int i = 0; i < libInstanceList.size(); i++) {
+ if (isFirst) {
+ fileBuffer.append(" EFI_STATUS Status;\r\n");
+ fileBuffer.append("\r\n");
+ isFirst = false;
+ }
+ switch (CommonDefinition.getModuleType(moduleType)) {
+ case CommonDefinition.ModuleTypeBase:
+ fileBuffer.append(" Status = ");
+ fileBuffer.append(libInstanceList.get(i));
+ fileBuffer.append("();\r\n");
+ fileBuffer.append(" VOID\r\n");
+ break;
+ case CommonDefinition.ModuleTypePeiCore:
+ case CommonDefinition.ModuleTypePeim:
+ fileBuffer.append(" Status = ");
+ fileBuffer.append(libInstanceList.get(i));
+ 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));
+ fileBuffer.append(" (ImageHandle, SystemTable);\r\n");
+ break;
+ }
+ 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 Exception {
+ boolean isFirst = true;
+ for (int i = 0; i < libInstanceList.size(); i++) {
+ switch (CommonDefinition.getModuleType(moduleType)) {
+ case CommonDefinition.ModuleTypeBase:
+ fileBuffer.append("RETURN_STATUS\n");
+ fileBuffer.append(libInstanceList.get(i));
+ 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(libInstanceList.get(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");
+ 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(libInstanceList.get(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");
+ 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("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");
+
+ for (int i = 0; i < libInstanceList.size(); i++) {
+ if (isFirst) {
+ fileBuffer.append(" EFI_STATUS Status;\r\n");
+ fileBuffer.append("\r\n");
+ isFirst = false;
+ }
+ fileBuffer.append(" Status = ");
+ fileBuffer.append(libInstanceList.get(i));
+ 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 BuildException {
+
+ //
+ // Check what <extern> contains. And the number of following elements
+ // under <extern> should be same. 1. DRIVER_BINDING 2. COMPONENT_NAME
+ // 3.DRIVER_CONFIGURATION 4. DRIVER_DIAGNOSTIC
+ //
+
+ String[] drvBindList = SurfaceAreaQuery.getDriverBindingArray();
+
+ //
+ // If component name protocol,component configuration protocol,
+ // component diagnostic protocol is not null or empty, check
+ // if every one have the same number of the driver binding protocol.
+ //
+ if (drvBindList == null || drvBindList.length == 0) {
+ return;
+ }
+
+ String[] compNamList = SurfaceAreaQuery.getComponentNameArray();
+ String[] compConfList = SurfaceAreaQuery.getDriverConfigArray();
+ String[] compDiagList = SurfaceAreaQuery.getDriverDiagArray();
+
+ int BitMask = 0;
+
+ //
+ // Write driver binding protocol extern to autogen.c
+ //
+ for (int i = 0; i < drvBindList.length; i++) {
+ fileBuffer.append("extern EFI_DRIVER_BINDING_PROTOCOL ");
+ fileBuffer.append(drvBindList[i]);
+ fileBuffer.append(";\r\n");
+ }
+
+ //
+ // Write component name protocol extern to autogen.c
+ //
+ if (compNamList != null && compNamList.length != 0) {
+ if (drvBindList.length != compNamList.length) {
+ throw new BuildException(
+ "Different number of Driver Binding and Component Name protocols!");
+ }
+
+ BitMask |= 0x01;
+ for (int i = 0; i < compNamList.length; i++) {
+ fileBuffer.append("extern EFI_COMPONENT_NAME_PROTOCOL ");
+ fileBuffer.append(compNamList[i]);
+ fileBuffer.append(";\r\n");
+ }
+ }
+
+ //
+ // Write driver configration protocol extern to autogen.c
+ //
+ if (compConfList != null && compConfList.length != 0) {
+ if (drvBindList.length != compConfList.length) {
+ throw new BuildException(
+ "Different number of Driver Binding and Driver Configuration protocols!");
+ }
+
+ BitMask |= 0x02;
+ for (int i = 0; i < compConfList.length; i++) {
+ fileBuffer.append("extern EFI_DRIVER_CONFIGURATION_PROTOCOL ");
+ fileBuffer.append(compConfList[i]);
+ fileBuffer.append(";\r\n");
+ }
+ }
+
+ //
+ // Write driver dignastic protocol extern to autogen.c
+ //
+ if (compDiagList != null && compDiagList.length != 0) {
+ if (drvBindList.length != compDiagList.length) {
+ throw new BuildException(
+ "Different number of Driver Binding and Driver Configuration protocols!");
+ }
+
+ BitMask |= 0x04;
+ for (int i = 0; i < compDiagList.length; i++) {
+ fileBuffer.append("extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL ");
+ fileBuffer.append(compDiagList[i]);
+ fileBuffer.append(";\r\n");
+ }
+ }
+
+ //
+ // 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(drvBindList.length));
+ fileBuffer.append(";\r\n");
+
+ //
+ // Write drive module protocol list to autogen.c
+ //
+ fileBuffer
+ .append("GLOBAL_REMOVE_IF_UNREFERENCED const EFI_DRIVER_MODEL_PROTOCOL_LIST _gDriverModelProtocolList[] = {");
+ for (int i = 0; i < drvBindList.length; i++) {
+ if (i != 0) {
+ fileBuffer.append(",");
+ }
+ fileBuffer.append("\r\n {\r\n");
+ fileBuffer.append(" &");
+ fileBuffer.append(drvBindList[i]);
+ fileBuffer.append(", \r\n");
+
+ if (compNamList != null) {
+ fileBuffer.append(" &");
+ fileBuffer.append(compNamList[i]);
+ fileBuffer.append(", \r\n");
+ } else {
+ fileBuffer.append(" NULL, \r\n");
+ }
+
+ if (compConfList != null) {
+ fileBuffer.append(" &");
+ fileBuffer.append(compConfList[i]);
+ fileBuffer.append(", \r\n");
+ } else {
+ fileBuffer.append(" NULL, \r\n");
+ }
+
+ if (compDiagList != null) {
+ fileBuffer.append(" &");
+ fileBuffer.append(compDiagList[i]);
+ fileBuffer.append(", \r\n");
+ } else {
+ fileBuffer.append(" NULL, \r\n");
+ }
+ fileBuffer.append(" }");
+ }
+ 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 BuildException {
+ String[] setVirtualList = SurfaceAreaQuery
+ .getSetVirtualAddressMapCallBackArray();
+ String[] exitBootList = SurfaceAreaQuery
+ .getExitBootServicesCallBackArray();
+ String moduleType = SurfaceAreaQuery.getModuleType();
+ boolean UefiOrDxeModule = false;
+ int Count = 0;
+ int i;
+
+ switch (CommonDefinition.getModuleType(moduleType)) {
+ case CommonDefinition.ModuleTypeDxeDriver:
+ case CommonDefinition.ModuleTypeDxeRuntimeDriver:
+ case CommonDefinition.ModuleTypeDxeSalDriver:
+ case CommonDefinition.ModuleTypeUefiDriver:
+ case CommonDefinition.ModuleTypeUefiApplication:
+ //
+ // Entry point lib for these module types needs to know the count
+ // of entryPoint.
+ //
+ UefiOrDxeModule = true;
+ 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
+ //
+ Count = 0;
+ if (setVirtualList != null) {
+ for (i = 0; i < setVirtualList.length; i++) {
+ if (setVirtualList[i].equalsIgnoreCase("")) {
+ break;
+ }
+ }
+ Count = i;
+ }
+
+ fileBuffer.append(Integer.toString(Count));
+ fileBuffer.append(";\r\n\r\n");
+ break;
+ default:
+ break;
+ }
+
+ if (setVirtualList == null) {
+ if (UefiOrDxeModule) {
+ //
+ // 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 < setVirtualList.length; i++) {
+ if (setVirtualList[i].equalsIgnoreCase("")) {
+ break;
+ }
+ fileBuffer.append("VOID\r\n");
+ fileBuffer.append("EFIAPI\n");
+ fileBuffer.append(setVirtualList[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 < setVirtualList.length; i++) {
+ if (setVirtualList[i].equalsIgnoreCase("")) {
+ break;
+ }
+
+ if (i == 0) {
+ fileBuffer.append("\r\n ");
+ } else {
+ fileBuffer.append(",\r\n ");
+ }
+
+ fileBuffer.append(setVirtualList[i]);
+ }
+ if (Count == 0) {
+ fileBuffer.append("\r\n NULL");
+ }
+ fileBuffer.append("\r\n};\r\n\r\n");
+ }
+
+ if (UefiOrDxeModule) {
+ //
+ // 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.
+ //
+ Count = 0;
+ if (exitBootList != null) {
+ if (setVirtualList != null) {
+ for (i = 0; i < exitBootList.length; i++) {
+ if (exitBootList[i].equalsIgnoreCase("")) {
+ break;
+ }
+ }
+ Count = i;
+ }
+ }
+ fileBuffer.append(Integer.toString(Count));
+ fileBuffer.append(";\r\n\r\n");
+ }
+
+ if (exitBootList == null) {
+ if (UefiOrDxeModule) {
+ //
+ // 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 < exitBootList.length; i++) {
+ if (exitBootList[i].equalsIgnoreCase("")) {
+ break;
+ }
+
+ fileBuffer.append("VOID\r\n");
+ fileBuffer.append("EFIAPI\n");
+ fileBuffer.append(exitBootList[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 < exitBootList.length; i++) {
+ if (exitBootList[i].equalsIgnoreCase("")) {
+ break;
+ }
+
+ if (i == 0) {
+ fileBuffer.append("\r\n ");
+ } else {
+ fileBuffer.append(",\r\n ");
+ }
+ fileBuffer.append(exitBootList[i]);
+ }
+ if (Count == 0) {
+ fileBuffer.append("\r\n NULL");
+ }
+ fileBuffer.append("\r\n};\r\n\r\n");
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java b/Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java
new file mode 100644
index 0000000000..77404d4007
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java
@@ -0,0 +1,306 @@
+/**@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.LibraryClassDocument.LibraryClass;
+
+import org.tianocore.build.global.GlobalData;
+import org.tianocore.build.global.SurfaceAreaQuery;
+
+/**
+ 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, String> libClassMap = new HashMap<String, String>();
+
+ ///
+ /// The map of library instance and its implemet instance.
+ ///
+ private Map<String, String[]> libInstanceMap = new HashMap<String, 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<String[]> libInstanceList = new ArrayList<String[]>();
+
+ /**
+ Constructor function
+
+ This function mainly initialize some member variable.
+
+ @param libraryList List of the library instance.
+ @throws Exception
+ **/
+ AutogenLibOrder(List<String> libraryList) throws Exception {
+ String[] libInstance = new String[3];
+ LibraryClass[] libClassDeclList = null;
+ LibraryClass[] libClassConsmList = null;
+
+ for (int i = 0; i < libraryList.size(); i++) {
+ //
+ // Add libraryInstance in to libInstanceList.
+ //
+ libInstance[0] = libraryList.get(i);
+ Map<String, XmlObject> libDoc = GlobalData.getDoc(libInstance[0]);
+ SurfaceAreaQuery.push(libDoc);
+ libInstance[1] = SurfaceAreaQuery.getLibConstructorName();
+ libInstance[2] = SurfaceAreaQuery.getLibDestructorName();
+ libInstanceList.add(libInstance.clone());
+
+ //
+ // Add library instance and consumed library class list to
+ // libInstanceMap.
+ //
+ libClassConsmList = SurfaceAreaQuery
+ .getLibraryClassArray(CommonDefinition.AlwaysConsumed);
+ if (libClassConsmList != null) {
+ String[] classStr = new String[libClassConsmList.length];
+ for (int k = 0; k < libClassConsmList.length; k++) {
+ classStr[k] = libClassConsmList[k].getStringValue();
+ }
+ if (this.libInstanceMap.containsKey(libInstance[0])) {
+ throw new Exception(
+ libInstance[0]
+ + "this library instance is already exist, please check you library instance list!");
+ } else {
+ this.libInstanceMap.put(libInstance[0], classStr);
+ }
+ }
+
+ //
+ // Add library class and library instance map.
+ //
+ libClassDeclList = SurfaceAreaQuery
+ .getLibraryClassArray(CommonDefinition.AlwaysProduced);
+ if (libClassDeclList != null) {
+ for (int j = 0; j < libClassDeclList.length; j++) {
+ if (this.libClassMap.containsKey(libClassDeclList[j]
+ .getStringValue())) {
+ System.out.println(libClassDeclList[j].getStringValue()
+ + " class is already implement by "
+ + this.libClassMap.get(libClassDeclList[j]
+ .getStringValue()));
+ throw new Exception(libClassDeclList
+ + " is already have library instance!");
+ } else {
+ this.libClassMap.put(libClassDeclList[j]
+ .getStringValue(), libInstance[0]);
+ }
+ }
+ }
+ SurfaceAreaQuery.pop();
+ }
+
+ //
+ // Check is the library instance list meet the require;
+ //
+ for (int s = 0; s < this.libInstanceList.size(); s++) {
+ String[] libClass = this.libInstanceMap.get(this.libInstanceList
+ .get(s));
+ if (libClass != null) {
+ for (int t = 0; t < libClass.length; t++) {
+ if (this.libClassMap.get(libClass[t]) == null) {
+ //
+ // Note: There exist a kind of module which depend on
+ // library class with no instance or whose instance will
+ // never be linked into the module.
+ // For this satuation, the module has the description of
+ // library class in MSA file but no description of
+ // corresponding library instance in MBD file. There
+ // will be a warnig message given here after a standard
+ // log way has been decided.
+ //
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ orderLibInstance
+
+ This function reorder the library instance according the library class
+ dependency.
+
+ @return List which content the ordered library instance.
+ **/
+ List orderLibInstance() {
+ List<String> orderList = new ArrayList<String>();
+ //
+ // Stack of node which track the library instance name ant its visiting
+ // flag.
+ //
+ List<Node> stackList = new ArrayList<Node>();
+ int stackSize = 0;
+ String libInstance = 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)[0])) {
+ continue;
+ }
+
+ Node node = new Node(libInstanceList.get(i)[0], 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).nodeName)) {
+ orderList.add(stackList.get(stackSize).nodeName);
+ 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).nodeName);
+ //
+ // Push the node dependence library instance to the stack.
+ //
+ if (libClassList != null) {
+ for (int j = 0; j < libClassList.length; j++) {
+ libInstance = this.libClassMap.get(libClassList[j]);
+ if (libInstance != null
+ && !isInLibInstance(orderList, libInstance)) {
+ //
+ // 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(libInstance)) {
+ stackList.add(new Node(this.libClassMap
+ .get(libClassList[j]), false));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return orderList;
+ }
+
+ /**
+ isInLibInstance
+
+ This function check does the library instance already in the list.
+
+ @param list List of the library instance.
+ @param instanceName Name of library instance.
+ @return "true" the library instance in list |
+ "false" the library instance is not in list.
+ **/
+ private boolean isInLibInstance(List list, String instanceName) {
+ for (int i = 0; i < list.size(); i++) {
+ if (instanceName.equalsIgnoreCase(list.get(i).toString())) {
+ 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, String nodeName) {
+ for (int i = 0; i < list.size(); i++) {
+ if (nodeName.equalsIgnoreCase(list.get(i).nodeName)) {
+ 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 (String libName){
+ for (int i = 0; i < libInstanceList.size(); i++){
+ if (libInstanceList.get(i)[0].equalsIgnoreCase(libName)){
+ if (libInstanceList.get(i)[1] != null || libInstanceList.get(i)[2] != null){
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
+
+/**
+ Node
+
+ This class is used as stack node.
+
+ **/
+class Node {
+ String nodeName;
+
+ boolean isVisit;
+
+ Node(String name, boolean isVisit) {
+ this.nodeName = name;
+ this.isVisit = false;
+ }
+} \ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java b/Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java
new file mode 100644
index 0000000000..2490d97467
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java
@@ -0,0 +1,257 @@
+/** @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;
+
+/**
+ CommonDefinition
+
+ This class is to define some common marcos, which used by AutoGen.
+
+**/
+public class CommonDefinition {
+ public final static String spdSuffix = ".spd";
+ public final static String mbdSuffix = ".mbd";
+ public final static String msaSuffix = ".msa";
+ public final static String LibraryStr = "LIBRARY";
+ public final static String autoGenHbegin = "extern int __make_me_compile_correctly;\r\n";
+ public final static String include = "#include";
+ public final static String autoGenCLine1 = "\r\n";
+
+ public final static String autoGenCLine2 = "const UINT8 _gDebugPropertyMask "
+ + "= DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED"
+ + " | DEBUG_PROPERTY_DEBUG_PRINT_ENABLED"
+ + " | DEBUG_PROPERTY_DEBUG_CODE_ENABLED;\r\n";
+
+ public final static String autoGenCLine3 = "const UINTN _gModuleDefaultErrorLevel"
+ + " = EFI_D_ERROR | EFI_D_LOAD;\r\n";
+
+ public final static String autoGenHLine1 = "#define EFI_SPECIFICATION_VERSION 0x00020000\r\n";
+ public final static String autoGenHVersionDefault = "#define EFI_SPECIFICATION_VERSION 0x00000000\r\n";
+ public final static String autoGenHLine2 = "#define EDK_RELEASE_VERSION 0x00090000\r\n";
+ public final static String autoGenHReleaseDefault = "#define EDK_RELEASE_VERSION 0x00000000\r\n";
+
+ public final static String includeAutogenH = "#include <AutoGen.h>\r\n" ;
+
+ public final static String gEfi = "gEfi";
+ public final static String protocolGuid = "ProtocolGuid";
+ public final static String ppiGuid = "PpiGuid";
+ public final static String guidGuid = "Guid";
+
+ //
+ // AutoGen.h and AutoGen.c file's header
+ //
+ public final static String autogenHNotation =
+ "/**\r\n" +
+ " DO NOT EDIT\r\n" +
+ " FILE auto-generated by GenBuild tasks\r\n" +
+ " Module name:\r\n" +
+ " AutoGen.h\r\n" +
+ " Abstract:" +
+ " Auto-generated AutoGen.h for building module or library.\r\n" +
+ "**/\r\n\r\n";
+
+ public final static String autogenCNotation =
+ "/**\r\n" +
+ " DO NOT EDIT\r\n" +
+ " FILE auto-generated by GenBuild tasks\r\n" +
+ " Module name:\r\n" +
+ " AutoGen.c\r\n" +
+ " Abstract:" +
+ " Auto-generated AutoGen.c for building module or library.\r\n" +
+ "**/\r\n\r\n";
+
+ //
+ // 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;
+
+
+ //
+ // component type
+ //
+ public final static int ComponentTypeNull = 0;
+ public final static int ComponentTypeApriori = 1;
+ public final static int ComponentTypeSec = 2;
+ public final static int ComponentTypeLibrary = 3;
+ public final static int ComponentTypeFvImageFile = 4;
+ public final static int ComponentTypeBsDriver = 5;
+ public final static int ComponentTypeRtDriver = 6;
+ public final static int ComponentTypeSalRtDriver =7;
+ public final static int ComponentTypePe32Peim = 8;
+ public final static int ComponentTypePicPeim =9;
+ public final static int ComponentTypeCombinedPeimDriver =10;
+ public final static int ComponentTypePeiCore = 11;
+ public final static int ComponentTypeDxeCore = 12;
+ public final static int ComponentTypeApplication = 13;
+ public final static int ComponentTypeBsDriverEfi = 14;
+ public final static int ComponentTypeShellApp = 15;
+ public final static int ComponentTypeBinary =16;
+ public final static int ComponentTypeLogo = 17;
+ public final static int ComponentTypeCustomBuild = 18;
+ public final static int ComponentTypeUnknown = 19;
+
+
+ //
+ // 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("BASE", ModuleTypeBase),
+ new MyEnum("SEC", ModuleTypeSec),
+ new MyEnum("PEI_CORE", ModuleTypePeiCore),
+ new MyEnum("PEIM", ModuleTypePeim),
+ new MyEnum("DXE_CORE", ModuleTypeDxeCore),
+ new MyEnum("DXE_DRIVER", ModuleTypeDxeRuntimeDriver),
+ new MyEnum("DXE_RUNTIME_DRIVER", ModuleTypeDxeRuntimeDriver),
+ new MyEnum("DXE_SAL_DRIVER", ModuleTypeDxeSmmDriver),
+ new MyEnum("DXE_SMM_DRIVER", ModuleTypeDxeSalDriver),
+ new MyEnum("UEFI_DRIVER", ModuleTypeUefiDriver),
+ new MyEnum("UEFI_APPLICATION", ModuleTypeUefiApplication) };
+
+ //
+ // Component type
+ //
+ public static final MyEnum[] componentEnum = new MyEnum[]{
+ new MyEnum("APRIORI", ComponentTypeApriori),
+ new MyEnum("SEC", ComponentTypeSec),
+ new MyEnum("LIBRARY", ComponentTypeLibrary),
+ new MyEnum("FV_IMAGE_FILE", ComponentTypeFvImageFile),
+ new MyEnum("BS_DRIVER", ComponentTypeBsDriver),
+ new MyEnum("RT_DRIVER", ComponentTypeRtDriver),
+ new MyEnum("SAL_RT_DRIVER", ComponentTypeSalRtDriver),
+ new MyEnum("PE32_PEIM", ComponentTypePe32Peim),
+ new MyEnum("PIC_PEIM", ComponentTypePicPeim),
+ new MyEnum("COMBINED_PEIM_DRIVER", ComponentTypeCombinedPeimDriver),
+ new MyEnum("PEI_CORE", ComponentTypePeiCore),
+ new MyEnum("DXE_CORE", ComponentTypeDxeCore),
+ new MyEnum("APPLICATION", ComponentTypeApplication),
+ new MyEnum("BS_DRIVER_EFI", ComponentTypeBsDriverEfi),
+ new MyEnum("SHELLAPP", ComponentTypeShellApp),
+ new MyEnum("BINARY", ComponentTypeBinary),
+ new MyEnum("LOGO", ComponentTypeLogo),
+ new MyEnum("CUSTOM_BUILD", ComponentTypeCustomBuild)
+ };
+
+ /**
+ getModuleType
+
+ This function get the module type value according module type string.
+
+ @param moduleTypeStr String of modlue type.
+ @return
+ **/
+ static public 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;
+ }
+
+ /**
+ getComponentType
+
+ This function get the component type value according commponet type
+ string.
+
+ @param componentTypeStr String of component type.
+ @return
+ **/
+ static public int getComponentType (String componentTypeStr){
+ int returnValue = -1;
+ for (int i = 0; i < CommonDefinition.componentEnum.length; i++) {
+ returnValue = CommonDefinition.componentEnum[i].ForInt(componentTypeStr);
+ if (returnValue != -1) {
+ return returnValue;
+ }
+ }
+ return CommonDefinition.ComponentTypeUnknown;
+ }
+
+ /**
+ getComponentTypeString
+
+ This function get the commponet type string according component type value.
+
+ @param componentType Integer value of component type.
+ @return
+ **/
+ static public String getComponentTypeString (int componentType) {
+ if ((componentType > CommonDefinition.ComponentTypeUnknown) ||
+ (componentType < CommonDefinition.ComponentTypeNull)) {
+ return null;
+ }
+ for (int index = 0; index < CommonDefinition.componentEnum.length; index ++) {
+ if (componentType == CommonDefinition.componentEnum[index].type) {
+ return CommonDefinition.componentEnum[index].moduleTypeStr;
+ }
+ }
+ return null;
+ }
+
+ /**
+ isLibraryComponent
+
+ This function is to check does componet is library according to commponet
+ type value.
+
+ @param componentType Integer value of component type.
+ @return
+ **/
+ static public boolean isLibraryComponent (int componentType) {
+ if (ComponentTypeLibrary == componentType) {
+ return true;
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdModuleIdentification.java b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdModuleIdentification.java
new file mode 100644
index 0000000000..261cf58a35
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdModuleIdentification.java
@@ -0,0 +1,131 @@
+/** @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.fpd;
+
+/**
+ This class is used to identify a module with BaseName, GUID, Version, PackageName
+ and ARCH.
+
+ @since GenBuild 1.0
+ **/
+public class FpdModuleIdentification {
+
+ private String arch;
+
+ private String fvBinding;
+
+ private String baseName;
+
+ private String packageName;
+
+ private String guid;
+
+ private String version;
+
+ private String sequence;
+
+ /**
+
+ @param baseName the base name of the module
+ @param guid the GUID of the module
+ @param arch the ARCH of the module
+ **/
+ public FpdModuleIdentification(String baseName, String guid, String arch){
+ this.baseName = baseName;
+ this.guid = guid;
+ this.arch = arch;
+ }
+
+ /**
+ 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 ( baseName.equalsIgnoreCase(moduleIdObj.baseName) && arch.equalsIgnoreCase(moduleIdObj.arch)) {
+ return true;
+ }
+ // TBD
+ return false;
+ }
+ else {
+ return super.equals(obj);
+ }
+ }
+
+ public void setArch(String arch) {
+ this.arch = arch;
+ }
+
+ public void setFvBinding(String fvBinding) {
+ this.fvBinding = fvBinding;
+ }
+
+ public void setSequence(String sequence) {
+ this.sequence = sequence;
+ }
+
+ public String toString(){
+ return arch + ":" + guid + "_" + baseName;
+ }
+
+ public void setBaseName(String baseName) {
+ this.baseName = baseName;
+ }
+
+ public void setGuid(String guid) {
+ this.guid = guid;
+ }
+
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getArch() {
+ return arch;
+ }
+
+ public String getBaseName() {
+ return baseName;
+ }
+
+ public String getFvBinding() {
+ return fvBinding;
+ }
+
+ public String getGuid() {
+ return guid;
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public String getSequence() {
+ return sequence;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java
new file mode 100644
index 0000000000..99b7242ebc
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java
@@ -0,0 +1,808 @@
+/** @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.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 javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Property;
+import org.apache.xmlbeans.XmlObject;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.tianocore.build.global.GlobalData;
+import org.tianocore.build.global.OutputManager;
+import org.tianocore.build.global.OverrideProcess;
+import org.tianocore.build.global.SurfaceAreaQuery;
+import org.tianocore.build.pcd.action.CollectPCDAction;
+import org.tianocore.build.pcd.action.ActionMessage;
+import org.tianocore.BuildOptionsDocument;
+import org.tianocore.FrameworkPlatformDescriptionDocument;
+import org.tianocore.ModuleSADocument;
+
+
+/**
+ <code>FpdParserTask</code> is an ANT task. The main function is parsing FPD
+ XML file and generating its ANT build script for Platform or Package.
+
+ <p>The usage is (take NT32 Platform for example):</p>
+
+ <pre>
+ &lt;FPDParser fpdfilename="Build\Nt32.fpd" /&gt;
+ </pre>
+
+ <p>The task will initialize all information through parsing Framework Database,
+ SPD, Tool chain configuration files. </p>
+
+ @since GenBuild 1.0
+**/
+public class FpdParserTask extends Task {
+
+ ///
+ /// FV dir: ${PLATFORM_DIR}/Build/FV
+ ///
+ public static final String FV_OUTPUT_DIR = "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "FV";
+
+ private File fpdFilename;
+
+ private File guiddatabase;
+
+ ///
+ /// Keep platform buildoption information
+ ///
+ public static XmlObject platformBuildOptions = null;
+
+ ///
+ /// Mapping from modules identification to out put file name
+ ///
+ private Map<FpdModuleIdentification, String> outfiles = new LinkedHashMap<FpdModuleIdentification, String>();
+
+ ///
+ /// Mapping from FV name to its modules
+ ///
+ private Map<String, Set<FpdModuleIdentification> > fvs = new HashMap<String, Set<FpdModuleIdentification> >();
+
+ ///
+ /// Mapping from sequence number to its modules
+ ///
+ private Map<String, Set<FpdModuleIdentification> > sequences = new HashMap<String, Set<FpdModuleIdentification> >();
+
+ ///
+ /// FpdParserTask can specify some ANT properties.
+ ///
+ private Vector<Property> properties = new Vector<Property>();
+
+ private String info = "====================================================================\n"
+ + "DO NOT EDIT \n"
+ + "File auto-generated by build utility\n"
+ + "\n"
+ + "Abstract:\n"
+ + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"
+ + "=====================================================================";
+
+ /**
+ 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 build.out.xml file for Flatform or Package build; </li>
+ <li>Collect PCD information. </li>
+ </ul>
+
+ @throws BuildException
+ Surface area is not valid.
+ **/
+ public void execute() throws BuildException {
+ OutputManager.update(getProject());
+ //
+ // Parse DB and SPDs files. Initialize Global Data
+ //
+ GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db", getProject()
+ .getProperty("WORKSPACE_DIR"));
+ //
+ // Parse FPD file
+ //
+ parseFpdFile();
+ //
+ // Gen Fv.inf files
+ //
+ genFvInfFiles();
+ //
+ // Gen build.xml
+ //
+ genBuildFile();
+ //
+ // Collect PCD information
+ //
+ collectPCDInformation ();
+ }
+
+ /**
+ Generate Fv.inf files. The Fv.inf file is composed with four
+ parts: Options, Attributes, Components and Files. The Fv.inf files
+ will be under ${PLATFOMR_DIR}\Build\Fv.
+
+ @throws BuildException
+ File write FV.inf files error.
+ **/
+ private void genFvInfFiles() throws BuildException{
+ String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
+ for (int i = 0; i < validFv.length; i++) {
+ getProject().setProperty("FV_FILENAME", validFv[i].toUpperCase());
+ //
+ // Get all global variables from FPD and set them to properties
+ //
+ String[][] globalVariables = SurfaceAreaQuery
+ .getFpdGlobalVariable();
+ for (int j = 0; j < globalVariables.length; j++) {
+ getProject().setProperty(globalVariables[j][0],
+ globalVariables[j][1]);
+ }
+
+ File fvFile = new File(getProject().replaceProperties(
+ FV_OUTPUT_DIR + File.separatorChar + validFv[i].toUpperCase()
+ + ".inf"));
+ fvFile.getParentFile().mkdirs();
+
+ try {
+ FileWriter fw = new FileWriter(fvFile);
+ BufferedWriter bw = new BufferedWriter(fw);
+ //
+ // Options
+ //
+ String[][] options = SurfaceAreaQuery.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 = SurfaceAreaQuery
+ .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 = SurfaceAreaQuery
+ .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> filesSet = fvs.get(validFv[i].toUpperCase());
+ if (filesSet != null) {
+ FpdModuleIdentification[] files = filesSet.toArray(new FpdModuleIdentification[filesSet
+ .size()]);
+ bw.write("[files]");
+ bw.newLine();
+ for (int j = 0; j < files.length; j++) {
+ String str = outfiles.get(files[j]);
+ bw.write(getProject().replaceProperties(
+ "EFI_FILE_NAME = " + str));
+ bw.newLine();
+ }
+ }
+ bw.flush();
+ bw.close();
+ fw.close();
+ } catch (Exception e) {
+ throw new BuildException("Generate Fv.inf file failed. \n" + e.getMessage());
+ }
+ }
+ }
+
+ /**
+ Parse FPD file.
+
+ @throws BuildException
+ FPD file is not valid.
+ **/
+ private void parseFpdFile() throws BuildException {
+ try {
+ FrameworkPlatformDescriptionDocument doc = (FrameworkPlatformDescriptionDocument) XmlObject.Factory
+ .parse(fpdFilename);
+ if ( ! doc.validate() ){
+ throw new BuildException("FPD file is invalid.");
+ }
+ platformBuildOptions = doc.getFrameworkPlatformDescription()
+ .getBuildOptions();
+ HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();
+ map.put("FrameworkPlatformDescription", doc);
+ SurfaceAreaQuery.setDoc(map);
+ //
+ // Parse all list modules SA
+ //
+ parseModuleSAFiles();
+ SurfaceAreaQuery.setDoc(map);
+ } catch (Exception e) {
+ throw new BuildException("Load FPD file [" + fpdFilename.getPath()
+ + "] error. \n" + e.getMessage());
+ }
+ }
+
+ /**
+ Parse all modules listed in FPD file.
+ **/
+ private void parseModuleSAFiles() {
+ ModuleSADocument.ModuleSA[] moduleSAs = SurfaceAreaQuery
+ .getFpdModules();
+ //
+ // For every Module lists in FPD file.
+ //
+ for (int i = 0; i < moduleSAs.length; i++) {
+ String defaultFv = "NULL";
+ String defaultArch = "IA32";
+ String baseName = moduleSAs[i].getModuleName();
+ if (baseName == null) {
+ System.out.println("Warning: Module Name is not specified.");
+ continue;
+ }
+ String fvBinding = moduleSAs[i].getFvBinding();
+ //
+ // If the module do not specify any FvBinding, use the default value.
+ // Else update the default FvBinding value to this value.
+ //
+ if (fvBinding == null) {
+ fvBinding = defaultFv;
+ }
+ else {
+ defaultFv = fvBinding;
+ }
+ String arch;
+ //
+ // If the module do not specify any Arch, use the default value.
+ // Else update the default Arch value to this value.
+ //
+ if (moduleSAs[i].getArch() == null ){
+ arch = defaultArch;
+ }
+ else {
+ arch = moduleSAs[i].getArch().toString();
+ defaultArch = arch;
+ }
+ Map<String, XmlObject> msaMap = GlobalData.getNativeMsa(baseName);
+ Map<String, XmlObject> mbdMap = GlobalData.getNativeMbd(baseName);
+ Map<String, XmlObject> map = new HashMap<String, XmlObject>();
+ //
+ // Whether the Module SA has parsed before or not
+ //
+ if (!GlobalData.isModuleParsed(baseName)) {
+ OverrideProcess op = new OverrideProcess();
+ //
+ // using overriding rules
+ // Here we can also put platform Build override
+ //
+ map = op.override(mbdMap, msaMap);
+ Map<String, XmlObject> overrideMap = op.override(
+ getPlatformOverrideInfo(moduleSAs[i]),
+ OverrideProcess.deal(map));
+ GlobalData.registerModule(baseName, overrideMap);
+ } else {
+ map = GlobalData.getDoc(baseName);
+ }
+ SurfaceAreaQuery.setDoc(map);
+ String guid = SurfaceAreaQuery.getModuleGuid();
+ String componentType = SurfaceAreaQuery.getComponentType();
+ FpdModuleIdentification moduleId = new FpdModuleIdentification(baseName, guid, arch);
+ updateFvs(fvBinding, moduleId);
+ outfiles.put(moduleId, "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar
+ + "${TARGET}" + File.separatorChar + arch
+ + File.separatorChar + guid + "-" + baseName
+ + getSuffix(componentType));
+ }
+ }
+
+ /**
+ Add the current module to corresponding FV.
+
+ @param fvName current FV name
+ @param moduleName current module identification
+ **/
+ private void updateFvs(String fvName, FpdModuleIdentification moduleName) {
+ String upcaseFvName = fvName.toUpperCase();
+ if (fvs.containsKey(upcaseFvName)) {
+ Set<FpdModuleIdentification> set = fvs.get(upcaseFvName);
+ set.add(moduleName);
+ } else {
+ Set<FpdModuleIdentification> set = new LinkedHashSet<FpdModuleIdentification>();
+ set.add(moduleName);
+ fvs.put(upcaseFvName, set);
+ }
+ }
+
+ /**
+ Get the suffix based on component type. Current relationship are listed:
+
+ <pre>
+ <b>ComponentType</b> <b>Suffix</b>
+ APPLICATION .APP
+ SEC .SEC
+ PEI_CORE .PEI
+ PE32_PEIM .PEI
+ RELOCATABLE_PEIM .PEI
+ PIC_PEIM .PEI
+ COMBINED_PEIM_DRIVER .PEI
+ TE_PEIM .PEI
+ LOGO .FFS
+ others .DXE
+ </pre>
+
+ @param componentType component type
+ @return
+ @throws BuildException
+ If component type is null
+ **/
+ public static String getSuffix(String componentType) throws BuildException{
+ if (componentType == null) {
+ throw new BuildException("Component type is not specified.");
+ }
+ String str = ".DXE";
+ if (componentType.equalsIgnoreCase("APPLICATION")) {
+ str = ".APP";
+ } else if (componentType.equalsIgnoreCase("SEC")) {
+ str = ".SEC";
+ } else if (componentType.equalsIgnoreCase("PEI_CORE")) {
+ str = ".PEI";
+ } else if (componentType.equalsIgnoreCase("PE32_PEIM")) {
+ str = ".PEI";
+ } else if (componentType.equalsIgnoreCase("RELOCATABLE_PEIM")) {
+ str = ".PEI";
+ } else if (componentType.equalsIgnoreCase("PIC_PEIM")) {
+ str = ".PEI";
+ } else if (componentType.equalsIgnoreCase("COMBINED_PEIM_DRIVER")) {
+ str = ".PEI";
+ } else if (componentType.equalsIgnoreCase("TE_PEIM")) {
+ str = ".PEI";
+ } else if (componentType.equalsIgnoreCase("LOGO")) {
+ str = ".FFS";
+ }
+ return str;
+ }
+
+ /**
+ Parse module surface are info described in FPD file and put them into map.
+
+ @param sa module surface area info descibed in FPD file
+ @return map list with top level elements
+ **/
+ private Map<String, XmlObject> getPlatformOverrideInfo(
+ ModuleSADocument.ModuleSA sa) {
+ Map<String, XmlObject> map = new HashMap<String, XmlObject>();
+ map.put("SourceFiles", sa.getSourceFiles());
+ map.put("Includes", sa.getIncludes());
+ map.put("Libraries", sa.getLibraries());
+ map.put("Protocols", sa.getProtocols());
+ map.put("Events", sa.getEvents());
+ map.put("Hobs", sa.getHobs());
+ map.put("PPIs", sa.getPPIs());
+ map.put("Variables", sa.getVariables());
+ map.put("BootModes", sa.getBootModes());
+ map.put("SystemTables", sa.getSystemTables());
+ map.put("DataHubs", sa.getDataHubs());
+ map.put("Formsets", sa.getFormsets());
+ map.put("Guids", sa.getGuids());
+ map.put("Externs", sa.getExterns());
+ map.put("BuildOptions", platformBuildOptions);
+ return map;
+ }
+
+ /**
+ Generate build.out.xml file.
+
+ @throws BuildException
+ build.out.xml XML document create error
+ **/
+ private void genBuildFile() throws BuildException {
+ DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
+ try {
+ DocumentBuilder dombuilder = domfac.newDocumentBuilder();
+ Document document = dombuilder.newDocument();
+ Comment rootComment = document.createComment(info);
+ //
+ // create root element and its attributes
+ //
+ Element root = document.createElement("project");
+ root.setAttribute("name", getProject().getProperty("PLATFORM"));
+ root.setAttribute("default", "main");
+ root.setAttribute("basedir", ".");
+ //
+ // element for External ANT tasks
+ //
+ root.appendChild(document.createComment("Apply external ANT tasks"));
+ Element ele = document.createElement("taskdef");
+ ele.setAttribute("resource", "GenBuild.tasks");
+ root.appendChild(ele);
+
+ ele = document.createElement("taskdef");
+ ele.setAttribute("resource", "frameworktasks.tasks");
+ root.appendChild(ele);
+
+ ele = document.createElement("property");
+ ele.setAttribute("environment", "env");
+ root.appendChild(ele);
+ //
+ // Default Target
+ //
+ root.appendChild(document.createComment("Default target"));
+ ele = document.createElement("target");
+ ele.setAttribute("name", "main");
+ ele.setAttribute("depends", "modules, fvs");
+ root.appendChild(ele);
+ //
+ // Modules Target
+ //
+ root.appendChild(document.createComment("Modules target"));
+ ele = document.createElement("target");
+ ele.setAttribute("name", "modules");
+
+ Set set = outfiles.keySet();
+ Iterator iter = set.iterator();
+ while (iter.hasNext()) {
+ FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
+ String baseName = moduleId.getBaseName();
+ Element moduleEle = document.createElement("ant");
+ moduleEle.setAttribute("antfile", GlobalData
+ .getModulePath(baseName)
+ + File.separatorChar + "build.xml");
+ moduleEle.setAttribute("target", baseName);
+ //
+ // ARCH
+ //
+ Element property = document.createElement("property");
+ property.setAttribute("name", "ARCH");
+ property.setAttribute("value", moduleId.getArch());
+ moduleEle.appendChild(property);
+ //
+ // PACKAGE_DIR
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE_DIR");
+ property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
+ + GlobalData.getPackagePathForModule(baseName));
+ moduleEle.appendChild(property);
+ //
+ // PACKAGE
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE");
+ property.setAttribute("value", GlobalData
+ .getPackageNameForModule(baseName));
+ moduleEle.appendChild(property);
+ ele.appendChild(moduleEle);
+ }
+ root.appendChild(ele);
+ //
+ // FVS Target
+ //
+ root.appendChild(document.createComment("FVs target"));
+ ele = document.createElement("target");
+ ele.setAttribute("name", "fvs");
+
+ String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
+ for (int i = 0; i < validFv.length; i++) {
+ String inputFile = FV_OUTPUT_DIR + "" + File.separatorChar
+ + validFv[i].toUpperCase() + ".inf";
+ Element fvEle = document.createElement("genfvimage");
+ fvEle.setAttribute("infFile", inputFile);
+ ele.appendChild(fvEle);
+ Element moveEle = document.createElement("move");
+ moveEle.setAttribute("file", validFv[i].toUpperCase() + ".fv");
+ moveEle.setAttribute("todir", FV_OUTPUT_DIR);
+ ele.appendChild(moveEle);
+ }
+ root.appendChild(ele);
+
+ boolean isUnified = false;
+ BuildOptionsDocument.BuildOptions buildOptions = (BuildOptionsDocument.BuildOptions)platformBuildOptions;
+ if (buildOptions.getOutputDirectory() != null){
+ if (buildOptions.getOutputDirectory().getIntermediateDirectories() != null){
+ if (buildOptions.getOutputDirectory().getIntermediateDirectories().toString().equalsIgnoreCase("UNIFIED")){
+ isUnified = true;
+ }
+ }
+ }
+ //
+ // Clean Target
+ //
+ root.appendChild(document.createComment("Clean target"));
+ ele = document.createElement("target");
+ ele.setAttribute("name", "clean");
+
+ if (isUnified) {
+ Element cleanEle = document.createElement("delete");
+ cleanEle.setAttribute("includeemptydirs", "true");
+ Element filesetEle = document.createElement("fileset");
+ filesetEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}");
+ filesetEle.setAttribute("includes", "**/OUTPUT/**");
+ cleanEle.appendChild(filesetEle);
+ ele.appendChild(cleanEle);
+ }
+ else {
+ set = outfiles.keySet();
+ iter = set.iterator();
+ while (iter.hasNext()) {
+ FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
+ String baseName = moduleId.getBaseName();
+
+ Element ifEle = document.createElement("if");
+ Element availableEle = document.createElement("available");
+ availableEle.setAttribute("file", GlobalData
+ .getModulePath(baseName)
+ + File.separatorChar + "build.xml");
+ ifEle.appendChild(availableEle);
+ Element elseEle = document.createElement("then");
+
+ Element moduleEle = document.createElement("ant");
+ moduleEle.setAttribute("antfile", GlobalData
+ .getModulePath(baseName)
+ + File.separatorChar + "build.xml");
+ moduleEle.setAttribute("target", baseName + "_clean");
+ //
+ // ARCH
+ //
+ Element property = document.createElement("property");
+ property.setAttribute("name", "ARCH");
+ property.setAttribute("value", moduleId.getArch());
+ moduleEle.appendChild(property);
+ //
+ // PACKAGE_DIR
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE_DIR");
+ property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
+ + GlobalData.getPackagePathForModule(baseName));
+ moduleEle.appendChild(property);
+ //
+ // PACKAGE
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE");
+ property.setAttribute("value", GlobalData
+ .getPackageNameForModule(baseName));
+ moduleEle.appendChild(property);
+ elseEle.appendChild(moduleEle);
+ ifEle.appendChild(elseEle);
+ ele.appendChild(ifEle);
+ }
+ }
+ root.appendChild(ele);
+ //
+ // Deep Clean Target
+ //
+ root.appendChild(document.createComment("Clean All target"));
+ ele = document.createElement("target");
+ ele.setAttribute("name", "cleanall");
+
+ if (isUnified) {
+ Element cleanAllEle = document.createElement("delete");
+ cleanAllEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}");
+ ele.appendChild(cleanAllEle);
+ }
+ else {
+ set = outfiles.keySet();
+ iter = set.iterator();
+ while (iter.hasNext()) {
+ FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
+ String baseName = moduleId.getBaseName();
+
+ Element ifEle = document.createElement("if");
+ Element availableEle = document.createElement("available");
+ availableEle.setAttribute("file", GlobalData
+ .getModulePath(baseName)
+ + File.separatorChar + "build.xml");
+ ifEle.appendChild(availableEle);
+ Element elseEle = document.createElement("then");
+
+ Element moduleEle = document.createElement("ant");
+ moduleEle.setAttribute("antfile", GlobalData
+ .getModulePath(baseName)
+ + File.separatorChar + "build.xml");
+ moduleEle.setAttribute("target", baseName + "_cleanall");
+ //
+ // ARCH
+ //
+ Element property = document.createElement("property");
+ property.setAttribute("name", "ARCH");
+ property.setAttribute("value", moduleId.getArch());
+ moduleEle.appendChild(property);
+ //
+ // PACKAGE_DIR
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE_DIR");
+ property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
+ + GlobalData.getPackagePathForModule(baseName));
+ moduleEle.appendChild(property);
+ //
+ // PACKAGE
+ //
+ property = document.createElement("property");
+ property.setAttribute("name", "PACKAGE");
+ property.setAttribute("value", GlobalData
+ .getPackageNameForModule(baseName));
+ moduleEle.appendChild(property);
+ elseEle.appendChild(moduleEle);
+ ifEle.appendChild(elseEle);
+ ele.appendChild(ifEle);
+ }
+ }
+ root.appendChild(ele);
+
+ document.appendChild(rootComment);
+ document.appendChild(root);
+ //
+ // Prepare the DOM document for writing
+ //
+ Source source = new DOMSource(document);
+ //
+ // Prepare the output file
+ //
+ File file = new File(getProject().getProperty("PLATFORM_DIR")
+ + File.separatorChar + "build.out.xml");
+ //
+ // generate all directory path
+ //
+ (new File(file.getParent())).mkdirs();
+ Result result = new StreamResult(file);
+ //
+ // Write the DOM document to the file
+ //
+ Transformer xformer = TransformerFactory.newInstance()
+ .newTransformer();
+ xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+ xformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ xformer.transform(source, result);
+ } catch (Exception ex) {
+ throw new BuildException("Generate build.out.xml failed. \n" + ex.getMessage());
+ }
+ }
+
+ /**
+ Add a property.
+
+ @param p property
+ **/
+ public void addProperty(Property p) {
+ properties.addElement(p);
+ }
+
+ /**
+ Get FPD file name.
+
+ @return FPD file name.
+ **/
+ public File getFpdFilename() {
+ return fpdFilename;
+ }
+
+ /**
+ Set FPD file name.
+
+ @param fpdFilename FPD file name
+ **/
+ public void setFpdFilename(File fpdFilename) {
+ this.fpdFilename = fpdFilename;
+ }
+
+ public File getGuiddatabase() {
+ return guiddatabase;
+ }
+
+ public void setGuiddatabase(File guiddatabase) {
+ this.guiddatabase = guiddatabase;
+ }
+
+ public void collectPCDInformation() {
+ CollectPCDAction collectAction = new CollectPCDAction ();
+ //
+ // Set memory database log file path. It should be put into same directory with FPD file.
+ //
+ GlobalData.getPCDMemoryDBManager().setLogFileName(
+ fpdFilename.getPath() + ".PCDMemroyDatabaseLog.txt"
+ );
+ //
+ // Collect all PCD information from FPD to MSA, and get help information from SPD.
+ // These all information will be stored into memory database for future usage such
+ // as autogen.
+ //
+ try {
+ collectAction.perform (
+ getProject().getProperty("WORKSPACE_DIR"),
+ fpdFilename.getPath(),
+ ActionMessage.NULL_MESSAGE_LEVEL
+ );
+ } catch (Exception exp) {
+ throw new BuildException (exp.getMessage());
+ }
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/DpFile.java b/Tools/Source/GenBuild/org/tianocore/build/global/DpFile.java
new file mode 100644
index 0000000000..78cde75604
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/DpFile.java
@@ -0,0 +1,129 @@
+/** @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 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) {
+ System.out.println (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/Source/GenBuild/org/tianocore/build/global/DpFileList.java b/Tools/Source/GenBuild/org/tianocore/build/global/DpFileList.java
new file mode 100644
index 0000000000..8b4b4a0add
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/DpFileList.java
@@ -0,0 +1,50 @@
+/** @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;
+
+/**
+ DpFileList is a container of Dpfile at the point of ANT task/datatype
+ **/
+public class DpFileList {
+ ///
+ /// 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());
+ }
+}
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java b/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
new file mode 100644
index 0000000000..611758a4ef
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
@@ -0,0 +1,637 @@
+/** @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.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+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.FrameworkDatabaseDocument;
+import org.tianocore.MsaFilesDocument;
+import org.tianocore.PackageListDocument;
+import org.tianocore.PackageSurfaceAreaDocument;
+import org.tianocore.MsaHeaderDocument.MsaHeader;
+import org.tianocore.MsaLibHeaderDocument.MsaLibHeader;
+import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
+import org.tianocore.build.autogen.CommonDefinition;
+import org.tianocore.build.fpd.FpdParserTask;
+
+/**
+ 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 it is necessary during build time. </p>
+
+ @since GenBuild 1.0
+**/
+public class GlobalData {
+
+ ///
+ /// means no surface area information for module
+ ///
+ public static final int NO_SA = 0;
+
+ ///
+ /// means only MSA
+ ///
+ public static final int ONLY_MSA = 1;
+
+ ///
+ /// means only Library MSA
+ ///
+ public static final int ONLY_LIBMSA = 2;
+
+ ///
+ /// means both MSA and MBD
+ ///
+ public static final int MSA_AND_MBD = 3;
+
+ ///
+ /// means both Library MSA and Library MBD
+ ///
+ public static final int LIBMSA_AND_LIBMBD = 4;
+
+ ///
+ /// Be used to ensure Global data will be initialized only once.
+ ///
+ public static boolean globalFlag = false;
+
+ ///
+ /// Record current WORKSPACE Directory
+ ///
+ private static String workspaceDir = "";
+
+ ///
+ /// Two columns: Package Name (Key), Package Path(ralative to WORKSPACE)
+ ///
+ private static final Map<String, String> packageInfo = new HashMap<String, String>();
+
+ ///
+ /// spdTable
+ /// Key: Package Name, Value: SPD detail info
+ ///
+ private static final Map<String, Spd> spdTable = new HashMap<String, Spd>();
+
+ ///
+ /// Three columns:
+ /// 1. Module Name | BaseName (Key)
+ /// 2. Module Path + Msa file name (relative to Package)
+ /// 3. Package Name (This module belong to which package)
+ ///
+ private static final Map<String, String[]> moduleInfo = new HashMap<String, String[]>();
+
+ ///
+ /// List all libraries for current build module
+ /// Key: Library BaseName, Value: output library path+name
+ ///
+ private static final Map<String, String> libraries = new HashMap<String, String>();
+
+ ///
+ /// Store every module's relative library instances BaseName
+ /// Key: Module BaseName, Value: All library instances module depends on.
+ ///
+ private static final Map<String, Set<String> > moduleLibraryMap = new HashMap<String, Set<String> >();
+
+ ///
+ /// Key: Module BaseName, Value: original MSA info
+ ///
+ private static final Map<String, Map<String, XmlObject> > nativeMsa = new HashMap<String, Map<String, XmlObject> >();
+
+ ///
+ /// Key: Module BaseName, Value: original MBD info
+ ///
+ private static final Map<String, Map<String, XmlObject> > nativeMbd = new HashMap<String, Map<String, XmlObject> >();
+
+ ///
+ /// Two columns: Module Name or Base Name as Key
+ /// Value is a HashMap with overridden data from MSA/MBD or/and Platform
+ ///
+ private static final Map<String, Map<String, XmlObject> > parsedModules = new HashMap<String, Map<String, XmlObject> >();
+
+ ///
+ /// List all built Module; Value is Module BaseName + Arch. TBD
+ ///
+ private static final Set<String> builtModules = new HashSet<String>();
+
+ ///
+ /// Library instance information table which recored the library and it's
+ /// constructor and distructor function
+ ///
+ private static final Map<String, String[]> libInstanceInfo = new HashMap<String, String[]>();
+
+ ///
+ /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.
+ ///
+ private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();
+
+ /**
+ Query the module's absolute path with module base name.
+
+ @param moduleName the base name of the module
+ @return the absolute module path
+ **/
+ public synchronized static String getModulePath(String moduleName) {
+ String[] info = moduleInfo.get(moduleName);
+ String packagePath = (String) packageInfo.get(info[1]);
+ File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);
+ return convertFile.getParent();
+ }
+
+ /**
+ Query the module's absolute MSA file path with module base name.
+
+ @param moduleName the base name of the module
+ @return the absolute MSA file name
+ @throws BuildException
+ Base name is not registered in any SPD files
+ **/
+ private synchronized static String getMsaFilename(String moduleName) throws BuildException {
+ String[] info = moduleInfo.get(moduleName);
+ if (info == null) {
+ throw new BuildException("Module base name [" + moduleName + "] can't found in all SPD.");
+ }
+ String packagePath = (String) packageInfo.get(info[1]);
+ File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);
+ return convertFile.getPath();
+ }
+
+ /**
+ Query the module's absolute MBD file path with module base name.
+
+ @param moduleName the base name of the module
+ @return the absolute MBD file name
+ @throws BuildException
+ Base name is not registered in any SPD files
+ **/
+ private synchronized static String getMbdFilename(String moduleName) throws BuildException {
+ String[] info = moduleInfo.get(moduleName);
+ if (info == null) {
+ throw new BuildException("Info: Module base name [" + moduleName + "] can't found in all SPD.");
+ }
+ String packagePath = (String) packageInfo.get(info[1]);
+ File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);
+ return convertFile.getPath().substring(0, convertFile.getPath().length() - 4) + ".mbd";
+ }
+
+ /**
+ Get the current WORKSPACE Directory.
+ @return current workspace directory
+ **/
+ public synchronized static String getWorkspacePath() {
+ return workspaceDir;
+ }
+
+ /**
+ Query package relative path to WORKSPACE_DIR with package name.
+
+ @param packageName the name of the package
+ @return the path relative to WORKSPACE_DIR
+ **/
+ public synchronized static String getPackagePath(String packageName) {
+ return (String) packageInfo.get(packageName);
+ }
+
+ /**
+ Query package (which the module belongs to) relative path to WORSPACE_DIR.
+
+ @param moduleName the base name of the module
+ @return the relative path to WORKSPACE_DIR of the package which the module belongs to
+ **/
+ public synchronized static String getPackagePathForModule(String moduleName) {
+ String[] info = moduleInfo.get(moduleName);
+ String packagePath = (String) packageInfo.get(info[1]);
+ return packagePath;
+ }
+
+ /**
+ Query the package name which the module belongs to with the module's base name.
+
+ @param moduleName the base name of the module
+ @return the package name which the module belongs to
+ **/
+ public synchronized static String getPackageNameForModule(String moduleName) {
+ return moduleInfo.get(moduleName)[1];
+ }
+
+ /**
+ 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) throws BuildException {
+ if (globalFlag) {
+ return;
+ }
+ globalFlag = true;
+ GlobalData.workspaceDir = workspaceDir;
+ File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
+ try {
+ FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);
+ List<PackageListDocument.PackageList.Package> packages = db.getFrameworkDatabase().getPackageList()
+ .getPackageList();
+ Iterator iter = packages.iterator();
+ while (iter.hasNext()) {
+ PackageListDocument.PackageList.Package packageItem = (PackageListDocument.PackageList.Package) iter
+ .next();
+ String name = packageItem.getPackageNameArray(0).getStringValue();
+ String path = packageItem.getPathArray(0).getStringValue();
+ packageInfo.put(name, path);
+ File spdFile = new File(workspaceDir + File.separatorChar + path + File.separatorChar + name + ".spd");
+ initPackageInfo(spdFile.getPath(), name);
+ //
+ // SPD Parse.
+ //
+ PackageSurfaceAreaDocument spdDoc = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(spdFile);
+ Spd spd = new Spd(spdDoc, path);
+ spdTable.put(name, spd);
+
+ }
+ } catch (Exception e) {
+ throw new BuildException("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());
+ }
+ }
+
+ /**
+ Parse every MSA files, get base name from MSA Header. And record those
+ values to ModuleInfo.
+
+ @param packageFilename the file name of the package
+ @param packageName the name of the package
+ @throws BuildException
+ SPD or MSA file is not valid
+ **/
+ private synchronized static void initPackageInfo(String packageFilename, String packageName) throws BuildException {
+ File packageFile = new File(packageFilename);
+ try {
+ PackageSurfaceAreaDocument spd = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(packageFile);
+ List<MsaFilesDocument.MsaFiles.MsaFile> msasList = spd.getPackageSurfaceArea().getMsaFiles()
+ .getMsaFileList();
+ Iterator msasIter = msasList.iterator();
+ while (msasIter.hasNext()) {
+ MsaFilesDocument.MsaFiles.MsaFile msas = (MsaFilesDocument.MsaFiles.MsaFile) msasIter.next();
+ String msaFilename = msas.getFilename().getStringValue();
+ File msaFile = new File(workspaceDir + File.separatorChar + GlobalData.getPackagePath(packageName)
+ + File.separatorChar + msaFilename);
+ SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
+ Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);
+ String baseName = "";
+ XmlObject header = null;
+ if ((header = map.get("MsaHeader")) != null) {
+ baseName = ((MsaHeader) header).getBaseName().getStringValue();
+ } else if ((header = map.get("MsaLibHeader")) != null) {
+ baseName = ((MsaLibHeader) header).getBaseName().getStringValue();
+ } else {
+ continue;
+ }
+ nativeMsa.put(baseName, map);
+ String[] info = { msaFilename, packageName };
+ moduleInfo.put(baseName, info);
+ }
+ } catch (Exception e) {
+ throw new BuildException("Parse package description file [" + packageFile.getPath() + "] Error.\n"
+ + e.getMessage());
+ }
+ }
+
+ /**
+ Query the libraries which the module depends on.
+
+ @param moduleName the base name of the module
+ @return the libraries which the module depends on
+ **/
+ public synchronized static String[] getModuleLibrary(String moduleName) {
+ Set<String> set = moduleLibraryMap.get(moduleName);
+ return set.toArray(new String[set.size()]);
+ }
+
+ /**
+ Register module's library list which it depends on for later use.
+
+ @param moduleName the base name of the module
+ @param libraryList the libraries which the module depends on
+ **/
+ public synchronized static void addModuleLibrary(String moduleName, Set<String> libraryList) {
+ moduleLibraryMap.put(moduleName, libraryList);
+ }
+
+ /**
+ Query the library absolute file name with library name.
+
+ @param library the base name of the library
+ @return the library absolute file name
+ **/
+ public synchronized static String getLibrary(String library) {
+ return libraries.get(library);
+ }
+
+ /**
+ Register library absolute file name for later use.
+
+ @param library the base name of the library
+ @param resultPath the library absolute file name
+ **/
+ public synchronized static void addLibrary(String library, String resultPath) {
+ libraries.put(library, resultPath);
+ }
+
+ /**
+ Whether the module with ARCH has built in the previous build.
+
+ @param moduleName the base name of the module
+ @param arch current build ARCH
+ @return true if the module has built in previous, otherwise return false
+ **/
+ public synchronized static boolean isModuleBuilt(String moduleName, String arch) {
+ return builtModules.contains(moduleName + "-" + arch);
+ }
+
+ /**
+ Register the module with ARCH has built.
+
+ @param moduleName the base name of the module
+ @param arch current build ARCH
+ **/
+ public synchronized static void registerBuiltModule(String moduleName, String arch) {
+ builtModules.add(moduleName + "-" + arch);
+ }
+
+ /**
+ Whether the module's surface area has parsed in the previous build.
+
+ @param moduleName the base name of the module
+ @return true if the module's surface area has parsed in previous, otherwise
+ return false
+ **/
+ public synchronized static boolean isModuleParsed(String moduleName) {
+ return parsedModules.containsKey(moduleName);
+ }
+
+ /**
+ Query overrided module surface area information. If current is Package
+ or Platform build, also include the information from FPD file.
+
+ <p>Note that surface area parsing is incremental. That means the method will
+ only to parse the MSA and MBD files when never parsed before. </p>
+
+ @param moduleName the base name of the module
+ @return the overrided module surface area information
+ @throws BuildException
+ MSA or MBD is not valid
+ **/
+ public synchronized static Map<String, XmlObject> getDoc(String moduleName) throws BuildException {
+ if (parsedModules.containsKey(moduleName)) {
+ return parsedModules.get(moduleName);
+ }
+ Map<String, XmlObject> msaMap = getNativeMsa(moduleName);
+ Map<String, XmlObject> mbdMap = getNativeMbd(moduleName);
+ OverrideProcess op = new OverrideProcess();
+ Map<String, XmlObject> map = op.override(mbdMap, msaMap);
+ //
+ // IF IT IS A PALTFORM BUILD, OVERRIDE FROM PLATFORM
+ //
+ if (FpdParserTask.platformBuildOptions != null) {
+ Map<String, XmlObject> platformMap = new HashMap<String, XmlObject>();
+ platformMap.put("BuildOptions", FpdParserTask.platformBuildOptions);
+ Map<String, XmlObject> overrideMap = op.override(platformMap, OverrideProcess.deal(map));
+ GlobalData.registerModule(moduleName, overrideMap);
+ return overrideMap;
+ } else {
+ parsedModules.put(moduleName, map);
+ return map;
+ }
+ }
+
+ /**
+ 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(String moduleName) throws BuildException {
+ if (nativeMsa.containsKey(moduleName)) {
+ return nativeMsa.get(moduleName);
+ }
+ String msaFilename = getMsaFilename(moduleName);
+ File msaFile = new File(msaFilename);
+ if (!msaFile.exists()) {
+ throw new BuildException("Info: Surface Area file [" + msaFile.getPath() + "] can't found.");
+ }
+ SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
+ Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);
+ nativeMsa.put(moduleName, map);
+ return map;
+ }
+
+ /**
+ Query the native MBD information with module base name.
+
+ <p>Note that MBD parsing is incremental. That means the method will
+ only to parse the MBD files when never parsed before. </p>
+
+ @param moduleName the base name of the module
+ @return the native MBD information
+ @throws BuildException
+ MBD file is not valid
+ **/
+ public synchronized static Map<String, XmlObject> getNativeMbd(String moduleName) throws BuildException {
+ if (nativeMbd.containsKey(moduleName)) {
+ return nativeMbd.get(moduleName);
+ }
+ String mbdFilename = getMbdFilename(moduleName);
+ File mbdFile = new File(mbdFilename);
+ if (!mbdFile.exists()) {
+ throw new BuildException("Info: Surface Area file [" + mbdFile.getPath() + "] can't found.");
+ }
+ SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
+ Map<String, XmlObject> map = surfaceAreaParser.parseFile(mbdFile);
+ nativeMbd.put(moduleName, map);
+ return map;
+ }
+
+ /**
+ Register module overrided surface area information. If has existed, then update.
+
+ @param moduleName the base name of the module
+ @param map the overrided surface area information
+ **/
+ public synchronized static void registerModule(String moduleName, Map<String, XmlObject> map) {
+ parsedModules.put(moduleName, map);
+ }
+
+ /**
+ *
+ * @param protocolName
+ * @return
+ */
+ public synchronized static String[] getProtocolInfoGuid(String protocolName) {
+ Set set = spdTable.keySet();
+ Iterator iter = set.iterator();
+ String[] cNameGuid = null;
+
+ while (iter.hasNext()) {
+ Spd spd = (Spd) spdTable.get(iter.next());
+ cNameGuid = spd.getProtocolNameGuidArray(protocolName);
+ if (cNameGuid != null) {
+ break;
+ }
+ }
+ return cNameGuid;
+ }
+
+ public synchronized static String[] getPpiInfoGuid(String ppiName) {
+ Set set = spdTable.keySet();
+ Iterator iter = set.iterator();
+ String[] cNameGuid = null;
+
+ while (iter.hasNext()) {
+ Spd spd = (Spd) spdTable.get(iter.next());
+ cNameGuid = spd.getPpiCnameGuidArray(ppiName);
+
+ if (cNameGuid != null) {
+ break;
+ }
+ }
+ return cNameGuid;
+ }
+
+ /**
+ *
+ * @param guidName
+ * @return
+ */
+ public synchronized static String[] getGuidInfoGuid(String guidName) {
+ String[] cNameGuid = null;
+ Set set = spdTable.keySet();
+ Iterator iter = set.iterator();
+
+ while (iter.hasNext()) {
+ Spd spd = (Spd) spdTable.get(iter.next());
+ cNameGuid = spd.getGuidNameArray(guidName);
+ if (cNameGuid != null) {
+ break;
+ }
+ }
+ return cNameGuid;
+ }
+
+ public synchronized static String getLibClassIncluder(String libName) {
+ String libIncluder = null;
+ Set set = spdTable.keySet();
+ Iterator iter = set.iterator();
+
+ while (iter.hasNext()) {
+ String packageName = (String) iter.next();
+ Spd spd = (Spd) spdTable.get(packageName);
+ libIncluder = spd.getLibClassIncluder(libName);
+ String packagePath = spd.packagePath;
+ if (packagePath != null) {
+ packagePath = packagePath.replace('\\', File.separatorChar);
+ packagePath = packagePath.replace('/', File.separatorChar);
+ } else {
+ packagePath = packageName;
+ }
+ if (libIncluder != null) {
+ libIncluder = libIncluder.replace('\\', File.separatorChar);
+ libIncluder = libIncluder.replace('/', File.separatorChar);
+ libIncluder = packageName + File.separatorChar + libIncluder;
+ break;
+ }
+ }
+ return libIncluder;
+ }
+
+ public synchronized static String getModuleInfoByPackageName(String packageName, String moduleType) {
+ Spd spd;
+ String includeFile = null;
+ String includeStr = "";
+ String cleanPath = "";
+
+ spd = (Spd) spdTable.get(packageName);
+ includeFile = spd.getModuleTypeIncluder(moduleType);
+ if (includeFile != null) {
+ includeFile = includeFile.replace('\\', File.separatorChar);
+ includeFile = includeFile.replace('/', File.separatorChar);
+ includeStr = CommonDefinition.include + " <" + includeStr;
+ cleanPath = spd.packagePath;
+ cleanPath = cleanPath.replace('\\', File.separatorChar);
+ cleanPath = cleanPath.replace('/', File.separatorChar);
+
+ if (cleanPath.charAt(spd.packagePath.length() - 1) != File.separatorChar) {
+ cleanPath = cleanPath + File.separatorChar;
+ }
+ includeStr = includeStr + cleanPath;
+ includeStr = includeStr + includeFile;
+ includeStr = includeStr + ">\r\n";
+ }
+
+ return includeStr;
+ }
+
+ public synchronized static void setLibInstanceInfo(String libName, String libConstructor, String libDesturctor) {
+ String[] libConsDes = new String[2];
+ libConsDes[0] = libConstructor;
+ libConsDes[1] = libDesturctor;
+
+ libInstanceInfo.put(libName, libConsDes);
+ }
+
+ public synchronized static boolean isHaveLibInstance(String libName) {
+ return libInstanceInfo.containsKey(libName);
+ }
+
+ public synchronized static String getLibInstanceConstructor(String libName) {
+ String[] libInstanceValue;
+ libInstanceValue = libInstanceInfo.get(libName);
+ if (libInstanceValue != null) {
+ return libInstanceValue[0];
+ } else {
+ return null;
+ }
+ }
+
+ public synchronized static String getLibInstanceDestructor(String libName) {
+ String[] libInstanceValue;
+ libInstanceValue = libInstanceInfo.get(libName);
+ if (libInstanceValue != null) {
+ return libInstanceValue[1];
+ } else {
+ return null;
+ }
+ }
+
+ public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
+ return pcdDbManager;
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java b/Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java
new file mode 100644
index 0000000000..5912127a10
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java
@@ -0,0 +1,178 @@
+/*++
+
+ 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:
+ ShareObject.java
+
+ Abstract:
+
+ --*/
+package org.tianocore.build.global;
+
+import java.util.*;
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.types.DataType;
+
+public class GlobalShare extends DataType implements DynamicConfigurator {
+ private static final HashMap<String, Object> objStorage = new HashMap<String, Object>();
+
+ private DataObjectOp op;
+
+ private String objName;
+
+ private Object objInst;
+
+ private String objClassPackage = "org.tianocore";
+
+ public GlobalShare () {
+
+ }
+
+ public GlobalShare (String objName) {
+ this.objName = objName;
+ this.objInst = objStorage.get(this.objName);
+ }
+
+ public GlobalShare (String objName, Object obj) {
+ this.objName = objName;
+ this.objInst = obj;
+ objStorage.put(this.objName, this.objInst);
+ }
+
+ public Object createDynamicElement(String name) throws BuildException {
+ String className = objClassPackage + "." + name;
+ log("GlobalShare.createDynamicElement(" + name + ")",
+ Project.MSG_VERBOSE);
+ try {
+ objInst = Class.forName(className).newInstance();
+ } catch (ClassNotFoundException e) {
+ throw new BuildException("class name is not found");
+ } catch (InstantiationException e) {
+ throw new BuildException("the class cannnot be instantiated");
+ } catch (IllegalAccessException e) {
+ throw new BuildException("cannot access the class");
+ }
+
+ return objInst;
+ }
+
+ public void setDynamicAttribute(String name, String value)
+ throws BuildException {
+ log("name = " + name + " value = " + value, Project.MSG_VERBOSE);
+ throw new BuildException();
+ }
+
+ public void setName(String name) {
+ this.objName = name;
+ if (this.op != null) {
+ issueOperation();
+ }
+ }
+
+ public String getName() {
+ return this.objName;
+ }
+
+ public void setPackage(String name) {
+ log("ShareObject.setPackage(" + name + ")", Project.MSG_VERBOSE);
+ this.objClassPackage = name;
+ }
+
+ public String getPackage() {
+ return this.objClassPackage;
+ }
+
+ public void setOperation(String opName) {
+ log("ShareObject.setOperation(" + opName + ")", Project.MSG_VERBOSE);
+ this.op = DataObjectOp.formString(opName);
+
+ if (this.objName != null) {
+ issueOperation();
+ }
+ }
+
+ public String getOperation() {
+ return this.op.toString();
+ }
+
+ public void issueOperation() {
+ if (this.op == DataObjectOp.ADD) {
+
+ log("ShareObject: adding ... " + this.objName, Project.MSG_VERBOSE);
+ objStorage.put(this.objName, this.objInst);
+
+ } else if (this.op == DataObjectOp.GET) {
+
+ log("ShareObject: fetching ... " + this.objName,
+ Project.MSG_VERBOSE);
+ objInst = objStorage.get(objName);
+
+ } else if (this.op == DataObjectOp.DEL) {
+
+ log("ShareObject: removing ... " + this.objName,
+ Project.MSG_VERBOSE);
+ objInst = objStorage.remove(objName);
+
+ } else {
+ throw new BuildException("not supported operation");
+ }
+ }
+
+ public Object get() {
+ return this.objInst;
+ }
+
+ public static int getObjectNum() {
+ return objStorage.size();
+ }
+
+ public static Object add(String objName, Object obj) {
+ return objStorage.put(objName, obj);
+ }
+
+ public static Object retrieve(String objName) {
+ return objStorage.get(objName);
+ }
+
+ public static Object remove(String objName) {
+ return objStorage.remove(objName);
+ }
+
+ public static void empty() {
+ objStorage.clear();
+ }
+}
+
+class DataObjectOp {
+ private static final HashMap<String, DataObjectOp> opMap = new HashMap<String, DataObjectOp>();
+
+ private final String opName;
+
+ private DataObjectOp (String name) {
+ this.opName = name;
+ opMap.put(this.opName, this);
+ }
+
+ public String toString() {
+ return opName;
+ }
+
+ public static DataObjectOp formString(String opName) {
+ return opMap.get(opName);
+ }
+
+ public static final DataObjectOp ADD = new DataObjectOp("ADD");
+
+ public static final DataObjectOp GET = new DataObjectOp("GET");
+
+ public static final DataObjectOp DEL = new DataObjectOp("DEL");
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java b/Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java
new file mode 100644
index 0000000000..4d7e870587
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java
@@ -0,0 +1,412 @@
+/** @file
+ This file is an ANT task.
+
+ LibBuildFileGenerator task is used to generate module's build.xml 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.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.xmlbeans.XmlObject;
+import org.tianocore.MsaHeaderDocument.MsaHeader;
+import org.tianocore.MsaLibHeaderDocument.MsaLibHeader;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ This class <code>LibBuildFileGenerator</code> is an ANT task to generate
+ build.xml for each module. Here are two usages.
+
+ <ul>
+ <li>
+ For one module (<b>bf</b> is LibBuildFileGenerator task name):
+ <pre>
+ &lt;bf buildFile="Application\HelloWorld\HelloWorld.msa" /&gt;
+ </pre>
+ </li>
+ <li>
+ For one package:
+ <pre>
+ &lt;bf recursive="true" /&gt;
+ </pre>
+ </li>
+ </ul>
+
+ @since GenBuild 1.0
+**/
+public class LibBuildFileGenerator extends Task {
+
+ private File buildFile;
+
+ private boolean recursive = false;
+
+ private String license = " Copyright (c) 2006, Intel Corporation \n"
+ + "All rights reserved. This program and the accompanying materials \n"
+ + "are licensed and made available under the terms and conditions of the BSD License \n"
+ + "which accompanies this distribution. The full text of the license may be found at \n"
+ + "http://opensource.org/licenses/bsd-license.php \n"
+ + "\n"
+ + "THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, \n"
+ + "WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.";
+
+ private String base_name;
+
+ private String module_relative_path;
+
+ private File base_file = new File(".");
+
+ /**
+ Public construct method. It is necessary for ANT task.
+ **/
+ public LibBuildFileGenerator () {
+ }
+
+ /**
+ ANT task's entry point, will be called after init().
+
+ @throws BuildException
+ buildFile do not specify while recursive set to false
+ **/
+ public void execute() throws BuildException {
+ if(recursive){
+ searchMsa(new File("."));
+ }
+ else {
+ Map<String,File> map = new HashMap<String,File>();
+ String basename = buildFile.getName();
+ int k = basename.lastIndexOf('.');
+ base_name = basename.substring(0, k);
+ map.put(base_name, buildFile);
+ genBuildFile(map);
+ }
+ }
+
+ /**
+ Recursivly find all MSA files and record all modules.
+
+ @param path Package path
+ **/
+ private void searchMsa(File path){
+ File[] files = path.listFiles();
+ Vector<File> vec = new Vector<File>();
+ for(int i=0; i < files.length; i ++){
+ if (files[i].isFile()){
+ if(files[i].getName().endsWith(".msa")){
+ System.out.println("#" + files[i].getPath());
+ vec.add(files[i]);
+ }
+ }
+ }
+ Map<String,File> mapBasename = new HashMap<String,File>();
+ if (vec.size() > 0){
+ base_name = null;
+ for ( int j = 0 ; j < vec.size(); j++){
+ if ( vec.size() > 1){
+ System.out.println("##" + vec.get(0));
+ }
+ File f = (File)vec.get(j);
+ SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
+ Map<String, XmlObject> map = surfaceAreaParser.parseFile(f);
+ String baseName = "";
+ XmlObject header = null;
+ if ( (header = map.get("MsaHeader")) != null ){
+ baseName = ((MsaHeader)header).getBaseName().getStringValue();
+ }
+ else if ( (header = map.get("MsaLibHeader")) != null){
+ baseName = ((MsaLibHeader)header).getBaseName().getStringValue();
+ } else {
+ continue ;
+ }
+ if ( base_name == null || base_name.length() > baseName.length()){
+ base_name = baseName;
+ buildFile = f;
+ try {
+ module_relative_path = buildFile.getParent().substring(base_file.getPath().length() + 1);
+ }
+ catch(Exception e){
+ module_relative_path = ".";
+ }
+ }
+ mapBasename.put(baseName, f);
+ }
+ genBuildFile(mapBasename);
+ }
+
+ for(int i=0; i < files.length; i ++){
+ if (files[i].isDirectory()){
+ searchMsa(files[i]);
+ }
+ }
+ }
+
+ /**
+ Generate build.xml.
+
+ @param map All base name under one module directory
+ **/
+ private void genBuildFile(Map map) {
+ DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
+ try {
+ DocumentBuilder dombuilder = domfac.newDocumentBuilder();
+ Document document = dombuilder.newDocument();
+ //
+ // create root element and its attributes
+ //
+ document.appendChild(document.createComment(license));
+ Element root = document.createElement("project");
+ root.setAttribute("default", base_name);
+ 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);
+ //
+ // <taskdef resource="net/sf/antcontrib/antlib.xml" />
+ //
+ 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);
+
+ ele = document.createElement("property");
+ ele.setAttribute("name", "WORKSPACE_DIR");
+ ele.setAttribute("value", "${env.WORKSPACE}");
+ root.appendChild(ele);
+
+ ele = document.createElement("import");
+ ele.setAttribute("file", "${WORKSPACE_DIR}"+File.separatorChar+"Tools"+File.separatorChar+"Conf"+File.separatorChar+"BuildMacro.xml");
+ root.appendChild(ele);
+
+ root.appendChild(document.createComment("MODULE_RELATIVE PATH is relative to PACKAGE_DIR"));
+ ele = document.createElement("property");
+ ele.setAttribute("name", "MODULE_RELATIVE_PATH");
+ ele.setAttribute("value", module_relative_path);
+ root.appendChild(ele);
+
+ ele = document.createElement("property");
+ ele.setAttribute("name", "MODULE_DIR");
+ ele.setAttribute("value", "${PACKAGE_DIR}" + File.separatorChar + "${MODULE_RELATIVE_PATH}");
+ root.appendChild(ele);
+
+ ele = document.createElement("property");
+ ele.setAttribute("name", "COMMON_FILE");
+ ele.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar + "Tools"
+ + File.separatorChar + "Conf" + File.separatorChar + "Common.xml");
+ root.appendChild(ele);
+
+ //
+ // generate the buildfmd target
+ //
+ Set set = map.keySet();
+ Iterator iter = set.iterator();
+ while (iter.hasNext()){
+ String bName = (String)iter.next();
+ File msaFile = (File)map.get(bName);
+ String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();
+ String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";
+ ele = document.createElement("target");
+ ele.setAttribute("name", bName);
+ Element target = document.createElement("GenBuild");
+ target.setAttribute("msaFilename", msaFilename);
+ target.setAttribute("mbdFilename", mbdFilename);
+ target.setAttribute("baseName", bName);
+ ele.appendChild(target);
+ root.appendChild(ele);
+ }
+
+ root.appendChild(ele);
+ //
+ // Default clean
+ //
+ ele = document.createElement("target");
+ ele.setAttribute("name", "clean");
+ ele.setAttribute("depends", base_name + "_clean");
+ root.appendChild(ele);
+ //
+ // Default Clean ALl
+ //
+ ele = document.createElement("target");
+ ele.setAttribute("name", "cleanall");
+ ele.setAttribute("depends", base_name + "_cleanall");
+ root.appendChild(ele);
+ //
+ // Every clean target for each BaseName
+ //
+ set = map.keySet();
+ iter = set.iterator();
+ while (iter.hasNext()){
+ String bName = (String)iter.next();
+ File msaFile = (File)map.get(bName);
+ String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();
+ String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";
+
+ ele = document.createElement("target");
+ ele.setAttribute("name", bName + "_clean");
+ //
+ // Output Dir
+ //
+ Element target = document.createElement("OutputDirSetup");
+ target.setAttribute("msaFilename", msaFilename);
+ target.setAttribute("mbdFilename", mbdFilename);
+ target.setAttribute("baseName", bName);
+ ele.appendChild(target);
+ //
+ // Call BaseName_build.xml clean
+ //
+ Element ifEle = document.createElement("if");
+ Element availableEle = document.createElement("available");
+ availableEle.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");
+ ifEle.appendChild(availableEle);
+ Element elseEle = document.createElement("then");
+
+ Element moduleEle = document.createElement("ant");
+ moduleEle.setAttribute("antfile", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");
+ moduleEle.setAttribute("target", "clean");
+
+ elseEle.appendChild(moduleEle);
+ ifEle.appendChild(elseEle);
+ ele.appendChild(ifEle);
+ //
+ // just delete
+ //
+ Element clean = document.createElement("delete");
+ clean.setAttribute("dir", "${DEST_DIR_OUTPUT}");
+ clean.setAttribute("excludes", "*.xml");
+ ele.appendChild(clean);
+
+ root.appendChild(ele);
+ }
+ //
+ // Every Clean ALl target for each BaseName
+ //
+ set = map.keySet();
+ iter = set.iterator();
+ while (iter.hasNext()){
+ String bName = (String)iter.next();
+ File msaFile = (File)map.get(bName);
+ String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();
+ String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";
+
+ ele = document.createElement("target");
+ ele.setAttribute("name", bName + "_cleanall");
+ //
+ // Output Dir
+ //
+ Element target = document.createElement("OutputDirSetup");
+ target.setAttribute("msaFilename", msaFilename);
+ target.setAttribute("mbdFilename", mbdFilename);
+ target.setAttribute("baseName", bName);
+ ele.appendChild(target);
+ //
+ // Call BaseName_build.xml clean
+ //
+ Element ifEle = document.createElement("if");
+ Element availableEle = document.createElement("available");
+ availableEle.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");
+ ifEle.appendChild(availableEle);
+ Element elseEle = document.createElement("then");
+
+ Element moduleEle = document.createElement("ant");
+ moduleEle.setAttribute("antfile", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");
+ moduleEle.setAttribute("target", "cleanall");
+
+ elseEle.appendChild(moduleEle);
+ ifEle.appendChild(elseEle);
+ ele.appendChild(ifEle);
+ //
+ // just delete
+ //
+ Element clean = document.createElement("delete");
+ clean.setAttribute("dir", "${DEST_DIR_OUTPUT}");
+ ele.appendChild(clean);
+
+ clean = document.createElement("delete");
+ clean.setAttribute("dir", "${DEST_DIR_DEBUG}");
+ ele.appendChild(clean);
+
+ clean = document.createElement("delete");
+ Element fileset = document.createElement("fileset");
+ fileset.setAttribute("dir", "${BIN_DIR}");
+ fileset.setAttribute("includes", "**" + bName + "*");
+ clean.appendChild(fileset);
+ ele.appendChild(clean);
+
+ root.appendChild(ele);
+ }
+ document.appendChild(root);
+ //
+ // Prepare the DOM document for writing
+ //
+ Source source = new DOMSource(document);
+ //
+ // Prepare the output file
+ //
+ String filename = buildFile.getParent() + File.separatorChar + "build.xml";
+ File file = new File(getProject().replaceProperties(filename));
+ //
+ // generate all directory path
+ //
+ Result result = new StreamResult(file);
+ //
+ // Write the DOM document to the file
+ //
+ Transformer xformer = TransformerFactory.newInstance()
+ .newTransformer();
+ xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+ xformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ xformer.transform(source, result);
+ } catch (Exception ex) {
+ System.out.println("##" + ex);
+ }
+ }
+
+
+ public File getBuildFile() {
+ return buildFile;
+ }
+
+ public void setBuildFile(File buildFile) {
+ this.buildFile = buildFile;
+ }
+
+ public boolean isRecursive() {
+ return recursive;
+ }
+
+ public void setRecursive(boolean recursive) {
+ this.recursive = recursive;
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java b/Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java
new file mode 100644
index 0000000000..74311d4541
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java
@@ -0,0 +1,55 @@
+package org.tianocore.build.global;
+
+public class ModuleIdentification {
+
+ private String baseName;
+
+ private String packageName;
+
+ private String guid;
+
+ private String version;
+
+ public ModuleIdentification(String baseName, String packageName, String guid, String version){
+ this.baseName = baseName;
+ this.packageName = packageName;
+ this.guid = guid;
+ this.version = version;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof ModuleIdentification) {
+ ModuleIdentification moduleIdObj = (ModuleIdentification)obj;
+ if ( baseName.equalsIgnoreCase(moduleIdObj.baseName)) {
+ return true;
+ }
+ // TBD
+ return false;
+ }
+ else {
+ return super.equals(obj);
+ }
+ }
+
+ public String toString(){
+ return packageName + ":" + guid + "_" + baseName + "_" + version;
+ }
+
+ public void setBaseName(String baseName) {
+ this.baseName = baseName;
+ }
+
+ public void setGuid(String guid) {
+ this.guid = guid;
+ }
+
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/OnDependency.java b/Tools/Source/GenBuild/org/tianocore/build/global/OnDependency.java
new file mode 100644
index 0000000000..936dac8ea3
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/OnDependency.java
@@ -0,0 +1,121 @@
+/** @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 org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Sequential;
+
+import java.io.File;
+import java.util.Iterator;
+
+/**
+ 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() {
+ if (isOutOfDate() && task != null) {
+ task.perform();
+ }
+ }
+
+ ///
+ /// 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) {
+ return true;
+ }
+
+ Iterator dstIt = targets.nameList.iterator();
+ while (dstIt.hasNext()) {
+ String dstFileName = (String)dstIt.next();
+ File dstFile = new File(dstFileName);
+ if (!dstFile.exists()) {
+ return true;
+ }
+
+ long dstTimeStamp = dstFile.lastModified();
+ Iterator srcIt = sources.nameList.iterator();
+ while (srcIt.hasNext()) {
+ String srcFileName = (String)srcIt.next();
+ File srcFile = new File(srcFileName);
+ if (!srcFile.exists()) {
+ throw new BuildException(srcFileName + " doesn't exist !!!");
+ }
+
+ if (dstTimeStamp < srcFile.lastModified()) {
+ return true;
+ }
+ }
+ }
+
+ 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/Source/GenBuild/org/tianocore/build/global/OutputManager.java b/Tools/Source/GenBuild/org/tianocore/build/global/OutputManager.java
new file mode 100644
index 0000000000..01e24e653f
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/OutputManager.java
@@ -0,0 +1,176 @@
+/** @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) according to BUILD_MODE.
+
+ @since GenBuild 1.0
+**/
+public class OutputManager {
+
+ ///
+ /// Single Module build
+ ///
+ public static final String MODULE_BUILD = "MODULE";
+
+ ///
+ /// Package build
+ ///
+ public static final String PACKAGE_BUILD = "PACKAGE";
+
+ ///
+ /// Platform build
+ ///
+ public static final String PLATFORM_BUILD = "PLATFORM";
+
+ public static String buildMode = MODULE_BUILD;
+
+ ///
+ /// For Package build, PLATFORM represent PACKAGE
+ ///
+ public static String PLATFORM;
+
+ ///
+ /// For Platform build, PLATFORM_DIR represent PACKAGE_DIR
+ ///
+ public static String PLATFORM_DIR;
+
+ ///
+ /// means intermediate files will put under Module's dir
+ ///
+ public static final String MODULE = "MODULE";
+
+ ///
+ /// mean intermediate files will put under a unify dir
+ ///
+ public static final String UNIFIED = "UNIFIED";
+
+ ///
+ /// Flag to ensure the function <code>update</code> will be called only one in the whole build.
+ ///
+ private static boolean flag = true;
+
+ /**
+ If BUILD_MODE is PLATFORM or PACKAGE, record PLATFORM and PLARFORM_DIR.
+ Reminder that for PACKAGE build, here set value PACKAGE to PLATFORM and
+ PACKAGE_DIR to PLARFORM_DIR, and also update the ant properties.
+
+ <p>Note that this function will be called only once in the whole build.</p>
+
+ @param project current ANT build Project
+ **/
+ public synchronized static void update(Project project) {
+ if (flag){
+ flag = false;
+ String str = project.getProperty("BUILD_MODE");
+ if (str != null){
+ if (str.equals(PLATFORM_BUILD)) {
+ buildMode = PLATFORM_BUILD;
+ PLATFORM = project.getProperty("PLATFORM");
+ PLATFORM_DIR = project.getProperty("PLATFORM_DIR");
+ }
+ else if (str.equals(PACKAGE_BUILD)) {
+ buildMode = PACKAGE_BUILD;
+ PLATFORM = project.getProperty("PACKAGE");
+ PLATFORM_DIR = project.getProperty("PACKAGE_DIR");
+ project.setProperty("PLATFORM", PLATFORM);
+ project.setProperty("PLATFORM_DIR", PLATFORM_DIR);
+ }
+ }
+ }
+ }
+
+ /**
+ Setup BIN_DIR, DEST_DIR_OUTPUT and DEST_DIR_OUTPUT, following are the rules:
+
+ <pre>
+ Those three variables are defined as following
+ DEST_DIR_OUTPUT (intermediate files)
+ DEST_DIR_DEBUG (intermediate debug files)
+ BIN_DIR (final files)
+
+ Output Dir (MODULE or UNIFIED):
+ For <b>Module</b> build:
+ All intermediate files are at ${MODULE_DIR}/Build/${TARGET}/${ARCH}/DEBUG|OUTPUT
+ All final files are at ${MODULE_DIR}/Build/${TARGET}/${ARCH}
+
+ For <b>Platform</b> build:
+ If specified with MODULE
+ Intermediate files->${MODULE_DIR}/Build/${PLATFORM}/${TARGET}/${ARCH}/DEBUG|OUTPUT
+ Final files -> ${PLARFORM_DIR}/Build/${TARGET}/${ARCH}
+
+ Else if specified with UNIFIED
+ Intermediate files->${PLARFORM_DIR}/Build/${TARGET}/${ARCH}/${PACKAGE}/${SOURCE_RELATIVE_PATH}/DEBUG|OUTPUT
+ Final files -> ${PLARFORM_DIR}/Build/${TARGET}/${ARCH}
+
+ For <b>Package</b> build:
+ If specified with MODULE
+ Intermediate files->${MODULE_DIR}/Build/${PACKAGE}/${TARGET}/${ARCH}/DEBUG|OUTPUT
+ Final files -> ${PACKAGE_DIR}/Build/${TARGET}/${ARCH}
+
+ Else if specified with UNIFIED
+ Intermediate files->${PACKAGE_DIR}/Build/${TARGET}/${ARCH}/${PACKAGE}/${SOURCE_RELATIVE_PATH}/DEBUG|OUTPUT
+ Final files -> ${PACKAGE_DIR}/Build/${TARGET}/${ARCH}
+ </pre>
+
+ @param project current ANT build Project
+ @param userdir user-defined directory
+ @param type the module build type (MODULE or UNIFIED)
+ **/
+ public synchronized static void update(Project project, String userdir, String type) {
+ //
+ // userdir TBD
+ //
+ if( type == null || ! type.equals(MODULE)){
+ type = UNIFIED;
+ }
+ if (buildMode.equals(MODULE_BUILD)){
+ project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${MODULE_DIR}"
+ + File.separatorChar + "Build" + File.separatorChar + "${TARGET}"
+ + File.separatorChar + "${ARCH}" + File.separatorChar + "OUTPUT"));
+ project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "DEBUG"));
+ project.setProperty("BIN_DIR", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));
+ }
+ else if (buildMode.equals(PLATFORM_BUILD)) {
+ if (type.equals(MODULE)) {
+ project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "OUTPUT"));
+ project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "DEBUG"));
+ project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));
+ }
+ else if (type.equals(UNIFIED)){
+ project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "OUTPUT"));
+ project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "DEBUG"));
+ project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));
+ }
+ }
+ else if (buildMode.equals(PACKAGE_BUILD)) {
+ if (type.equals(MODULE)) {
+ project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "OUTPUT"));
+ project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "DEBUG"));
+ project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));
+ }
+ else if (type.equals(UNIFIED)){
+ project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "OUTPUT"));
+ project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "DEBUG"));
+ project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));
+ }
+ }
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java b/Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java
new file mode 100644
index 0000000000..dae2ca29aa
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java
@@ -0,0 +1,354 @@
+/** @file
+ OverrideProcess class.
+
+ OverrideProcess class is used to override surface area 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.global;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlObject;
+import org.tianocore.BootModesDocument;
+import org.tianocore.BuildOptionsDocument;
+import org.tianocore.DataHubsDocument;
+import org.tianocore.EventsDocument;
+import org.tianocore.ExternsDocument;
+import org.tianocore.FormsetsDocument;
+import org.tianocore.GuidsDocument;
+import org.tianocore.HobsDocument;
+import org.tianocore.IncludesDocument;
+import org.tianocore.LibrariesDocument;
+import org.tianocore.LibraryClassDefinitionsDocument;
+import org.tianocore.MsaHeaderDocument;
+import org.tianocore.MsaLibHeaderDocument;
+import org.tianocore.PCDsDocument;
+import org.tianocore.PPIsDocument;
+import org.tianocore.ProtocolsDocument;
+import org.tianocore.SourceFilesDocument;
+import org.tianocore.SystemTablesDocument;
+import org.tianocore.VariablesDocument;
+
+/**
+ This class is used to override surface area information. For example, MBD can
+ overried MSA, Platform can override all information of the module.
+
+ <p>Override will take effect if two element satisfy one of following two condition: </p>
+ <ul>
+ <li>Element name and its attribute OverrideID equal each other. </li>
+ <li>Element is defined as exclusive which mean such element can be
+ only appeared in the surface area. </li>
+ </ul>
+
+ <p>For example, here OutputDirectory element is exclusive: </p>
+
+ <pre>
+ Low priority Xml Document fragment:
+ &lt;Libraries&gt;
+ &lt;Arch ArchType="IA32"&gt;
+ &lt;Library OverrideID="8888"&gt;EdkPeCoffLoaderLib&lt;/Library&gt;
+ &lt;Library OverrideID="8888"&gt;BasePeCoffLib&lt;/Library&gt;
+ &lt;/Arch&gt;
+ &lt;/Libraries&gt;
+ &lt;BuildOptions&gt;
+ &lt;OutputDirectory IntermediateDirectories="MODULE"/&gt;
+ &lt;Option&gt;CC_FLAGS = "/NOLOGO", "/C"&lt;/Option&gt;
+ &lt;BuildOptions&gt;
+
+ High priority Xml Document fragment:
+ &lt;Libraries&gt;
+ &lt;Arch ArchType="IA32"&gt;
+ &lt;Library OverrideID="8888">Nt32PeCoffLoaderLib&lt;/Library&gt;
+ &lt;/Arch&gt;
+ &lt;/Libraries&gt;
+ &lt;BuildOptions&gt;
+ &lt;OutputDirectory IntermediateDirectories="UNIFIED"/&gt;
+ &lt;Option&gt;LIB_FLAGS = "/NOLOGO"&lt;/Option&gt;
+ &lt;BuildOptions&gt;
+
+ The result is:
+ &lt;Libraries&gt;
+ &lt;Arch ArchType="IA32"&gt;
+ &lt;Library OverrideID="8888"&gt;Nt32PeCoffLoaderLib&lt;/Library&gt;
+ &lt;/Arch&gt;
+ &lt;/Libraries&gt;
+ &lt;BuildOptions&gt;
+ &lt;OutputDirectory IntermediateDirectories="UNIFIED"/&gt;
+ &lt;Option&gt;CC_FLAGS = "/NOLOGO", "/C"&lt;/Option&gt;
+ &lt;Option&gt;LIB_FLAGS = "/NOLOGO"&lt;/Option&gt;
+ &lt;BuildOptions&gt;
+
+ </pre>
+
+ <p>Note that using XmlBeans to walk through the whole XML document tree.</p>
+
+ @since GenBuild 1.0
+ @see org.apache.xmlbeans.XmlBeans
+**/
+public class OverrideProcess {
+
+ ///
+ /// URI, the namespace of current XML schema
+ ///
+ public static String prefix = "http://www.TianoCore.org/2006/Edk2.0";
+
+ ///
+ /// list of top elements of surface area
+ ///
+ public static String[] topElements = { "LibraryClassDefinitions",
+ "SourceFiles", "Includes", "Libraries", "Protocols",
+ "Events", "Hobs", "PPIs", "Variables", "BootModes",
+ "SystemTables", "DataHubs", "Formsets", "Guids", "Externs",
+ "PCDs", "BuildOptions" };
+
+ ///
+ /// list of exclusive elements
+ ///
+ public static String[] exclusiveElements = {"OutputDirectory"};
+
+ /**
+ Recursively find out all elements specified with OverrideId attribute
+ and exclusive elements in current XML object.
+
+ @param o curent parsing XML object
+ @param map Map to list elements specified OverrideID attribute
+ @param execlusiveMap Map to list exclusive elements appeared in current XMl object
+ @param level the depth in XML document tree
+ **/
+ private void listOverrideID(XmlObject o, Map<String,Object> map, Map<String,Object> execlusiveMap, int level) {
+ XmlCursor cursor = o.newCursor();
+ String name = cursor.getName().getLocalPart();
+ for (int i = 0 ; i < exclusiveElements.length; i++){
+ if (name.equalsIgnoreCase(exclusiveElements[i])){
+ execlusiveMap.put(exclusiveElements[i], cursor.getObject());
+ }
+ }
+ String overrideID = cursor.getAttributeText(new QName("OverrideID"));
+ if (overrideID != null) {
+ map.put(name + ":" + overrideID, cursor.getObject());
+ }
+ if (cursor.toFirstChild()) {
+ do {
+ listOverrideID(cursor.getObject(), map, execlusiveMap, level + 1);
+ } while (cursor.toNextSibling());
+ }
+ }
+
+ /**
+ This function is used to prepare for overriding with changing data.
+
+ @param map original surface area information
+ @return after normalize surface area information
+ **/
+ public synchronized static Map<String, XmlObject> deal(Map<String, XmlObject> map) {
+ Map<String, XmlObject> newMap = new HashMap<String, XmlObject>();
+ if (map.get("MsaHeader") != null) {
+ newMap.put("MsaHeader", ((MsaHeaderDocument) map.get("MsaHeader"))
+ .getMsaHeader());
+ }
+ if (map.get("MsaLibHeader") != null) {
+ newMap.put("MsaLibHeader", ((MsaLibHeaderDocument) map
+ .get("MsaLibHeader")).getMsaLibHeader());
+ }
+ if (map.get("LibraryClassDefinitions") != null) {
+ newMap.put("LibraryClassDefinitions",
+ ((LibraryClassDefinitionsDocument) map
+ .get("LibraryClassDefinitions"))
+ .getLibraryClassDefinitions());
+ }
+ if (map.get("SourceFiles") != null) {
+ newMap.put("SourceFiles", ((SourceFilesDocument) map
+ .get("SourceFiles")).getSourceFiles());
+ }
+ if (map.get("Includes") != null) {
+ newMap.put("Includes", ((IncludesDocument) map.get("Includes"))
+ .getIncludes());
+ }
+ if (map.get("Libraries") != null) {
+ newMap.put("Libraries", ((LibrariesDocument) map.get("Libraries"))
+ .getLibraries());
+ }
+ if (map.get("Protocols") != null) {
+ newMap.put("Protocols", ((ProtocolsDocument) map.get("Protocols"))
+ .getProtocols());
+ }
+ if (map.get("Events") != null) {
+ newMap.put("Events", ((EventsDocument) map.get("Events"))
+ .getEvents());
+ }
+ if (map.get("Hobs") != null) {
+ newMap.put("Hobs", ((HobsDocument) map.get("Hobs")).getHobs());
+ }
+ if (map.get("PPIs") != null) {
+ newMap.put("PPIs", ((PPIsDocument) map.get("PPIs")).getPPIs());
+ }
+ if (map.get("Variables") != null) {
+ newMap.put("Variables", ((VariablesDocument) map.get("Variables"))
+ .getVariables());
+ }
+ if (map.get("BootModes") != null) {
+ newMap.put("BootModes", ((BootModesDocument) map.get("BootModes"))
+ .getBootModes());
+ }
+ if (map.get("SystemTables") != null) {
+ newMap.put("SystemTables", ((SystemTablesDocument) map
+ .get("SystemTables")).getSystemTables());
+ }
+ if (map.get("DataHubs") != null) {
+ newMap.put("DataHubs", ((DataHubsDocument) map.get("DataHubs"))
+ .getDataHubs());
+ }
+ if (map.get("Formsets") != null) {
+ newMap.put("Formsets", ((FormsetsDocument) map.get("Formsets"))
+ .getFormsets());
+ }
+ if (map.get("Guids") != null) {
+ newMap.put("Guids", ((GuidsDocument) map.get("Guids")).getGuids());
+ }
+ if (map.get("Externs") != null) {
+ newMap.put("Externs", ((ExternsDocument) map.get("Externs"))
+ .getExterns());
+ }
+ if (map.get("PCDs") != null) {
+ newMap.put("PCDs", ((PCDsDocument) map.get("PCDs")).getPCDs());
+ }
+ if (map.get("BuildOptions") != null) {
+ newMap.put("BuildOptions", ((BuildOptionsDocument) map
+ .get("BuildOptions")).getBuildOptions());
+ }
+ return newMap;
+ }
+
+ /**
+ Recursively remove all subelement in Xml Object l (with low priority)
+ based on OverrideID or exclusive elements.
+
+ @param l the XML object to process
+ @param map list of elements with OverrideID in high priority XML object
+ @param execusiveMap list of exclusive elements in high priority XML object
+ **/
+ private void cut(XmlCursor l, Map map, Map execusiveMap) {
+ String name = l.getName().getLocalPart();
+ if (execusiveMap.containsKey(name)){
+ l.removeXml();
+ return;
+ }
+ String overrideID = l.getAttributeText(new QName("OverrideID"));
+ if (overrideID != null) {
+ if (map.containsKey(name + ":" + overrideID)) {
+ l.removeXml();
+ return;
+ }
+ }
+ if (l.toFirstChild()) {
+ do {
+ cut(l, map, execusiveMap);
+ } while (l.toNextSibling());
+ }
+ }
+
+ private XmlObject cloneXmlObject(XmlObject object, boolean deep) throws BuildException {
+ XmlObject result = null;
+ try {
+ result = XmlObject.Factory.parse(object.getDomNode()
+ .cloneNode(deep));
+ } catch (Exception ex) {
+ throw new BuildException(ex.getMessage());
+ }
+ return result;
+ }
+
+ /**
+ Process every item list in h and l.
+
+ @param h surface area info with high priority
+ @param l surface area info with low priority
+ @return surface area after override
+ **/
+ public Map<String, XmlObject> override(Map<String, XmlObject> h,
+ Map<String, XmlObject> l) {
+ Map<String, XmlObject> result = new HashMap<String, XmlObject>();
+ result.put("MsaHeader", override(l.get("MsaHeader"), null));
+ result.put("MsaLibHeader", override(l.get("MsaLibHeader"), null));
+ for (int i = 0; i < topElements.length; i++) {
+ result.put(topElements[i], override(h.get(topElements[i]), l
+ .get(topElements[i])));
+ }
+ return result;
+ }
+
+ /**
+ Recursively override two Xml Objects.
+
+ @param h Xml Object info with high priority
+ @param l Xml Object info with low priority
+ @return Xml Object after area
+ **/
+ public XmlObject override(XmlObject h, XmlObject l) {
+ if (l == null && h == null) {
+ return null;
+ }
+ if (h == null) {
+ return cloneXmlObject(l, true);
+ }
+ if (l == null) {
+ return cloneXmlObject(h, true);
+ }
+ XmlCursor hc = h.newCursor();
+ if (h.getClass() != l.getClass()) {
+ System.out
+ .println("Error: Two XmlObject does not with compliant format.");
+ return null;
+ }
+ if (!hc.toFirstChild()) {
+ return cloneXmlObject(l, true);
+ }
+
+ XmlCursor result = cloneXmlObject(h, true).newCursor();
+ XmlCursor lcursor = cloneXmlObject(l, true).newCursor();
+ result.push();
+ result.toNextToken();
+ result.insertNamespace("", prefix);
+ result.toFirstChild();
+ //
+ // found out all element specified a OverrideID
+ //
+ Map<String,Object> hmap = new HashMap<String,Object>();
+ Map<String,Object> execlusiveMap = new HashMap<String,Object>();
+ listOverrideID(h, hmap, execlusiveMap, 0);
+ lcursor.toNextToken();
+ lcursor.push();
+ //
+ // for every direct subelement of l, cut all element satisfied with
+ // override rule
+ //
+ if (lcursor.toFirstChild()) {
+ do {
+ cut(lcursor, hmap, execlusiveMap);
+ } while (lcursor.toNextSibling());
+ }
+ lcursor.pop();
+ if (lcursor.toFirstChild()) {
+ do {
+ lcursor.copyXml(result);
+ result.insertChars("\n");
+ } while (lcursor.toNextSibling());
+ }
+ result.pop();
+ return result.getObject();
+ }
+} \ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/Spd.java b/Tools/Source/GenBuild/org/tianocore/build/global/Spd.java
new file mode 100644
index 0000000000..54c1391094
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/Spd.java
@@ -0,0 +1,414 @@
+/** @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.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.tianocore.PackageSurfaceAreaDocument;
+import org.tianocore.GuidDeclarationsDocument.GuidDeclarations;
+import org.tianocore.IncludeHeaderDocument.IncludeHeader;
+import org.tianocore.LibraryClassDeclarationDocument.LibraryClassDeclaration;
+import org.tianocore.LibraryClassDeclarationsDocument.LibraryClassDeclarations;
+import org.tianocore.PackageHeadersDocument.PackageHeaders;
+import org.tianocore.PackageSurfaceAreaDocument.PackageSurfaceArea;
+import org.tianocore.PpiDeclarationsDocument.PpiDeclarations;
+import org.tianocore.ProtocolDeclarationsDocument.ProtocolDeclarations;
+
+/**
+
+ This class is to generate a global table for the content of spd file.
+
+**/
+public class Spd {
+ ///
+ /// Map of module name and package it belongs to.
+ /// Key : Module BaseName
+ /// Value: Relative Path to Package
+ ///
+ Map<String, String[]> msaInfo = new HashMap<String, String[]>();
+
+ ///
+ /// Map of module info.
+ /// Key : moduletype
+ /// Value: moduletype related include file
+ ///
+ Map<String, String> moduleInfo = 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 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.
+ ///
+ String packagePath = null;
+
+ /**
+ Constructor function
+
+ This function mainly initialize some member variables.
+
+ @param spdDoc Handle of spd document.
+ @param spdPath Path of spd file.
+ **/
+ Spd (PackageSurfaceAreaDocument spdDoc, String spdPath) {
+
+ PackageSurfaceArea spd = spdDoc.getPackageSurfaceArea();
+ this.packagePath = spdPath;
+
+ GuidDeclarations spdGuidInfo = spd.getGuidDeclarations();
+ genGuidInfoList(spdGuidInfo);
+
+ PpiDeclarations spdPpiInfo = spd.getPpiDeclarations();
+ genPpiInfoList(spdPpiInfo);
+
+ ProtocolDeclarations spdProtocolInfo = spd.getProtocolDeclarations();
+ genProtocolInfoList(spdProtocolInfo);
+
+ LibraryClassDeclarations spdLibClassDeclare = spd
+ .getLibraryClassDeclarations();
+ genLibClassDeclare(spdLibClassDeclare);
+
+ PackageHeaders spdPackageHeaderInfo = spd.getPackageHeaders();
+ genModuleInfoList(spdPackageHeaderInfo);
+
+ }
+
+ /**
+ genModuleInfoList
+
+ This function is to generate Module info map.
+
+ @param packageHeader The information of packageHeader which descripted
+ in spd file.
+ **/
+ public void genModuleInfoList(PackageHeaders packageHeader) {
+
+ if (packageHeader != null) {
+ List<IncludeHeader> headerList = packageHeader.getIncludeHeaderList();
+ for (int i = 0; i < headerList.size(); i++) {
+ try {
+ this.moduleInfo
+ .put(headerList.get(i).getModuleType()
+ .toString(), headerList.get(i)
+ .getStringValue());
+ } catch (Exception e) {
+ System.out
+ .print("can't find ModuleHeaders ModuleType & includeHeader!\n");
+ }
+ }
+ }
+ }
+
+ /**
+ genPpiInfoList
+
+ This function is to generate Ppi info map.
+
+ @param ppiInfo The information of PpiDeclarations which descripted
+ in spd file.
+ **/
+ public void genPpiInfoList(PpiDeclarations ppiInfo) {
+ String[] cNameGuid = new String[2];
+
+ if (ppiInfo != null) {
+ List<PpiDeclarations.Entry> ppiEntryList = ppiInfo.getEntryList();
+ for (int i = 0; i < ppiEntryList.size(); i++) {
+ try {
+ cNameGuid[0] = ppiEntryList.get(i).getCName();
+ cNameGuid[1] = formatGuidName(ppiEntryList.get(i)
+ .getGuid().getStringValue());
+ this.ppiInfo.put(ppiEntryList.get(i).getName(), new String[] {
+ cNameGuid[0], cNameGuid[1] });
+ } catch (Exception e) {
+ System.out
+ .print("can't find GuidDeclarations C_Name & Guid!\n");
+ }
+ }
+ }
+ }
+
+ /**
+ genProtocolInfoList
+
+ This function is to generate Protocol info map.
+
+ @param proInfo The information of ProtocolDeclarations which
+ descripted in spd file.
+ **/
+ public void genProtocolInfoList(ProtocolDeclarations proInfo) {
+ String[] cNameGuid = new String[2];
+ if (proInfo != null) {
+ List<ProtocolDeclarations.Entry> protocolEntryList = proInfo.getEntryList();
+ for (int i = 0; i < protocolEntryList.size(); i++) {
+ try {
+ cNameGuid[0] = protocolEntryList.get(i).getCName();
+ cNameGuid[1] = formatGuidName(protocolEntryList.get(i)
+ .getGuid().getStringValue());
+
+ String temp = new String(protocolEntryList.get(i).getName());
+ this.protocolInfo.put(temp, new String[] { cNameGuid[0],
+ cNameGuid[1] });
+ } catch (Exception e) {
+ System.out
+ .print("can't find ProtocolDeclarations C_Name & Guid!\n");
+ }
+ }
+ }
+ }
+
+ /**
+ genGuidInfoList
+
+ This function is to generate GUID inf map.
+
+ @param guidInfo The information of GuidDeclarations which descripted
+ in spd file.
+
+ **/
+ public void genGuidInfoList(GuidDeclarations guidInfo) {
+ String[] cNameGuid = new String[2];
+ if (guidInfo != null) {
+
+ List<GuidDeclarations.Entry> guidEntryList = guidInfo.getEntryList();
+ for (int i = 0; i < guidEntryList.size(); i++) {
+ cNameGuid[0] = guidEntryList.get(i).getCName();
+ cNameGuid[1] = formatGuidName(guidEntryList.get(i)
+ .getGuid().getStringValue());
+ this.guidInfo.put(guidEntryList.get(i).getName(), new String[] {
+ cNameGuid[0], cNameGuid[1] });
+ }
+ }
+ }
+
+ /**
+ genLibClassDeclare
+
+ This function is to generate the libClassHeader list.
+
+ @param libClassDeclares The information of LibraryClassDeclarations which
+ descripted in spd file.
+ **/
+ public void genLibClassDeclare(LibraryClassDeclarations libClassDeclares) {
+ if (libClassDeclares != null && libClassDeclares.getLibraryClassDeclarationList() != null) {
+ if (libClassDeclares.getLibraryClassDeclarationList().size() > 0) {
+ List<LibraryClassDeclaration> libDeclareList = libClassDeclares.getLibraryClassDeclarationList();
+ for (int i = 0; i < libDeclareList.size(); i++) {
+ libClassHeaderList.put(libDeclareList.get(i).getLibraryClass()
+ .getStringValue(), libDeclareList.get(i)
+ .getIncludeHeader().getStringValue());
+ }
+ }
+ }
+ }
+
+ /**
+ getPpiGuid
+
+ This function is to get ppi GUID according ppi name.
+
+ @param ppiStr Name of ppi.
+ @return PPi's GUID.
+ **/
+ public String getPpiGuid(String ppiStr) {
+ if (ppiInfo.get(ppiStr) != null) {
+ return ppiInfo.get(ppiStr)[1];
+ } else {
+ return null;
+ }
+
+ }
+
+ /**
+ getPpiCnameGuidArray
+
+ This function is to get the ppi CName and it's GUID according to ppi name.
+
+ @param ppiName Name of ppi.
+ @return Ppi CName and it's GUID.
+ **/
+ public String[] getPpiCnameGuidArray(String ppiName) {
+ return this.ppiInfo.get(ppiName);
+ }
+
+ /**
+ getProtocolGuid
+
+ This function is to get the protocol GUID according to protocol's name.
+
+ @param protocolStr Name of protocol.
+ @return Protocol's GUID.
+ **/
+ public String getProtocolGuid(String protocolStr) {
+ if (protocolInfo.get(protocolStr) != null) {
+ return this.protocolInfo.get(protocolStr)[0];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ getProtocolNameGuidArray
+
+ This function is to get the protocol's CName ant it's GUID according to
+ protocol's namej.
+
+ @param protocolName Name of protocl.
+ @return Protocol's CName and it's GUID.
+ **/
+ public String[] getProtocolNameGuidArray(String protocolName) {
+ return this.protocolInfo.get(protocolName);
+ }
+
+ /**
+ getGUIDGuid
+
+ This function is to get the GUID according to GUID's name
+
+ @param guidStr Name of GUID
+ @return GUID.
+ **/
+ public String getGUIDGuid(String guidStr) {
+ if (guidInfo.get(guidStr) != null) {
+ return guidInfo.get(guidStr)[1];
+ } else {
+ return null;
+ }
+
+ }
+
+ /**
+ getGuidNameArray
+
+ This function is to get the GUID's CName and it's GUID according to
+ GUID's name
+
+ @param guidName Name of GUID
+ @return CName and GUID.
+ **/
+ public String[] getGuidNameArray(String guidName) {
+ return this.guidInfo.get(guidName);
+ }
+
+ /**
+ 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 getModuleTypeIncluder(String moduleType) {
+ return moduleInfo.get(moduleType);
+ }
+
+ /**
+ 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 don't conform to the schema!!!");
+ return "0";
+
+ }
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java b/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java
new file mode 100644
index 0000000000..96003c2e71
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java
@@ -0,0 +1,218 @@
+/** @file
+ SurfaceAreaParser class.
+
+ SurfaceAreaParser class is used to parse module surface area include both
+ driver and library.
+
+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.HashMap;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.xmlbeans.XmlObject;
+import org.tianocore.LibraryModuleBuildDescriptionDocument;
+import org.tianocore.LibraryModuleSurfaceAreaDocument;
+import org.tianocore.ModuleBuildDescriptionDocument;
+import org.tianocore.ModuleSurfaceAreaDocument;
+
+/**
+ This class is used to parse module surface area (MSA & MBD) include both
+ driver and library.
+
+ @since GenBuild 1.0
+**/
+public class SurfaceAreaParser {
+
+ /**
+ Using XmlBeans to parse and valid surface area file.
+
+ @param surfaceAreaFile the surface area file to parse
+ @return top level elements and its value mapping information
+ @throws BuildException
+ If surface area is not well-formed or invalid
+ **/
+ public Map<String, XmlObject> parseFile(File surfaceAreaFile) throws BuildException {
+ Map<String, XmlObject> map = new HashMap<String, XmlObject>();
+ try {
+ XmlObject sadoc = XmlObject.Factory.parse(surfaceAreaFile);
+ // Validate File if they obey XML Schema
+
+ if ( ! sadoc.validate()){
+ throw new BuildException("Surface Area file [" + surfaceAreaFile.getPath() + "] is invalid.");
+ }
+ if (sadoc instanceof ModuleSurfaceAreaDocument){
+ parseFile((ModuleSurfaceAreaDocument) sadoc, map);
+ }
+ else if(sadoc instanceof ModuleBuildDescriptionDocument){
+ parseFile((ModuleBuildDescriptionDocument) sadoc, map);
+ }
+ else if(sadoc instanceof LibraryModuleSurfaceAreaDocument){
+ parseFile((LibraryModuleSurfaceAreaDocument) sadoc, map);
+ }
+ else if(sadoc instanceof LibraryModuleBuildDescriptionDocument){
+ parseFile((LibraryModuleBuildDescriptionDocument) sadoc, map);
+ }
+ }
+ catch (Exception ex){
+ throw new BuildException(ex.getMessage());
+ }
+ return map;
+ }
+
+
+ /**
+ Parse MSA.
+
+ @param doc top level surface area XML document
+ @param msaMap the map to store the result
+ **/
+ private void parseFile(ModuleSurfaceAreaDocument doc, Map<String, XmlObject> msaMap) {
+ msaMap.put("MsaHeader", doc.getModuleSurfaceArea().getMsaHeader());
+ msaMap.put("LibraryClassDefinitions", doc.getModuleSurfaceArea()
+ .getLibraryClassDefinitions());
+ msaMap.put("SourceFiles", doc.getModuleSurfaceArea().getSourceFiles());
+ msaMap.put("Includes", doc.getModuleSurfaceArea().getIncludes());
+ msaMap.put("Protocols", doc.getModuleSurfaceArea().getProtocols());
+
+ msaMap.put("Events", doc.getModuleSurfaceArea().getEvents());
+ msaMap.put("Hobs", doc.getModuleSurfaceArea().getHobs());
+ msaMap.put("PPIs", doc.getModuleSurfaceArea().getPPIs());
+ msaMap.put("Variables", doc.getModuleSurfaceArea().getVariables());
+ msaMap.put("BootModes", doc.getModuleSurfaceArea().getBootModes());
+
+ msaMap
+ .put("SystemTables", doc.getModuleSurfaceArea()
+ .getSystemTables());
+ msaMap.put("DataHubs", doc.getModuleSurfaceArea().getDataHubs());
+ msaMap.put("Formsets", doc.getModuleSurfaceArea().getFormsets());
+ msaMap.put("Guids", doc.getModuleSurfaceArea().getGuids());
+ msaMap.put("Externs", doc.getModuleSurfaceArea().getExterns());
+
+ msaMap.put("PCDs", doc.getModuleSurfaceArea().getPCDs());
+ msaMap
+ .put("BuildOptions", doc.getModuleSurfaceArea()
+ .getBuildOptions());
+ }
+
+ /**
+ Parse MBD.
+
+ @param doc top level surface area XML document
+ @param msaMap the map to store the result
+ **/
+ private void parseFile(ModuleBuildDescriptionDocument doc, Map<String, XmlObject> mbdMap) {
+ mbdMap.put("MbdHeader", doc.getModuleBuildDescription().getMbdHeader());
+ mbdMap.put("Libraries", doc.getModuleBuildDescription().getLibraries());
+ mbdMap.put("SourceFiles", doc.getModuleBuildDescription()
+ .getSourceFiles());
+ mbdMap.put("Includes", doc.getModuleBuildDescription().getIncludes());
+ mbdMap.put("Protocols", doc.getModuleBuildDescription().getProtocols());
+
+ mbdMap.put("Events", doc.getModuleBuildDescription().getEvents());
+ mbdMap.put("Hobs", doc.getModuleBuildDescription().getHobs());
+ mbdMap.put("PPIs", doc.getModuleBuildDescription().getPPIs());
+ mbdMap.put("Variables", doc.getModuleBuildDescription().getVariables());
+ mbdMap.put("BootModes", doc.getModuleBuildDescription().getBootModes());
+
+ mbdMap.put("SystemTables", doc.getModuleBuildDescription()
+ .getSystemTables());
+ mbdMap.put("DataHubs", doc.getModuleBuildDescription().getDataHubs());
+ mbdMap.put("Formsets", doc.getModuleBuildDescription().getFormsets());
+ mbdMap.put("Guids", doc.getModuleBuildDescription().getGuids());
+ mbdMap.put("Externs", doc.getModuleBuildDescription().getExterns());
+
+ mbdMap.put("PCDs", doc.getModuleBuildDescription().getPCDs());
+ mbdMap.put("BuildOptions", doc.getModuleBuildDescription()
+ .getBuildOptions());
+ }
+ /**
+ Parse Library MSA.
+
+ @param doc top level surface area XML document
+ @param msaMap the map to store the result
+ **/
+ private void parseFile(LibraryModuleSurfaceAreaDocument doc, Map<String, XmlObject> msaMap) {
+ msaMap.put("MsaLibHeader", doc.getLibraryModuleSurfaceArea()
+ .getMsaLibHeader());
+ msaMap.put("LibraryClassDefinitions", doc.getLibraryModuleSurfaceArea()
+ .getLibraryClassDefinitions());
+ msaMap.put("SourceFiles", doc.getLibraryModuleSurfaceArea()
+ .getSourceFiles());
+ msaMap.put("Includes", doc.getLibraryModuleSurfaceArea().getIncludes());
+ msaMap.put("Protocols", doc.getLibraryModuleSurfaceArea()
+ .getProtocols());
+
+ msaMap.put("Events", doc.getLibraryModuleSurfaceArea().getEvents());
+ msaMap.put("Hobs", doc.getLibraryModuleSurfaceArea().getHobs());
+ msaMap.put("PPIs", doc.getLibraryModuleSurfaceArea().getPPIs());
+ msaMap.put("Variables", doc.getLibraryModuleSurfaceArea()
+ .getVariables());
+ msaMap.put("BootModes", doc.getLibraryModuleSurfaceArea()
+ .getBootModes());
+
+ msaMap.put("SystemTables", doc.getLibraryModuleSurfaceArea()
+ .getSystemTables());
+ msaMap.put("DataHubs", doc.getLibraryModuleSurfaceArea().getDataHubs());
+ msaMap.put("Formsets", doc.getLibraryModuleSurfaceArea().getFormsets());
+ msaMap.put("Guids", doc.getLibraryModuleSurfaceArea().getGuids());
+ msaMap.put("Externs", doc.getLibraryModuleSurfaceArea().getExterns());
+
+ msaMap.put("PCDs", doc.getLibraryModuleSurfaceArea().getPCDs());
+ msaMap.put("BuildOptions", doc.getLibraryModuleSurfaceArea()
+ .getBuildOptions());
+ }
+
+ /**
+ Parse Library MBD.
+
+ @param doc top level surface area XML document
+ @param msaMap the map to store the result
+ **/
+ private void parseFile(LibraryModuleBuildDescriptionDocument doc, Map<String, XmlObject> mbdMap) {
+ mbdMap.put("MbdLibHeader", doc.getLibraryModuleBuildDescription()
+ .getMbdLibHeader());
+ mbdMap.put("Libraries", doc.getLibraryModuleBuildDescription()
+ .getLibraries());
+ mbdMap.put("SourceFiles", doc.getLibraryModuleBuildDescription()
+ .getSourceFiles());
+ mbdMap.put("Includes", doc.getLibraryModuleBuildDescription()
+ .getIncludes());
+ mbdMap.put("Protocols", doc.getLibraryModuleBuildDescription()
+ .getProtocols());
+
+ mbdMap
+ .put("Events", doc.getLibraryModuleBuildDescription()
+ .getEvents());
+ mbdMap.put("Hobs", doc.getLibraryModuleBuildDescription().getHobs());
+ mbdMap.put("PPIs", doc.getLibraryModuleBuildDescription().getPPIs());
+ mbdMap.put("Variables", doc.getLibraryModuleBuildDescription()
+ .getVariables());
+ mbdMap.put("BootModes", doc.getLibraryModuleBuildDescription()
+ .getBootModes());
+
+ mbdMap.put("SystemTables", doc.getLibraryModuleBuildDescription()
+ .getSystemTables());
+ mbdMap.put("DataHubs", doc.getLibraryModuleBuildDescription()
+ .getDataHubs());
+ mbdMap.put("Formsets", doc.getLibraryModuleBuildDescription()
+ .getFormsets());
+ mbdMap.put("Guids", doc.getLibraryModuleBuildDescription().getGuids());
+ mbdMap.put("Externs", doc.getLibraryModuleBuildDescription()
+ .getExterns());
+
+ mbdMap.put("PCDs", doc.getLibraryModuleBuildDescription().getPCDs());
+ mbdMap.put("BuildOptions", doc.getLibraryModuleBuildDescription()
+ .getBuildOptions());
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java b/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java
new file mode 100644
index 0000000000..03c8d4328d
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java
@@ -0,0 +1,1109 @@
+/** @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.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.xmlbeans.XmlNormalizedString;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlString;
+import org.tianocore.BuildOptionsDocument;
+import org.tianocore.CName;
+import org.tianocore.ExternsDocument;
+import org.tianocore.FfsDocument;
+import org.tianocore.FileNameConvention;
+import org.tianocore.FrameworkComponentTypes;
+import org.tianocore.FvImageOptionsDocument;
+import org.tianocore.GuidDocument;
+import org.tianocore.GuidsDocument;
+import org.tianocore.LibrariesDocument;
+import org.tianocore.LibraryClassDocument;
+import org.tianocore.LibraryUsage;
+import org.tianocore.ModuleSADocument;
+import org.tianocore.ModuleTypeDef;
+import org.tianocore.NameValueDocument;
+import org.tianocore.OutputDirectoryDocument;
+import org.tianocore.PPIsDocument;
+import org.tianocore.PackageNameDocument;
+import org.tianocore.ProtocolsDocument;
+import org.tianocore.PCDsDocument.PCDs;
+
+/**
+ 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 {
+ ///
+ /// Contains name/value pairs of Surface Area document object. The name is
+ /// always the top level element name.
+ ///
+ private static Map<String, XmlObject> map = null;
+
+ ///
+ /// mapStack is used to do nested query
+ ///
+ private static Stack< Map<String, XmlObject> > mapStack = new Stack< Map<String, XmlObject> >();
+
+ ///
+ /// prefix of name space
+ ///
+ private static String nsPrefix = "sans";
+
+ ///
+ /// xmlbeans needs a name space for each Xpath element
+ ///
+ private static String ns = null;
+
+ ///
+ /// keep the namep declaration for xmlbeans Xpath query
+ ///
+ private static String queryDeclaration = null;
+
+ /**
+ Set a Surface Area document for query later
+
+ @param map A Surface Area document in TopLevelElementName/XmlObject format.
+ **/
+ public static void setDoc(Map<String, XmlObject> map) {
+ ns = OverrideProcess.prefix;
+ queryDeclaration = "declare namespace " + nsPrefix + "='" + ns + "'; ";
+ SurfaceAreaQuery.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 static void push(Map<String, XmlObject> newMap) {
+ mapStack.push(SurfaceAreaQuery.map);
+ SurfaceAreaQuery.map = newMap;
+ }
+
+ /**
+ Discard current used Surface Area document and use the top document in stack
+ instead.
+ **/
+ public static void pop() {
+ SurfaceAreaQuery.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 static String normalizeQueryString(String[] exp, String from) {
+ StringBuffer normQueryString = new StringBuffer(4096);
+
+ int i = 0;
+ while (i < exp.length) {
+ String newExp = from + exp[i];
+ Pattern pattern = Pattern.compile("([^/]*)(/|//)([^/]+)");
+ Matcher matcher = pattern.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 static XmlObject[] get(String[] xPath) {
+ if (map == null) {
+ return null;
+ }
+
+ String[] keys = (String[]) map.keySet().toArray(new String[map.size()]);
+ List<XmlObject> result = new ArrayList<XmlObject>();
+ 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(tmp[j]);
+ }
+ }
+
+ int size = result.size();
+ if (size <= 0) {
+ return null;
+ }
+
+ return (XmlObject[]) result.toArray(new XmlObject[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 static XmlObject[] 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 result;
+ }
+
+ query = queryDeclaration + normalizeQueryString(xPath, "/" + rootName);
+ result = root.selectPath(query);
+ if (result.length > 0) {
+ return result;
+ }
+
+ return null;
+ }
+
+ /**
+ Retrieve SourceFiles/Filename for specified ARCH type
+
+ @param arch architecture name
+ @returns An array of XmlObject if elements are found at the known xpath
+ @returns NULL if nothing is found at the known xpath
+ **/
+ public static XmlObject[] getSourceFiles(String arch) {
+ String[] xPath;
+
+ if (arch == null || arch.equals("")) {
+ xPath = new String[] {
+ "/Filename",
+ "/Arch/Filename"
+ };
+ } else {
+ xPath = new String[] {
+ "/Filename[not(@ArchType) or @ArchType='ALL' or @ArchType='" + arch + "']",
+ "/Arch[@ArchType='ALL' or @ArchType='" + arch + "']/Filename"
+ };
+ }
+
+ return get("SourceFiles", xPath);
+ }
+
+ /**
+ Retrieve BuildOptions/Ffs
+
+ @returns FfsDocument.Ffs object if elements are found at the known xpath
+ @returns NULL if nothing is found at the known xpath
+ **/
+ public static FfsDocument.Ffs getFfs() {
+ String[] xPath = new String[] { "/Ffs" };
+
+ XmlObject[] returns = get("BuildOptions", xPath);
+ if (returns != null && returns.length > 0) {
+ return (FfsDocument.Ffs) returns[0];
+ }
+
+ return null;
+ }
+
+ /**
+ Retrieve BuildOptions/OutputDirectory
+
+ @returns Directory names array if elements are found at the known xpath
+ @returns Empty if nothing is found at the known xpath
+ **/
+ public static String[] getOutputDirectory() {
+ String[] xPath = new String[] { "/OutputDirectory" };
+
+ XmlObject[] returns = get("BuildOptions", xPath);
+ if (returns != null && returns.length > 0) {
+ String[] dirString = new String[2];
+
+ OutputDirectoryDocument.OutputDirectory[] dir = (OutputDirectoryDocument.OutputDirectory[]) returns;
+ dirString[0] = dir[0].getIntermediateDirectories().toString();
+ dirString[1] = dir[0].getStringValue();
+
+ return dirString;
+ }
+
+ return new String[] { "UNIFIED", null };
+ }
+
+ /**
+ Retrieve BuildOptions/Option or Arch/Option
+
+ @param arch architecture name
+
+ @returns name/value pairs of options if elements are found at the known xpath
+ @returns Empty array if nothing is there
+ **/
+ public static String[][] getOptions(String arch){
+ String[] xPath;
+
+ if (arch == null || arch.equals("")) {
+ xPath = new String[] {
+ "/Option",
+ "/Arch/Option"
+ };
+ } else {
+ xPath = new String[] {
+ "/Option",
+ "/Arch[@ArchType='ALL' or @ArchType='" + arch + "']/Option"
+ };
+ }
+
+ XmlObject[] returns = get("BuildOptions", xPath);
+ if (returns == null){
+ return new String[0][2];
+ }
+
+ String[][] result = new String[returns.length][2];
+ for (int i = 0; i < returns.length; i ++){
+ String str;
+ String name = null;
+ String value = null;
+
+ if (returns[i] instanceof BuildOptionsDocument.BuildOptions.Option) {
+ BuildOptionsDocument.BuildOptions.Option option = (BuildOptionsDocument.BuildOptions.Option)returns[i];
+ str = option.getStringValue();
+ } else if (returns[i] instanceof BuildOptionsDocument.BuildOptions.Arch.Option) {
+ BuildOptionsDocument.BuildOptions.Arch.Option archOption = (BuildOptionsDocument.BuildOptions.Arch.Option)returns[i];
+ str = archOption.getStringValue();
+ } else {
+ continue;
+ }
+
+ int equalIndex = str.indexOf('=');
+ if ( equalIndex > 0) {
+ name = str.substring(0, equalIndex).trim();
+ value = str.substring(equalIndex + 1).trim();
+ // TBD remove some forbidden name: BASE_NAME, ARCH and so on
+ if (name.length() == 0){
+ name = null;
+ }
+ }
+ result[i][0] = name;
+ result[i][1] = value;
+ }
+
+ return result;
+ }
+
+ /**
+ Retrieve <xxxHeader>/ModuleType
+
+ @returns The module type name if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static String getModuleType() {
+ String[] xPath = new String[] { "/ModuleType" };
+
+ XmlObject[] returns = get(xPath);
+ if (returns != null && returns.length > 0) {
+ ModuleTypeDef type = (ModuleTypeDef) returns[0];
+ return type.enumValue().toString();
+ }
+
+ return null;
+ }
+
+ /**
+ Retrieve <xxxHeader>/ComponentType
+
+ @returns The component type name if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static String getComponentType() {
+ String[] xPath = new String[] { "/ComponentType" };
+
+ XmlObject[] returns = get(xPath);
+ if (returns != null && returns.length > 0) {
+ FrameworkComponentTypes type = (FrameworkComponentTypes) returns[0];
+ return type.enumValue().toString();
+ }
+
+ return null;
+ }
+
+ /**
+ Retrieve Includes/PackageName
+
+ @param arch Architecture name
+
+ @returns package name list if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static List<String> getIncludePackageName(String arch) {
+ String[] xPath;
+
+ if (arch == null || arch.equals("")) {
+ xPath = new String[] {
+ "/PackageName",
+ "/Arch/PackageName"
+ };
+ } else {
+ xPath = new String[] {
+ "/PackageName",
+ "/Arch[@ArchType='ALL' or @ArchType='" + arch + "']/PackageName"
+ };
+ }
+
+ XmlObject[] returns = get("Includes", xPath);
+ if (returns == null || returns.length == 0) {
+ return null;
+ }
+
+ List<String> packageNames = new ArrayList<String>();
+ PackageNameDocument.PackageName[] nameObj = (PackageNameDocument.PackageName[])returns;
+ for (int i = 0; i < returns.length; ++i) {
+ packageNames.add(nameObj[i].getStringValue());
+ }
+
+ return packageNames;
+ }
+
+ /**
+ 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 static LibraryClassDocument.LibraryClass[] getLibraryClassArray(String usage) {
+ String[] xPath;
+
+ if (usage == null || usage.equals("")) {
+ xPath = new String[] {"/LibraryClass"};
+ } else {
+ xPath = new String[] {"/LibraryClass[@Usage='" + usage + "']"};
+ }
+
+ XmlObject[] returns = get("LibraryClassDefinitions", xPath);
+ if (returns != null && returns.length > 0) {
+ return (LibraryClassDocument.LibraryClass[]) returns;
+ }
+
+ return null;
+ }
+
+ /**
+ Retrieve ModuleEntryPoint names
+
+ @returns ModuleEntryPoint name list if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static String[] getModuleEntryPointArray() {
+ String[] xPath = new String[] { "/Extern/ModuleEntryPoint" };
+
+ XmlObject[] 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] = ((XmlNormalizedString) returns[i])
+ .getStringValue();
+ }
+
+ return entryPoints;
+ }
+
+ return null;
+ }
+
+ /**
+ Retrieve module Guid string
+
+ @returns GUILD string if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static String getModuleGuid() {
+ String[] xPath = new String[] { "/Guid" };
+
+ XmlObject[] returns = get(xPath);
+ if (returns != null && returns.length > 0) {
+ GuidDocument.Guid guid = (GuidDocument.Guid) returns[0];
+ return guid.getStringValue();
+ }
+
+ return null;
+ }
+
+ /**
+ retrieve Protocol for specified usage
+
+ @param usage Protocol usage
+
+ @returns Protocol objects list if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static ProtocolsDocument.Protocols.Protocol[] getProtocolArray(String usage) {
+ String[] xPath;
+
+ if (usage == null || usage.equals("")) {
+ xPath = new String[] {"/Protocol"};
+ } else {
+ xPath = new String[] {"/Protocol[@Usage='" + usage + "']"};
+ }
+
+ XmlObject[] returns = get("Protocols", xPath);
+ if (returns != null && returns.length > 0) {
+ return (ProtocolsDocument.Protocols.Protocol[]) returns;
+ }
+
+ return null;
+ }
+
+ /**
+ Retrieve ProtocolNotify for specified usage
+
+ @param usage ProtocolNotify usage
+
+ @returns ProtocolNotify objects list if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static ProtocolsDocument.Protocols.ProtocolNotify[] getProtocolNotifyArray(String usage) {
+ String[] xPath;
+
+ if (usage == null || usage.equals("")) {
+ xPath = new String[] {"/ProtocolNotify"};
+ } else {
+ xPath = new String[] {"/ProtocolNotify[@Usage='" + usage + "']"};
+ }
+
+ XmlObject[] returns = get("Protocols", xPath);
+ if (returns != null && returns.length > 0) {
+ return (ProtocolsDocument.Protocols.ProtocolNotify[]) returns;
+ }
+
+ return null;
+ }
+
+ /**
+ Retrieve ModuleUnloadImage names
+
+ @returns ModuleUnloadImage name list if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static String[] getModuleUnloadImageArray() {
+ String[] xPath = new String[] { "/Extern/ModuleUnloadImage" };
+
+ XmlObject[] returns = get("Externs", xPath);
+ if (returns != null && returns.length > 0) {
+ String[] stringArray = new String[returns.length];
+ XmlNormalizedString[] doc = (XmlNormalizedString[])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 static ExternsDocument.Externs.Extern[] getExternArray() {
+ String[] xPath = new String[] { "/Extern" };
+
+ XmlObject[] returns = get("Externs", xPath);
+ if (returns != null && returns.length > 0) {
+ return (ExternsDocument.Externs.Extern[]) returns;
+ }
+
+ return null;
+ }
+
+ /**
+ Retrieve Ppi information
+
+ @param usage Ppi usage
+
+ @returns Ppi objects list if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static PPIsDocument.PPIs.Ppi[] getPpiArray(String usage) {
+ String[] xPath;
+
+ if (usage == null || usage.equals("")) {
+ xPath = new String[] { "/Ppi" };
+ } else {
+ xPath = new String[] { "/Ppi[@Usage='" + usage + "']" };
+ }
+
+ XmlObject[] returns = get("PPIs", xPath);
+ if (returns != null && returns.length > 0) {
+ return (PPIsDocument.PPIs.Ppi[])returns;
+ }
+
+ return null;
+ }
+
+ /**
+ Retrive PpiNotify information
+
+ @param usage
+
+ @returns PpiNotify objects list if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static PPIsDocument.PPIs.PpiNotify[] getPpiNotifyArray(String usage) {
+ String[] xPath;
+
+ if (usage == null || usage.equals("")) {
+ xPath = new String[] { "/PpiNotify" };
+ } else {
+ xPath = new String[] { "/PpiNotify[@Usage='" + usage + "']" };
+ }
+
+ XmlObject[] returns = get("PPIs", xPath);
+ if (returns != null && returns.length > 0) {
+ return (PPIsDocument.PPIs.PpiNotify[])returns;
+ }
+
+ return null;
+ }
+
+ /**
+ Retrieve GuidEntry information for specified usage
+
+ @param usage GuidEntry usage
+
+ @returns GuidEntry objects list if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static GuidsDocument.Guids.GuidEntry[] getGuidEntryArray(String usage) {
+ String[] xPath;
+
+ if (usage == null || usage.equals("")) {
+ xPath = new String[] { "/GuidEntry" };
+ } else {
+ xPath = new String[] { "/GuidEntry[@Usage='" + usage + "']" };
+ }
+
+ XmlObject[] returns = get("Guids", xPath);
+ if (returns != null && returns.length > 0) {
+ return (GuidsDocument.Guids.GuidEntry[])returns;
+ }
+
+ return null;
+ }
+
+ /**
+ 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 static List<String> getLibraryInstance(String arch, String usage) {
+ String[] xPath;
+ String archAttribute = "";
+ String usageAttribute = "";
+
+ if ((arch != null) || (!arch.equals(""))) {
+ archAttribute = "[@ArchType='ALL' or @ArchType='" + arch + "']";
+ }
+
+ if ((usage != null) || (!usage.equals(""))) {
+ // if no Usage attribute specified, default to ALWAYS_CONSUMED
+ if (usage.equals(LibraryUsage.ALWAYS_CONSUMED.toString())) {
+ usageAttribute = "[not(@Usage) or @Usage='" + usage + "']";
+ } else {
+ usageAttribute = "[@Usage='" + usage + "']";
+ }
+ }
+
+ xPath = new String[] {
+ "/Library" + usageAttribute,
+ "/Arch" + archAttribute + "/Library" + usageAttribute
+ };
+
+ XmlObject[] returns = get("Libraries", xPath);
+ if (returns == null || returns.length == 0) {
+ return null;
+ }
+
+ List<String> instances = new ArrayList<String>();
+ for (int i = 0; i < returns.length; ++i) {
+ if (returns[i] instanceof LibrariesDocument.Libraries.Library) {
+ LibrariesDocument.Libraries.Library lib = (LibrariesDocument.Libraries.Library)returns[i];
+ instances.add(lib.getStringValue());
+ } else if (returns[i] instanceof LibrariesDocument.Libraries.Arch.Library) {
+ LibrariesDocument.Libraries.Arch.Library lib = (LibrariesDocument.Libraries.Arch.Library)returns[i];
+ instances.add(lib.getStringValue());
+ }
+ }
+
+ return instances;
+ }
+
+ ///
+ /// This method is used for retrieving the elements information which has
+ /// CName sub-element
+ ///
+ private static String[] getCNames(String from, String xPath[]) {
+ XmlObject[] 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) {
+ strings[i] = ((CName)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 static String getLibConstructorName() {
+ String[] xPath = new String[] {"/Extern/Constructor"};
+
+ XmlObject[] returns = get("Externs", xPath);
+ if (returns != null && returns.length > 0) {
+ CName constructor = (CName)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 static String getLibDestructorName() {
+ String[] xPath = new String[] {"/Extern/Destructor"};
+
+ XmlObject[] returns = get("Externs", xPath);
+ if (returns != null && returns.length > 0) {
+ CName destructor = (CName)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 static 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 static 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 static 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 static String[] getDriverDiagArray() {
+ String[] xPath = new String[] {"/Extern/DriverDiag"};
+ return getCNames("Externs", xPath);
+ }
+
+ /**
+ Retrive SetVirtualAddressMapCallBack names
+
+ @returns SetVirtualAddressMapCallBack name list
+ if elements are found at the known xpath
+ @returns null if nothing is there
+ **/
+ public static 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 static String[] getExitBootServicesCallBackArray() {
+ String[] xPath = new String[] {"/Extern/ExitBootServicesCallBack"};
+ return getCNames("Externs", xPath);
+ }
+
+ /**
+ 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 static ModuleSADocument.ModuleSA[] getFpdModules() {
+ String[] xPath = new String[] { "/TianoImage/*/ModuleSA" };
+
+ XmlObject[] result = get("FrameworkPlatformDescription", xPath);
+ if (result == null) {
+ return new ModuleSADocument.ModuleSA[0];
+ }
+
+ return (ModuleSADocument.ModuleSA[]) result;
+ }
+
+ /**
+ Retrieve variables for FV images
+
+ @returns name/value list if elements are found at the known xpath
+ @returns empty list if nothing is there
+ **/
+ public static String[][] getFpdGlobalVariable() {
+ String[] xPath = new String[] { "/Flash/FvImages/NameValue" };
+
+ XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
+ if (queryResult == null) {
+ return new String[0][];
+ }
+
+ String[][] result = new String[queryResult.length][2];
+ for (int i = 0; i < queryResult.length; i++){
+ result[i][0] = ((NameValueDocument.NameValue)queryResult[i]).getName();
+ result[i][1] = ((NameValueDocument.NameValue)queryResult[i]).getValue();
+ }
+
+ return result;
+ }
+
+ /**
+ 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 static String[] getFpdValidImageNames(){
+ String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='ValidImageNames']/FvImageNames" };
+
+ XmlObject[] queryResult = get("FrameworkPlatformDescription", 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;
+ }
+
+ /**
+ 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 static String[][] getFpdOptions(String fvName){
+ String[] xPath = new String[] {"/Flash/FvImages/FvImageName[@Name='" + fvName.toUpperCase() + "']/FvImageOptions/NameValue" };
+
+ XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
+ if (queryResult == null) {
+ return new String[0][];
+ }
+
+ String[][] result = new String[queryResult.length][2];
+ for (int i = 0; i < queryResult.length; i++){
+ result[i][0] = ((NameValueDocument.NameValue)queryResult[i]).getName();
+ result[i][1] = ((NameValueDocument.NameValue)queryResult[i]).getValue();
+ }
+
+ return result;
+ }
+
+ /**
+ 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 static String[][] getFpdAttributes(String fvName){
+ String[] xPath = new String[] {"/Flash/FvImages/FvImage[@Type='Attributes' and ./FvImageNames='" + fvName.toUpperCase() + "']/FvImageOptions" };
+
+ XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
+ if (queryResult == null) {
+ return new String[0][];
+ }
+
+ ArrayList<String[]> list = new ArrayList<String[]>();
+ for (int i = 0 ; i < queryResult.length; i++){
+ FvImageOptionsDocument.FvImageOptions item = (FvImageOptionsDocument.FvImageOptions)queryResult[i];
+
+ List<NameValueDocument.NameValue> namevalues = item.getNameValueList();
+ Iterator iter = namevalues.iterator();
+ while (iter.hasNext()) {
+ NameValueDocument.NameValue nvItem = (NameValueDocument.NameValue)iter.next();
+ list.add(new String[]{nvItem.getName(), nvItem.getValue()});
+ }
+
+ List<String> enables = item.getEnableList();
+ iter = enables.iterator();
+ while (iter.hasNext()) {
+ String enableItem = (String)iter.next();
+ list.add(new String[]{enableItem, "TRUE"});
+ }
+
+ List<String> disables = item.getDisableList();
+ iter = disables.iterator();
+ while (iter.hasNext()) {
+ String disableItem = (String)iter.next();
+ list.add(new String[]{disableItem, "FALSE"});
+ }
+ }
+
+ 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 static String getFlashDefinitionFile(){
+ String[] xPath = new String[] {"/Flash/FlashDefinitionFile" };
+
+ XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
+ if (queryResult == null || queryResult.length == 0) {
+ return null;
+ }
+
+ FileNameConvention filename = (FileNameConvention)queryResult[queryResult.length - 1];
+ return filename.getStringValue();
+ }
+
+ /**
+ 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 static String[][] getFpdComponents(String fvName){
+ String[] xPath = new String[] {"/Flash/FvImages/FvImage[@Type='Components' and ./FvImageNames='" + fvName.toUpperCase() + "']/FvImageOptions" };
+
+ XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
+ if (queryResult == null) {
+ return new String[0][];
+ }
+
+ ArrayList<String[]> list = new ArrayList<String[]>();
+ for (int i = 0 ; i < queryResult.length; i++){
+ FvImageOptionsDocument.FvImageOptions item = (FvImageOptionsDocument.FvImageOptions)queryResult[i];
+
+ List<NameValueDocument.NameValue> namevalues = item.getNameValueList();
+ Iterator iter = namevalues.iterator();
+ while (iter.hasNext()) {
+ NameValueDocument.NameValue nvItem = (NameValueDocument.NameValue)iter.next();
+ list.add(new String[]{nvItem.getName(), nvItem.getValue()});
+ }
+
+ List<String> enables = item.getEnableList();
+ iter = enables.iterator();
+ while (iter.hasNext()) {
+ String enableItem = (String)iter.next();
+ list.add(new String[]{enableItem, "TRUE"});
+ }
+
+ List<String> disables = item.getDisableList();
+ iter = disables.iterator();
+ while (iter.hasNext()) {
+ String disableItem = (String)iter.next();
+ list.add(new String[]{disableItem, "FALSE"});
+ }
+ }
+
+ 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 static String[][] getPcdTokenArray() {
+ String[] xPath = new String[] {"/PcdData"};
+
+ XmlObject[] returns = get("PCDs", xPath);
+ if (returns == null || returns.length == 0) {
+ return null;
+ }
+
+ PCDs.PcdData[] pcds = (PCDs.PcdData[]) returns;
+ String[][] result = new String[pcds.length][2];
+ for (int i = 0; i < returns.length; ++i) {
+ if (pcds[i].getItemType() != null) {
+ result[i][1] = pcds[i].getItemType().toString();
+ } else {
+ result[i][1] = null;
+ }
+ result[i][0] = pcds[i].getCName();
+ }
+
+ return result;
+ }
+
+ /**
+ Get the PcdToken array from module's surface area document.
+ The array should contains following data:
+ <p>-------------------------------------------------------------------</p>
+ <p>CName | ItemType | TokenspaceName | DefaultValue | Usage | HelpText</p>
+ <p>-------------------------------------------------------------------</p>
+ <p>Note: Until new schema applying, now we can only get CName, ItemType,</p>
+
+ @return 2-array table contains all information of PCD token retrieved from MSA.
+ **/
+ public static Object[][] getModulePCDTokenArray () {
+ int index;
+ Object[][] result;
+ PCDs.PcdData[] pcds;
+ String[] xPath = new String[] {"/PcdData"};
+ XmlObject[] returns = get ("PCDs", xPath);
+
+ if ((returns == null) || (returns.length == 0)) {
+ return null;
+ }
+
+ pcds = (PCDs.PcdData[]) returns;
+ result = new Object[pcds.length][6];
+ for (index = 0; index < pcds.length; index ++) {
+ //
+ // Get CName
+ //
+ result [index][0] = pcds[index].getCName();
+ //
+ // Get ItemType: FEATURE_FLAG, FIXED_AT_BUILD, PATCHABLE_IN_MODLE, DYNAMIC, DYNAMIC_EX
+ //
+ if (pcds[index].getItemType() != null) {
+ result [index][1] = pcds[index].getItemType().toString();
+ } else {
+ result [index][1] = null;
+ }
+
+ //
+ // BUGBUG: following field can *not* be got from current MSA until schema changed.
+ //
+ //result [index][2] = pcds[index].getTokenSpaceName();
+ result [index][2] = null;
+ result [index][3] = pcds[index].getDefaultValue();
+ //result [index][4] = pcds[index].getUsage ();
+ result [index][4] = null;
+ //result [index][5] = pcds[index].getHelpText ();
+ result [index][5] = null;
+ }
+ return result;
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/VariableTask.java b/Tools/Source/GenBuild/org/tianocore/build/global/VariableTask.java
new file mode 100644
index 0000000000..f830e0ac76
--- /dev/null
+++ b/Tools/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 must not null.");
+ }
+ getProject().setProperty(name, value);
+ }
+}
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ActionMessage.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ActionMessage.java
new file mode 100644
index 0000000000..a67d2f9e4d
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ActionMessage.java
@@ -0,0 +1,129 @@
+/** @file
+ ActionMessage class.
+
+ ActionMessage class take over all message for loging and waning. This class should
+ dispatch message into different class according to instance class type.
+
+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 org.apache.tools.ant.Task;
+import org.tianocore.build.pcd.action.BuildAction;
+import org.tianocore.build.pcd.action.UIAction;
+
+/** ActionMessage class take over all message for loging and waning. This class
+ should dispatch message into different Action class according to instance
+ class type.
+**/
+public class ActionMessage {
+ ///
+ /// Macro definition for NULL messge level.
+ /// In this meessage level, all message will be hidden.
+ ///
+ public final static int NULL_MESSAGE_LEVEL = 0;
+ ///
+ /// Macro definition for Log messge level.
+ /// In this message level, Only log information will be shown.
+ ///
+ public final static int LOG_MESSAGE_LEVEL = 1;
+ ///
+ /// Macro definition for Warning message level.
+ /// In this message level, log and waning message will be shown.
+ ///
+ public final static int WARNING_MESSAGE_LEVEL = 2;
+ ///
+ /// Macro definition for Debug mesage level.
+ /// In this message level, log, warning, debug message will be shown.
+ ///
+ public final static int DEBUG_MESSAGE_LEVEL = 3;
+ ///
+ /// Macor definition for MAX message level.
+ /// In this message level, all message will be shown.
+ ///
+ public final static int MAX_MESSAGE_LEVEL = 4;
+ ///
+ /// Current message level. It will control all message output for PCD tool.
+ ///
+ public static int messageLevel = NULL_MESSAGE_LEVEL;
+
+ /**
+ Log() function provide common log information functionality for all
+ PCD tool includes all function
+
+ This function will dispatch message to special class such as BuildAction
+ Class, Entity Class etc.
+
+ @param thisClass The class object who want log information.
+ @param logStr The string contains log information.
+ **/
+ public static void log(Object thisClass, String logStr) {
+ if(messageLevel < LOG_MESSAGE_LEVEL) {
+ return;
+ }
+
+ if(thisClass instanceof Task) {
+ BuildAction.logMsg(thisClass, "$$LOG$$:" + logStr);
+ } else if(thisClass instanceof UIAction) {
+ UIAction.logMsg(thisClass, "$$LOG$$:" + logStr);
+ } else {
+ System.out.println("$$LOG$$:" + logStr);
+ }
+ }
+
+ /**
+ Warning() function provide common warning information functionality for all
+ PCD tool.
+
+ This function will dispatch message to special class such as BuildAction
+ Class, Entity Class etc.
+
+ @param thisClass The class object who want warn information.
+ @param warningStr The string contains warning information.
+ **/
+ public static void warning(Object thisClass, String warningStr) {
+ if(messageLevel < WARNING_MESSAGE_LEVEL) {
+ return;
+ }
+
+ if(thisClass instanceof Task) {
+ BuildAction.warningMsg(thisClass, "**WARNING**:" + warningStr);
+ } else if(thisClass instanceof UIAction) {
+ UIAction.warningMsg(thisClass, "**WARNING**:" + warningStr);
+ } else {
+ System.out.println("**WARNING**:" + warningStr);
+ }
+ }
+
+ /**
+ Debug() function provide common Debug information functionality for all
+ PCD tool.
+
+ This function will dispatch message to special class such as BuildAction
+ Class, Entity Class etc.
+
+ @param thisClass The class object who want Debug information.
+ @param debugStr The string contains Debug information.
+ **/
+ public static void debug(Object thisClass, String debugStr) {
+ if(messageLevel < DEBUG_MESSAGE_LEVEL) {
+ return;
+ }
+
+ if(thisClass instanceof Task) {
+ BuildAction.logMsg(thisClass, "%%DEBUG%%:" + debugStr);
+ } else if(thisClass instanceof UIAction) {
+ UIAction.logMsg(thisClass, "%%DEBUG%%:" + debugStr);
+ } else {
+ System.out.println("%%DEBUG%%:" + debugStr);
+ }
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/BuildAction.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/BuildAction.java
new file mode 100644
index 0000000000..c8b0d9dba1
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/BuildAction.java
@@ -0,0 +1,114 @@
+/** @file
+ BuildAction class.
+
+ BuildAction is the parent class for all action related to ant Task. This class will
+ define some common utility functionality, such as logMsg, warningMsg..etc.
+
+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 org.apache.tools.ant.Task;
+import org.tianocore.build.pcd.exception.BuildActionException;
+
+/** BuildAction is the parent class for all action related to ant Task. This class will
+ define some common utility functionality, such as logMsg, warningMsg..etc.
+**/
+abstract class BuildAction extends Task {
+ ///
+ /// Original message level before this action. This value will
+ /// be restored when quit this action.
+ ///
+ private int originalMessageLevel;
+
+ /**
+ checkParameter function check all parameter valid.
+
+ This function will be overrided by child class.
+ **/
+ abstract void checkParameter() throws BuildActionException;
+
+ /**
+ performAction is to execute the detail action.
+
+ This function will be overrided by child class.
+ **/
+ abstract void performAction() throws BuildActionException;
+
+ /**
+ setMessageLevel function set current message for task instance object.
+
+ The message should be restored when this action exit.
+
+ @param messageLevel The message level for this action.
+ **/
+ public void setMessageLevel(int messageLevel) {
+ originalMessageLevel = ActionMessage.messageLevel;
+ ActionMessage.messageLevel = messageLevel;
+ }
+
+ /**
+ logMsg function provide common log information functionality for all
+ PCD tool extends from ANT task class.
+
+ This function will use the log function in Ant task class.
+
+ @param action The class object who want log information.
+ @param logStr The string contains log information.
+ **/
+ public static void logMsg(Object action, String logStr) {
+ //
+ // Comment following code because in console debug environment, we can't
+ // get Project instance.
+ //((Task) action).log(errorText, Project.MSG_INFO);
+ //
+ System.out.println(logStr);
+ }
+
+ /**
+ warningMsg function provide common warning information functionality for all
+ PCD tool.
+
+ This function will dispatch message to special class such as BuildAction
+ Class, Entity Class etc.
+
+ @param action The class object who want warn information.
+ @param warningStr The string contains warning information.
+ **/
+ public static void warningMsg(Object action, String warningStr) {
+ //
+ // Comment following code because in console debug environment, we can't
+ // get Project instance.
+ //((Task) action).log(warningText, Project.MSG_WARN);
+ //
+ System.out.println(warningStr);
+ }
+
+ /**
+ execute function is the main flow for all build action class.
+
+ This workflow will be:
+ 1) Check paramet of this action.
+ 2) Perform the child class action function.
+ 3) Restore the message level.
+
+ @throws BuildActionException
+ **/
+ public void execute() throws BuildActionException {
+ checkParameter();
+ performAction();
+
+ //
+ // Restore orignal message level when exist the action.
+ //
+ ActionMessage.messageLevel = originalMessageLevel;
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
new file mode 100644
index 0000000000..055563df1b
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
@@ -0,0 +1,669 @@
+/** @file
+ CollectPCDAction 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.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
+import org.tianocore.FrameworkPlatformDescriptionDocument;
+import org.tianocore.ModuleSADocument;
+import org.tianocore.PackageSurfaceAreaDocument;
+import org.tianocore.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData;
+import org.tianocore.PcdDefinitionsDocument.PcdDefinitions;
+import org.tianocore.build.autogen.CommonDefinition;
+import org.tianocore.build.global.GlobalData;
+import org.tianocore.build.global.SurfaceAreaQuery;
+import org.tianocore.build.pcd.action.ActionMessage;
+import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
+import org.tianocore.build.pcd.entity.SkuInstance;
+import org.tianocore.build.pcd.entity.Token;
+import org.tianocore.build.pcd.entity.UsageInstance;
+import org.tianocore.build.pcd.exception.EntityException;
+
+/** 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 CollectPCDAction {
+ /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.
+ private MemoryDatabaseManager dbManager;
+
+ /// Workspacepath hold the workspace information.
+ private String workspacePath;
+
+ /// FPD file is the root file.
+ private String fpdFilePath;
+
+ /// Message level for CollectPCDAction.
+ private int originalMessageLevel;
+
+ /**
+ Set WorkspacePath parameter for this action class.
+
+ @param workspacePath parameter for this action
+ **/
+ public void setWorkspacePath(String workspacePath) {
+ this.workspacePath = workspacePath;
+ }
+
+ /**
+ Set action message level for CollectPcdAction tool.
+
+ The message should be restored when this action exit.
+
+ @param actionMessageLevel parameter for this action
+ **/
+ public void setActionMessageLevel(int actionMessageLevel) {
+ originalMessageLevel = ActionMessage.messageLevel;
+ ActionMessage.messageLevel = actionMessageLevel;
+ }
+
+ /**
+ 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 workspacePath The path of workspace of current build or analysis.
+ @param fpdFilePath The fpd file path of current build or analysis.
+ @param messageLevel The message level for this Action.
+
+ @throws Exception 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 workspacePath, String fpdFilePath,
+ int messageLevel) throws Exception {
+ setWorkspacePath(workspacePath);
+ setFPDFilePath(fpdFilePath);
+ setActionMessageLevel(messageLevel);
+ checkParameter();
+ execute();
+ ActionMessage.messageLevel = originalMessageLevel;
+ }
+
+ /**
+ Core execution function for this action class.
+
+ This function work flows will be:
+ 1) Get all token's platform information from FPD, and create token object into memory database.
+ 2) Get all token's module information from MSA, and create usage instance for every module's PCD entry.
+ 3) Get all token's inherited information from MSA's library, and create usage instance
+ for module who consume this library and create usage instance for library for building.
+ 4) Collect token's package information from SPD, update these information for token in memory
+ database.
+
+ @throws EntityException Exception indicate failed to execute this action.
+
+ **/
+ private void execute() throws EntityException {
+ FrameworkPlatformDescriptionDocument fpdDoc = null;
+ Object[][] modulePCDArray = null;
+ Map<String, XmlObject> docMap = null;
+ ModuleSADocument.ModuleSA[] moduleSAs = null;
+ UsageInstance usageInstance = null;
+ String packageName = null;
+ String packageFullPath = null;
+ int index = 0;
+ int libraryIndex = 0;
+ int pcdArrayIndex = 0;
+ List<String> listLibraryInstance = null;
+ String componentTypeStr = null;
+
+ //
+ // Collect all PCD information defined in FPD file.
+ // Evenry token defind in FPD will be created as an token into
+ // memory database.
+ //
+ fpdDoc = createTokenInDBFromFPD();
+
+ //
+ // Searching MSA and SPD document.
+ // The information of MSA will be used to create usage instance into database.
+ // The information of SPD will be used to update the token information in database.
+ //
+
+ HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();
+ map.put("FrameworkPlatformDescription", fpdDoc);
+ SurfaceAreaQuery.setDoc(map);
+
+ moduleSAs = SurfaceAreaQuery.getFpdModules();
+ for(index = 0; index < moduleSAs.length; index ++) {
+ //
+ // Get module document and use SurfaceAreaQuery to get PCD information
+ //
+ docMap = GlobalData.getDoc(moduleSAs[index].getModuleName());
+ SurfaceAreaQuery.setDoc(docMap);
+ modulePCDArray = SurfaceAreaQuery.getModulePCDTokenArray();
+ componentTypeStr = SurfaceAreaQuery.getComponentType();
+ packageName =
+ GlobalData.getPackageNameForModule(moduleSAs[index].getModuleName());
+ packageFullPath = this.workspacePath + File.separator +
+ GlobalData.getPackagePath(packageName) +
+ packageName + ".spd";
+
+ if(modulePCDArray != null) {
+ //
+ // If current MSA contains <PCDs> information, then create usage
+ // instance for PCD information from MSA
+ //
+ for(pcdArrayIndex = 0; pcdArrayIndex < modulePCDArray.length;
+ pcdArrayIndex ++) {
+ usageInstance =
+ createUsageInstanceFromMSA(moduleSAs[index].getModuleName(),
+ modulePCDArray[pcdArrayIndex]);
+
+ if(usageInstance == null) {
+ continue;
+ }
+ //
+ // Get remaining PCD information from the package which this module belongs to
+ //
+ updateTokenBySPD(usageInstance, packageFullPath);
+ }
+ }
+
+ //
+ // Get inherit PCD information which inherit from library instance of this module.
+ //
+ listLibraryInstance =
+ SurfaceAreaQuery.getLibraryInstance(moduleSAs[index].getArch().toString(),
+ CommonDefinition.AlwaysConsumed);
+ if(listLibraryInstance != null) {
+ for(libraryIndex = 0; libraryIndex < listLibraryInstance.size();
+ libraryIndex ++) {
+ inheritPCDFromLibraryInstance(listLibraryInstance.get(libraryIndex),
+ moduleSAs[index].getModuleName(),
+ packageName,
+ componentTypeStr);
+ }
+ }
+ }
+ }
+
+ /**
+ This function will collect inherit PCD information from library for a module.
+
+ This function will create two usage instance for inherited PCD token, one is
+ for module and another is for library.
+ For module, if it inherited a PCD token from library, this PCD token's value
+ should be instanced in module level, and belongs to module.
+ For library, it also need a usage instance for build.
+
+ @param libraryName The name of library instance.
+ @param moduleName The name of module.
+ @param packageName The name of package while module belongs to.
+ @param parentcomponentType The component type of module.
+
+ @throws EntityException If the token does *not* exist in memory database.
+
+ **/
+ private void inheritPCDFromLibraryInstance(String libraryName,
+ String moduleName,
+ String packageName,
+ String parentcomponentType)
+ throws EntityException {
+ Map<String, XmlObject> docMap = null;
+ String primaryKeyString = null;
+ Object[][] libPcdDataArray = null;
+ UUID nullUUID = new UUID(0,0);
+ UUID platformUUID = nullUUID;
+ UUID tokenSpaceGuid = null;
+ int tokenIndex = 0;
+ Token token = null;
+ Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
+ UsageInstance usageInstance = null;
+ String packageFullPath = null;
+
+ //
+ // Query PCD information from library's document.
+ //
+ docMap = GlobalData.getDoc(libraryName);
+ SurfaceAreaQuery.setDoc(docMap);
+ libPcdDataArray = SurfaceAreaQuery.getModulePCDTokenArray();
+
+ if(libPcdDataArray == null) {
+ return;
+ }
+
+ for(tokenIndex = 0; tokenIndex < libPcdDataArray.length; tokenIndex ++) {
+ tokenSpaceGuid =((UUID)libPcdDataArray[tokenIndex][2] == null) ?
+ nullUUID :(UUID)libPcdDataArray[tokenIndex][2];
+
+ //
+ // Get token from memory database. The token must be created from FPD already.
+ //
+ primaryKeyString = Token.getPrimaryKeyString((String)libPcdDataArray[tokenIndex][0],
+ tokenSpaceGuid,
+ platformUUID
+ );
+
+ if(dbManager.isTokenInDatabase(primaryKeyString)) {
+ token = dbManager.getTokenByKey(primaryKeyString);
+ } else {
+ throw new EntityException("The PCD token " + primaryKeyString +
+ " defined in module " + moduleName +
+ " does not exist in FPD file!");
+ }
+
+ //
+ // Create usage instance for module.
+ //
+ pcdType = Token.getpcdTypeFromString((String)libPcdDataArray[tokenIndex][1]);
+ usageInstance = new UsageInstance(token,
+ Token.PCD_USAGE.ALWAYS_CONSUMED,
+ pcdType,
+ CommonDefinition.getComponentType(parentcomponentType),
+ libPcdDataArray[tokenIndex][3],
+ null,
+ (String) libPcdDataArray[tokenIndex][5],
+ "",
+ moduleName,
+ packageName,
+ true);
+ if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(moduleName)) {
+ token.addUsageInstance(usageInstance);
+
+ packageFullPath = this.workspacePath + File.separator +
+ GlobalData.getPackagePath(packageName) +
+ packageName + ".spd";
+ updateTokenBySPD(usageInstance, packageFullPath);
+ }
+
+ //
+ // We need create second usage instance for inherited case, which
+ // add library as an usage instance, because when build a module, and
+ // if module inherited from base library, then build process will build
+ // library at first.
+ //
+ if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(libraryName)) {
+ packageName = GlobalData.getPackageNameForModule(libraryName);
+ usageInstance = new UsageInstance(token,
+ Token.PCD_USAGE.ALWAYS_CONSUMED,
+ pcdType,
+ CommonDefinition.ComponentTypeLibrary,
+ libPcdDataArray[tokenIndex][3],
+ null,
+ (String)libPcdDataArray[tokenIndex][5],
+ "",
+ libraryName,
+ packageName,
+ false);
+ token.addUsageInstance(usageInstance);
+ }
+ }
+ }
+
+ /**
+ Create usage instance for PCD token defined in MSA document
+
+ A PCD token maybe used by many modules, and every module is one of usage
+ instance of this token. For ALWAY_CONSUMED, SOMETIMES_CONSUMED, it is
+ consumer type usage instance of this token, and for ALWAYS_PRODUCED,
+ SOMETIMES_PRODUCED, it is produce type usage instance.
+
+ @param moduleName The name of module
+ @param tokenInfoInMsa The PCD token information array retrieved from MSA.
+
+ @return UsageInstance The usage instance created in memroy database.
+
+ @throws EntityException If token did not exist in database yet.
+
+ **/
+ private UsageInstance createUsageInstanceFromMSA(String moduleName,
+ Object[] tokenInfoInMsa)
+ throws EntityException {
+ String packageName = null;
+ UsageInstance usageInstance = null;
+ UUID tokenSpaceGuid = null;
+ UUID nullUUID = new UUID(0,0);
+ String primaryKeyString = null;
+ UUID platformTokenSpace = nullUUID;
+ Token token = null;
+ Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
+ Token.PCD_USAGE pcdUsage = Token.PCD_USAGE.UNKNOWN;
+
+ tokenSpaceGuid =((UUID)tokenInfoInMsa[2] == null) ? nullUUID :(UUID)tokenInfoInMsa[2];
+
+ primaryKeyString = Token.getPrimaryKeyString((String)tokenInfoInMsa[0],
+ tokenSpaceGuid,
+ platformTokenSpace);
+
+ //
+ // Get token object from memory database firstly.
+ //
+ if(dbManager.isTokenInDatabase(primaryKeyString)) {
+ token = dbManager.getTokenByKey(primaryKeyString);
+ } else {
+ throw new EntityException("The PCD token " + primaryKeyString + " defined in module " +
+ moduleName + " does not exist in FPD file!" );
+ }
+ pcdType = Token.getpcdTypeFromString((String)tokenInfoInMsa[1]);
+ pcdUsage = Token.getUsageFromString((String)tokenInfoInMsa[4]);
+
+ packageName = GlobalData.getPackageNameForModule(moduleName);
+
+ if(Token.PCD_USAGE.UNKNOWN != token.isUsageInstanceExist(moduleName)) {
+ //
+ // BUGBUG: It should *not* throw exception here. Becaues in MdePkg.fpd,
+ // more than on BaseLib exist. But why? need confirmation.
+ //
+ //throw new EntityException(
+ // "In module " + moduleName + " exist more than one PCD token " + token.cName
+ // );
+ ActionMessage.warning(this,
+ "In module " + moduleName + " exist more than one PCD token " + token.cName
+ );
+ return null;
+ }
+
+ //
+ // BUGBUG: following code could be enabled at current schema. Because
+ // current schema does not provide usage information.
+ //
+ // For FEATRURE_FLAG, FIXED_AT_BUILD, PATCH_IN_MODULE type PCD token, his
+ // usage is always ALWAYS_CONSUMED
+ //
+ //if((pcdType != Token.PCD_TYPE.DYNAMIC) &&
+ // (pcdType != Token.PCD_TYPE.DYNAMIC_EX)) {
+ pcdUsage = Token.PCD_USAGE.ALWAYS_CONSUMED;
+ //}
+
+ usageInstance = new UsageInstance(token,
+ pcdUsage,
+ pcdType,
+ CommonDefinition.getComponentType(SurfaceAreaQuery.getComponentType()),
+ tokenInfoInMsa[3],
+ null,
+ (String) tokenInfoInMsa[5],
+ "",
+ moduleName,
+ packageName,
+ false);
+
+ //
+ // Use default value defined in MSA to update datum of token,
+ // if datum of token does not defined in FPD file.
+ //
+ if((token.datum == null) &&(tokenInfoInMsa[3] != null)) {
+ token.datum = tokenInfoInMsa[3];
+ }
+
+ token.addUsageInstance(usageInstance);
+
+ return usageInstance;
+ }
+
+ /**
+ Create token instance object into memory database, the token information
+ comes for FPD file. Normally, FPD file will contain all token platform
+ informations.
+
+ This fucntion should be executed at firsly before others collection work
+ such as searching token information from MSA, SPD.
+
+ @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.
+
+ @throws EntityException Failed to parse FPD xml file.
+
+ **/
+ private FrameworkPlatformDescriptionDocument createTokenInDBFromFPD()
+ throws EntityException {
+ XmlObject doc = null;
+ FrameworkPlatformDescriptionDocument fpdDoc = null;
+ int index = 0;
+ List<PcdBuildData> pcdBuildDataArray = new ArrayList<PcdBuildData>();
+ PcdBuildData pcdBuildData = null;
+ Token token = null;
+ UUID nullUUID = new UUID(0,0);
+ UUID platformTokenSpace= nullUUID;
+ List skuDataArray = new ArrayList();
+ SkuInstance skuInstance = null;
+ int skuIndex = 0;
+
+ //
+ // Get all tokens from FPD file and create token into database.
+ //
+
+ try {
+ doc = XmlObject.Factory.parse(new File(fpdFilePath));
+ } catch(IOException ioE) {
+ throw new EntityException("Can't find the FPD xml fle:" + fpdFilePath);
+ } catch(XmlException xmlE) {
+ throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath);
+ }
+
+ //
+ // Get memoryDatabaseManager instance from GlobalData.
+ //
+ if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {
+ throw new EntityException("The instance of PCD memory database manager is null");
+ }
+
+ dbManager = new MemoryDatabaseManager();
+
+ if(!(doc instanceof FrameworkPlatformDescriptionDocument)) {
+ throw new EntityException("File " + fpdFilePath +
+ " is not a FrameworkPlatformDescriptionDocument");
+ }
+
+ fpdDoc =(FrameworkPlatformDescriptionDocument)doc;
+
+ //
+ // Add all tokens in FPD into Memory Database.
+ //
+ pcdBuildDataArray =
+ fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().getPcdBuildDataList();
+ for(index = 0;
+ index < fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().sizeOfPcdBuildDataArray();
+ index ++) {
+ pcdBuildData = pcdBuildDataArray.get(index);
+ token = new Token(pcdBuildData.getCName(), new UUID(0, 0), new UUID(0, 0));
+ //
+ // BUGBUG: in FPD, <defaultValue> should be defined as <Value>
+ //
+ token.datum = pcdBuildData.getDefaultValue();
+ token.hiiEnabled = pcdBuildData.getHiiEnable();
+ token.variableGuid = Token.getGUIDFromSchemaObject(pcdBuildData.getVariableGuid());
+ token.variableName = pcdBuildData.getVariableName();
+ token.variableOffset = Integer.decode(pcdBuildData.getDataOffset());
+ token.skuEnabled = pcdBuildData.getSkuEnable();
+ token.maxSkuCount = Integer.decode(pcdBuildData.getMaxSku());
+ token.skuId = Integer.decode(pcdBuildData.getSkuId());
+ token.skuDataArrayEnabled = pcdBuildData.getSkuDataArrayEnable();
+ token.assignedtokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue());
+ skuDataArray = pcdBuildData.getSkuDataArray1();
+
+ if(skuDataArray != null) {
+ for(skuIndex = 0; skuIndex < skuDataArray.size(); skuIndex ++) {
+ //
+ // BUGBUG: Now in current schema, The value is defined as String type,
+ // it is not correct, the type should be same as the datumType
+ //
+ skuInstance = new SkuInstance(((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getId(),
+ ((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getValue());
+ token.skuData.add(skuInstance);
+ }
+ }
+
+ if(dbManager.isTokenInDatabase(Token.getPrimaryKeyString(token.cName,
+ token.tokenSpaceName,
+ platformTokenSpace))) {
+ //
+ // If found duplicate token, Should tool be hold?
+ //
+ ActionMessage.warning(this,
+ "Token " + token.cName + " exists in token database");
+ continue;
+ }
+ token.pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());
+ dbManager.addTokenToDatabase(Token.getPrimaryKeyString(token.cName,
+ token.tokenSpaceName,
+ platformTokenSpace),
+ token);
+ }
+
+ return fpdDoc;
+ }
+
+ /**
+ Update PCD token in memory database by help information in SPD.
+
+ After create token from FPD and create usage instance from MSA, we should collect
+ PCD package level information from SPD and update token information in memory
+ database.
+
+ @param usageInstance The usage instance defined in MSA and want to search in SPD.
+ @param packageFullPath The SPD file path.
+
+ @throws EntityException Failed to parse SPD xml file.
+
+ **/
+ private void updateTokenBySPD(UsageInstance usageInstance,
+ String packageFullPath)
+ throws EntityException {
+ PackageSurfaceAreaDocument pkgDoc = null;
+ List<PcdDefinitions.PcdEntry> pcdEntryArray = new ArrayList<PcdDefinitions.PcdEntry>();
+ int index;
+ boolean isFoundInSpd = false;
+ Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;
+
+ try {
+ pkgDoc =(PackageSurfaceAreaDocument)XmlObject.Factory.parse(new File(packageFullPath));
+ } catch(IOException ioE) {
+ throw new EntityException("Can't find the FPD xml fle:" + packageFullPath);
+ } catch(XmlException xmlE) {
+ throw new EntityException("Can't parse the FPD xml fle:" + packageFullPath);
+ }
+
+ pcdEntryArray = pkgDoc.getPackageSurfaceArea().getPcdDefinitions().getPcdEntryList();
+ for(index = 0; index < pcdEntryArray.size(); index ++) {
+ if(pcdEntryArray.get(index).getCName().equalsIgnoreCase(
+ usageInstance.parentToken.cName)) {
+ isFoundInSpd = true;
+ //
+ // From SPD file , we can get following information.
+ // Token: Token number defined in package level.
+ // PcdItemType: This item does not single one. It means all supported item type.
+ // datumType: UINT8, UNIT16, UNIT32, UINT64, VOID*, BOOLEAN
+ // datumSize: The size of default value or maxmine size.
+ // defaultValue: This value is defined in package level.
+ // HelpText: The help text is provided in package level.
+ //
+
+ usageInstance.parentToken.tokenNumber = Integer.decode(pcdEntryArray.get(index).getToken());
+
+ if(pcdEntryArray.get(index).getDatumType() != null) {
+ datumType = Token.getdatumTypeFromString(
+ pcdEntryArray.get(index).getDatumType().toString());
+ if(usageInstance.parentToken.datumType == Token.DATUM_TYPE.UNKNOWN) {
+ usageInstance.parentToken.datumType = datumType;
+ } else {
+ if(datumType != usageInstance.parentToken.datumType) {
+ throw new EntityException("Different datum types are defined for Token :" +
+ usageInstance.parentToken.cName);
+ }
+ }
+
+ } else {
+ throw new EntityException("The datum type for token " + usageInstance.parentToken.cName +
+ " is not defind in SPD file " + packageFullPath);
+ }
+
+ usageInstance.defaultValueInSPD = pcdEntryArray.get(index).getDefaultValue();
+ usageInstance.helpTextInSPD = "Help Text in SPD";
+
+ //
+ // If token's datum is not valid, it indicate that datum is not provided
+ // in FPD and defaultValue is not provided in MSA, then use defaultValue
+ // in SPD as the datum of token.
+ //
+ if(usageInstance.parentToken.datum == null) {
+ if(pcdEntryArray.get(index).getDefaultValue() != null) {
+ usageInstance.parentToken.datum = pcdEntryArray.get(index).getDefaultValue();
+ } else {
+ throw new EntityException("FPD does not provide datum for token " + usageInstance.parentToken.cName +
+ ", MSA and SPD also does not provide <defaultValue> for this token!");
+ }
+ }
+ }
+ }
+
+ if(!isFoundInSpd ) {
+ ActionMessage.warning(this,
+ "Can *not* find the PCD token " + usageInstance.parentToken.cName +
+ " in SPD file!");
+ }
+ }
+
+ /**
+ check parameter for this action.
+
+ @throws EntityException Bad parameter.
+ **/
+ private void checkParameter() throws EntityException {
+ File file = null;
+
+ if((fpdFilePath == null) ||(workspacePath == null)) {
+ throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
+ }
+
+ if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {
+ throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
+ }
+
+ file = new File(workspacePath);
+ if(!file.exists()) {
+ throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");
+ }
+
+ file = new File(fpdFilePath);
+
+ if(!file.exists()) {
+ throw new EntityException("FPD File " + fpdFilePath + " does not exist!");
+ }
+ }
+
+ /**
+ Test case function
+
+ @param argv parameter from command line
+ **/
+ public static void main(String argv[]) throws EntityException {
+ CollectPCDAction ca = new CollectPCDAction();
+ ca.setWorkspacePath("G:/mdk");
+ ca.setFPDFilePath("G:/mdk/EdkNt32Pkg/build/Nt32.fpd");
+ ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);
+ GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
+ "G:/mdk");
+ ca.execute();
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java
new file mode 100644
index 0000000000..ca65c7546c
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java
@@ -0,0 +1,452 @@
+/** @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.io.File;
+import java.util.List;
+
+import org.tianocore.build.global.GlobalData;
+import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
+import org.tianocore.build.pcd.entity.Token;
+import org.tianocore.build.pcd.entity.UsageInstance;
+import org.tianocore.build.pcd.exception.BuildActionException;
+import org.tianocore.build.pcd.exception.EntityException;
+
+/** 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 name of module which is analysised currently.
+ ///
+ private String moduleName;
+ ///
+ /// Wheter current module is PCD emulated driver. It is only for
+ /// emulated PCD driver and will be kept until PCD IMAGE tool ready.
+ ///
+ private boolean isEmulatedPCDDriver;
+ ///
+ /// The generated string for header file.
+ ///
+ private String hAutoGenString;
+ ///
+ /// The generated string for C code file.
+ ///
+ private String cAutoGenString;
+
+ /**
+ Set parameter ModuleName
+
+ @param moduleName the module name parameter.
+ **/
+ public void setModuleName(String moduleName) {
+ this.moduleName = moduleName;
+ }
+
+ /**
+ Set parameter isEmulatedPCDDriver
+
+ @param isEmulatedPCDDriver whether this module is PeiEmulatedPCD driver
+ **/
+ public void setIsEmulatedPCDDriver(boolean isEmulatedPCDDriver) {
+ this.isEmulatedPCDDriver = isEmulatedPCDDriver;
+ }
+
+ /**
+ Get the output of generated string for header file.
+
+ @return the string of header file for PCD
+ **/
+ public String OutputH() {
+ return hAutoGenString;
+ }
+
+ /**
+ Get the output of generated string for C Code file.
+
+ @return the string of C code file for PCD
+ **/
+ public String OutputC() {
+ return cAutoGenString;
+ }
+
+ /**
+ Construct function
+
+ This function mainly initialize some member variable.
+
+ @param moduleName Parameter of this action class.
+ @param isEmulatedPCDDriver Parameter of this action class.
+ **/
+ public PCDAutoGenAction(String moduleName, boolean isEmulatedPCDDriver) {
+ dbManager = null;
+ setIsEmulatedPCDDriver(isEmulatedPCDDriver);
+ setModuleName(moduleName);
+ }
+
+ /**
+ check the parameter for action class.
+
+ @throws BuildActionException Bad parameter.
+ **/
+ void checkParameter() throws BuildActionException {
+ if(!isEmulatedPCDDriver &&(moduleName == null)) {
+ throw new BuildActionException("Wrong module name parameter for PCDAutoGenAction tool!");
+ }
+
+ if(!isEmulatedPCDDriver && moduleName.length() == 0) {
+ throw new BuildActionException("Wrong module name parameter for PCDAutoGenAction tool!");
+ }
+
+ //
+ // Check the PCD memory database manager is valid.
+ //
+ if(GlobalData.getPCDMemoryDBManager() == null) {
+ throw new BuildActionException("Memory database has not been initlizated!");
+ }
+
+ dbManager = GlobalData.getPCDMemoryDBManager();
+
+ if(dbManager.getDBSize() == 0) {
+ throw new BuildActionException("Memory database does not contain any record!");
+ }
+
+ ActionMessage.debug(this,
+ "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens");
+ }
+
+ /**
+ 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.
+ **/
+ void performAction() throws BuildActionException {
+ ActionMessage.debug(this,
+ "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");
+
+ hAutoGenString = "";
+ cAutoGenString = "";
+
+ if(isEmulatedPCDDriver) {
+ generateAutogenForPCDEmulatedDriver();
+ } else {
+ 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;
+ List<UsageInstance> usageInstanceArray;
+
+ usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(moduleName);
+
+ if(usageInstanceArray.size() != 0) {
+ //
+ // Add "#include 'PcdLib.h'" for Header file
+ //
+ hAutoGenString = "#include <MdePkg/Include/Library/PcdLib.h>\r\n";
+ }
+
+ for(index = 0; index < usageInstanceArray.size(); index ++) {
+ ActionMessage.debug(this,
+ "Module " + moduleName + "'s PCD [" + Integer.toHexString(index) +
+ "]: " + usageInstanceArray.get(index).parentToken.cName);
+ try {
+ usageInstanceArray.get(index).generateAutoGen();
+ hAutoGenString += usageInstanceArray.get(index).getHAutogenStr() + "\r\n";
+ cAutoGenString += usageInstanceArray.get(index).getCAutogenStr() + "\r\n";
+ } catch(EntityException exp) {
+ throw new BuildActionException(exp.getMessage());
+ }
+ }
+
+ ActionMessage.debug(this,
+ "Module " + moduleName + "'s PCD header file:\r\n" + hAutoGenString + "\r\n"
+ );
+ ActionMessage.debug(this,
+ "Module " + moduleName + "'s PCD C file:\r\n" + cAutoGenString + "\r\n"
+ );
+ }
+
+ /**
+ Generate all PCD autogen string and the emulated PCD IMAGE array for emulated driver.
+
+ Currently, we should generated all PCD information(maybe all dynamic) as array
+ in Pei emulated driver for simulating PCD runtime database.
+
+ **/
+ private void generateAutogenForPCDEmulatedDriver() {
+ int index;
+ Token[] tokenArray;
+ UsageInstance usageInstance;
+
+ //
+ // Add "#include 'PcdLib.h'" for Header file
+ //
+ hAutoGenString = "#include <MdePkg/Include/Library/PcdLib.h>\r\n";
+
+ tokenArray = dbManager.getRecordArray();
+ for(index = 0; index < tokenArray.length; index ++) {
+ //
+ // Get one consumer instance and generate autogen for this token.
+ //
+ if(tokenArray[index].consumers != null ) {
+ if(tokenArray[index].consumers.size() == 0) {
+ continue;
+ }
+
+ usageInstance = tokenArray[index].consumers.get(0);
+ try {
+ usageInstance.generateAutoGen();
+ } catch(EntityException exp) {
+ throw new BuildActionException(exp.getMessage());
+ }
+
+ hAutoGenString += usageInstance.getHAutogenStr();
+ cAutoGenString += usageInstance.getCAutogenStr();
+
+ hAutoGenString += "\r\n";
+ cAutoGenString += "\r\n";
+ }
+ }
+
+ generatePCDEmulatedArray(tokenArray);
+
+ ActionMessage.debug(this,
+ "PCD emulated driver's header: \r\n" + hAutoGenString + "\r\n"
+ );
+ ActionMessage.debug(this,
+ "PCD emulated driver's C code: \r\n" + cAutoGenString + "\r\n"
+ );
+
+ }
+
+ /**
+ Generate PCDEmulated array in PCDEmulated driver for emulated runtime database.
+
+ @param tokenArray All PCD token in memory database.
+
+ @throws BuildActionException Unknown PCD_TYPE
+ **/
+ private void generatePCDEmulatedArray(Token[] tokenArray)
+ throws BuildActionException {
+ int index;
+ Token token;
+ String[] guidStrArray;
+ String value;
+
+ //
+ // The value of String type of PCD entry maybe use byte array but not string direcly
+ // such as {0x1, 0x2, 0x3}, and define PCD1_STRING_Value as L"string define here"
+ // For this case, we should generate a string array to C output and use the address
+ // of generated string array.
+ //
+ for(index = 0; index < tokenArray.length; index ++) {
+ token = tokenArray[index];
+
+ if((token.producers.size() == 0) &&(token.consumers.size() == 0)) {
+ //
+ // If no one use this PCD token, it will not generated in emulated array.
+ //
+ continue;
+ }
+ value = token.datum.toString();
+ if(token.datumType == Token.DATUM_TYPE.POINTER) {
+ if(!((value.charAt(0) == 'L' && value.charAt(1) == '"') ||(value.charAt(0) == '"'))) {
+ cAutoGenString += String.format("UINT8 _mPcdArray%08x[] = %s;\r\n",
+ index,
+ value
+ );
+ }
+ }
+ }
+
+ //
+ // Output emulated PCD entry array
+ //
+ cAutoGenString += "\r\nEMULATED_PCD_ENTRY gEmulatedPcdEntry[] = {\r\n";
+
+ for(index = 0; index < tokenArray.length; index ++) {
+ token = tokenArray[index];
+
+ if((token.producers.size() == 0) &&(token.consumers.size() == 0)) {
+ //
+ // If no one use this PCD token, it will not generated in emulated array.
+ //
+ continue;
+ }
+
+ if(index != 0) {
+ cAutoGenString += ",\r\n";
+ }
+
+ //
+ // Print Start "{" for a Token item in array
+ //
+ cAutoGenString += " {\r\n";
+
+ //
+ // Print Token Name
+ //
+ cAutoGenString += String.format(" _PCD_TOKEN_%s,\r\n", token.cName);
+
+ //
+ // Print Hii information
+ //
+ if(token.hiiEnabled) {
+ cAutoGenString += String.format(" TRUE,\r\n");
+ } else {
+ cAutoGenString += String.format(" FALSE,\r\n");
+ }
+
+ //
+ // Print sku information
+ //
+ if(token.skuEnabled) {
+ cAutoGenString += String.format(" TRUE,\r\n");
+ } else {
+ cAutoGenString += String.format(" FALSE,\r\n");
+ }
+
+ //
+ // Print maxSkuCount
+ //
+ cAutoGenString += String.format(" %d,\r\n", token.maxSkuCount);
+
+ cAutoGenString += String.format(" %d,\r\n", token.skuId);
+
+ if(token.variableGuid == null) {
+ cAutoGenString += " { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\r\n";
+ } else {
+ guidStrArray =(token.variableGuid.toString()).split("-");
+
+ cAutoGenString += String.format(" { 0x%s, 0x%s, 0x%s, { 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s } },\r\n",
+ 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))
+ );
+
+ }
+
+ value = token.datum.toString();
+ if(token.datumType == Token.DATUM_TYPE.POINTER) {
+ if((value.charAt(0) == 'L' && value.charAt(1) == '"') || value.charAt(0) == '"') {
+ cAutoGenString += String.format(" sizeof(_PCD_VALUE_%s),\r\n", token.cName);
+ cAutoGenString += String.format(" 0, %s, %s,\r\n", token.variableName, value);
+ } else {
+ cAutoGenString += String.format(" sizeof(_mPcdArray%08x),\r\n", index);
+ cAutoGenString += String.format(" 0, &_mPcdArray%08x, %s,\r\n", index, token.variableName);
+ }
+ } else {
+ switch(token.datumType) {
+ case UINT8:
+ cAutoGenString += " 1,\r\n";
+ break;
+ case UINT16:
+ cAutoGenString += " 2,\r\n";
+ break;
+ case UINT32:
+ cAutoGenString += " 4,\r\n";
+ break;
+ case UINT64:
+ cAutoGenString += " 8,\r\n";
+ break;
+ case BOOLEAN:
+ cAutoGenString += " 1,\r\n";
+ break;
+ default:
+ throw new BuildActionException("Unknown datum size");
+ }
+ cAutoGenString += String.format(" %s, %s, NULL,\r\n", value, token.variableName);
+ }
+
+ //
+ // Print end "}" for a token item in array
+ //
+ cAutoGenString += " }";
+ }
+
+ cAutoGenString += "\r\n};\r\n";
+ cAutoGenString += "\r\n";
+ cAutoGenString += "UINTN\r\n";
+ cAutoGenString += "GetPcdDataBaseSize(\r\n";
+ cAutoGenString += " VOID\r\n";
+ cAutoGenString += " )\r\n";
+ cAutoGenString += "{\r\n";
+ cAutoGenString += " return sizeof(gEmulatedPcdEntry);\r\n";
+ cAutoGenString += "}\r\n";
+ }
+
+ /**
+ Test case function
+
+ @param argv paramter from command line
+ **/
+ public static void main(String argv[]) {
+ String logFilePath = "G:/mdk/EdkNt32Pkg/build/Nt32.fpd";
+
+ //
+ // At first, CollectPCDAction should be invoked to collect
+ // all PCD information from SPD, MSA, FPD.
+ //
+ CollectPCDAction collectionAction = new CollectPCDAction();
+ GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
+ "G:/mdk");
+
+ GlobalData.getPCDMemoryDBManager().setLogFileName(logFilePath + ".PCDMemroyDatabaseLog.txt");
+
+ try {
+ collectionAction.perform("G:/mdk",
+ logFilePath,
+ ActionMessage.MAX_MESSAGE_LEVEL);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+
+ //
+ // Then execute the PCDAuotoGenAction to get generated Autogen.h and Autogen.c
+ //
+ PCDAutoGenAction autogenAction = new PCDAutoGenAction("HelloWorld",
+ true
+ );
+ autogenAction.execute();
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java
new file mode 100644
index 0000000000..cd67dd46c9
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/ShowPCDDatabaseAction.java
@@ -0,0 +1,130 @@
+/** @file
+ ShowPCDDatabase class.
+
+ This class is the action to diplay the PCD database.
+
+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 org.tianocore.build.global.GlobalData;
+import org.tianocore.build.pcd.exception.UIException;
+import org.tianocore.build.pcd.ui.PCDDatabaseFrame;
+
+/** This class is the action to show PCD database.
+**/
+public class ShowPCDDatabaseAction extends UIAction {
+ ///
+ /// The workspace path parameter.
+ ///
+ private String workspacePath;
+ ///
+ /// The FpdfileName parameter.
+ ///
+ private String fpdFilePath;
+
+ /**
+ set workspace path parameter for this action.
+
+ @param workspacePath the string of workspace path.
+ **/
+ public void setWorkspacePath(String workspacePath) {
+ this.workspacePath = workspacePath;
+ }
+
+ /**
+ set fpd file path parameter for this action.
+
+ @param fpdFilePath file path string
+ **/
+ public void setFPDFilePath(String fpdFilePath) {
+ this.fpdFilePath = "./" + fpdFilePath;
+ }
+
+ /**
+ check paramter for this action.
+
+ @throw UIException wrong paramter.
+ **/
+ void checkParamter() throws UIException {
+ File file = null;
+
+ if((fpdFilePath == null) ||(workspacePath == null)) {
+ throw new UIException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
+ }
+
+ if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {
+ throw new UIException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
+ }
+
+ file = new File(workspacePath);
+ if(!file.exists()) {
+ throw new UIException("WorkpacePath " + workspacePath + " does not exist!");
+ }
+
+ file = new File(fpdFilePath);
+
+ if(!file.exists()) {
+ throw new UIException("FPD File " + fpdFilePath + " does not exist!");
+ }
+ }
+
+ /**
+ Core workflow function.
+
+ @throw UIException Fail to show PCD database.
+ **/
+ void performAction() throws UIException {
+ CollectPCDAction collectAction = null;
+ PCDDatabaseFrame dbFrame = null;
+
+ //
+ // Initialize global data.
+ //
+ GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
+ workspacePath);
+ GlobalData.getPCDMemoryDBManager().setLogFileName(fpdFilePath + ".PCDMemroyDatabaseLog.txt");
+
+ //
+ // Collect PCD information.
+ //
+ collectAction = new CollectPCDAction();
+
+ try {
+ collectAction.perform(workspacePath,
+ fpdFilePath,
+ ActionMessage.LOG_MESSAGE_LEVEL);
+ } catch(Exception exp) {
+ throw new UIException(exp.getMessage());
+ }
+
+ //
+ // Start tree windows.
+ //
+ dbFrame = new PCDDatabaseFrame(GlobalData.getPCDMemoryDBManager());
+ }
+
+ /**
+ Entry function.
+
+ The action is run from command line.
+
+ @param argv command line parameter.
+ **/
+ public static void main(String[] argv) throws UIException {
+ ShowPCDDatabaseAction showAction = new ShowPCDDatabaseAction();
+ showAction.setWorkspacePath(argv[0]);
+ showAction.setFPDFilePath(argv[1]);
+ showAction.execute();
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/action/UIAction.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/UIAction.java
new file mode 100644
index 0000000000..2cde9b24ec
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/action/UIAction.java
@@ -0,0 +1,83 @@
+/** @file
+ UIAction class.
+
+ This class is the parent action class of UI wizard.
+
+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 org.tianocore.build.pcd.exception.UIException;
+
+/** This class is the parent class for all UI wizard action.
+**/
+public abstract class UIAction {
+ ///
+ /// original message level. when finish this action, original
+ /// message level will be restored.
+ ///
+ private int originalMessageLevel;
+
+ /**
+ Check the parameter for this aciton.
+
+ This function will be overrided by child class.
+ **/
+ abstract void checkParamter() throws UIException;
+
+ /**
+ Perform action.
+
+ This function will be overrided by child class.
+ **/
+ abstract void performAction() throws UIException;
+
+ /**
+ set the message level for this action.
+
+ @param messageLevel message level wanted.
+ **/
+ public void setMessageLevel(int messageLevel) {
+ originalMessageLevel = ActionMessage.messageLevel;
+ ActionMessage.messageLevel = messageLevel;
+ }
+
+ /**
+ log message for UI wizard aciton.
+
+ @param actionObj aciton instance object.
+ @param logStr log message string
+ **/
+ public static void logMsg(Object actionObj, String logStr) {
+ System.out.println(logStr);
+ }
+
+ /**
+ Warning message for UI wizard action.
+
+ @param warningObj action instance object.
+ @param warningStr warning message string.
+ **/
+ public static void warningMsg(Object warningObj, String warningStr) {
+ System.out.println(warningStr);
+ }
+
+ /**
+ Entry function for all UI wizard actions.
+ **/
+ public void execute() throws UIException {
+ checkParamter();
+ performAction();
+
+ ActionMessage.messageLevel = originalMessageLevel;
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java
new file mode 100644
index 0000000000..6f4f8949ef
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/MemoryDatabaseManager.java
@@ -0,0 +1,306 @@
+/** @file
+ MemoryDatabaseManager class.
+
+ Database hold all PCD information comes from SPD, MSA, FPD file in memory.
+
+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.entity;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.tianocore.build.autogen.CommonDefinition;
+import org.tianocore.build.pcd.action.ActionMessage;
+
+/** Database hold all PCD information comes from SPD, MSA, FPD file in memory.
+**/
+public class MemoryDatabaseManager {
+ ///
+ /// Memory database. The string "cName + SpaceNameGuid" is primary key.
+ /// memory database is in global scope, and it will be used for others PCD tools.
+ ///
+ private static Map<String, Token> memoryDatabase = null;
+ ///
+ /// The log file name for dumping memory database.
+ ///
+ private static String logFileName = null;
+
+ /**
+ Constructure function
+ **/
+ public MemoryDatabaseManager() {
+ //
+ // Allocate memory for new database in global scope.
+ //
+ if (memoryDatabase == null) {
+ memoryDatabase = new HashMap<String, Token>();
+ }
+ }
+
+ /**
+ Get the log file name.
+ **/
+ public String getLogFileName() {
+ return logFileName;
+ }
+
+ /**
+ Set parameter log file name.
+
+ @param fileName log file name parameter.
+ **/
+ public void setLogFileName(String fileName) {
+ logFileName = fileName;
+ }
+
+ /**
+ Judege whether token exists in memory database
+
+ @param primaryKey the primaryKey for searching token
+
+ @retval TRUE - token already exist in database.
+ @retval FALSE - token does not exist in database.
+ **/
+ public boolean isTokenInDatabase(String primaryKey) {
+ return (memoryDatabase.get(primaryKey) != null);
+ }
+
+ /**
+ Add a pcd token into memory database.
+
+ @param primaryKey the primary key for searching token
+ @param token token instance
+ **/
+ public void addTokenToDatabase(String primaryKey, Token token) {
+ memoryDatabase.put(primaryKey, token);
+ }
+
+ /**
+ Get a token instance from memory database with primary key.
+
+ @param primaryKey the primary key for searching token
+
+ @return token instance.
+ **/
+ public Token getTokenByKey(String primaryKey) {
+ return memoryDatabase.get(primaryKey);
+ }
+
+ /**
+ Get the number of PCD token record in memory database.
+
+ @return the number of PCD token record in memory database.
+ **/
+ public int getDBSize() {
+ return memoryDatabase.size();
+ }
+
+ /**
+ Get the token record array contained all PCD token in memory database.
+
+ @return the token record array contained all PCD token in memory database.
+ **/
+ public Token[] getRecordArray() {
+ Token[] tokenArray = null;
+ Object[] dataArray = null;
+ Map.Entry entry = null;
+ int index = 0;
+
+ if (memoryDatabase == null) {
+ return null;
+ }
+
+ dataArray = memoryDatabase.entrySet().toArray();
+ tokenArray = new Token[memoryDatabase.size()];
+ for (index = 0; index < memoryDatabase.size(); index ++) {
+ entry =(Map.Entry) dataArray [index];
+ tokenArray[index] =(Token) entry.getValue();
+ }
+
+ return tokenArray;
+ }
+
+ /**
+ Get all PCD record for a module according to module's name.
+
+ @param moduleName the name of module.
+
+ @return all usage instance for this module in memory database.
+ **/
+ public List<UsageInstance> getUsageInstanceArrayByModuleName(String moduleName) {
+ Token[] tokenArray = null;
+ int recordIndex = 0;
+ int usageInstanceIndex = 0;
+ List<UsageInstance> usageInstanceArray = null;
+ UsageInstance usageInstance = null;
+ List<UsageInstance> returnArray = new ArrayList<UsageInstance>();
+
+ tokenArray = getRecordArray();
+
+ //
+ // Loop to find all PCD record related to current module
+ //
+ for (recordIndex = 0; recordIndex < getDBSize(); recordIndex ++) {
+ if (tokenArray[recordIndex].producers != null) {
+ usageInstanceArray = tokenArray[recordIndex].producers;
+ for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex ++) {
+ usageInstance =(UsageInstance) usageInstanceArray.get(usageInstanceIndex);
+ if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {
+ returnArray.add(usageInstance);
+ }
+ }
+ }
+
+ if (tokenArray[recordIndex].consumers != null) {
+ usageInstanceArray = tokenArray[recordIndex].consumers;
+ for (usageInstanceIndex = 0; usageInstanceIndex < usageInstanceArray.size(); usageInstanceIndex ++) {
+ usageInstance =(UsageInstance) usageInstanceArray.get(usageInstanceIndex);
+ if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {
+ returnArray.add(usageInstance);
+ }
+ }
+ }
+ }
+
+ if (returnArray.size() == 0) {
+ ActionMessage.warning(this, "Can *not* find any usage instance for " + moduleName + " !");
+ }
+
+ return returnArray;
+ }
+
+ /**
+ Get all modules name who contains PCD information
+
+ @return Array for module name
+ **/
+ public List<String> getAllModuleArray()
+ {
+ int indexToken = 0;
+ int usageIndex = 0;
+ int moduleIndex = 0;
+ Token[] tokenArray = null;
+ List<String> moduleNames = new ArrayList<String>();
+ UsageInstance usageInstance = null;
+ boolean bFound = false;
+
+ tokenArray = this.getRecordArray();
+ //
+ // Find all producer usage instance for retrieving module's name
+ //
+ for (indexToken = 0; indexToken < getDBSize(); indexToken ++) {
+ for (usageIndex = 0; usageIndex < tokenArray[indexToken].producers.size(); usageIndex ++) {
+ usageInstance = tokenArray[indexToken].producers.get(usageIndex);
+ bFound = false;
+ for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {
+ if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.moduleName)) {
+ bFound = true;
+ break;
+ }
+ }
+ if (!bFound) {
+ moduleNames.add(usageInstance.moduleName);
+ }
+ }
+ }
+
+ //
+ // Find all consumer usage instance for retrieving module's name
+ //
+ for (indexToken = 0; indexToken < getDBSize(); indexToken ++) {
+ for (usageIndex = 0; usageIndex < tokenArray[indexToken].consumers.size(); usageIndex ++) {
+ usageInstance = tokenArray[indexToken].consumers.get(usageIndex);
+ bFound = false;
+ for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {
+ if (moduleNames.get(moduleIndex).equalsIgnoreCase(usageInstance.moduleName)) {
+ bFound = true;
+ break;
+ }
+ }
+ if (!bFound) {
+ moduleNames.add(usageInstance.moduleName);
+ }
+ }
+ }
+ return moduleNames;
+ }
+
+ /**
+ Dump all PCD record into file for reviewing.
+ **/
+ public void DumpAllRecords() {
+ BufferedWriter bWriter = null;
+ Object[] tokenArray = null;
+ Map.Entry entry = null;
+ Token token = null;
+ int index = 0;
+ int usageIndex = 0;
+ UsageInstance usageInstance = null;
+ String inheritString = null;
+ String componentTypeName = null;
+
+ try {
+ bWriter = new BufferedWriter(new FileWriter(new File(logFileName)));
+ tokenArray = memoryDatabase.entrySet().toArray();
+ for (index = 0; index < memoryDatabase.size(); index ++) {
+ entry =(Map.Entry) tokenArray [index];
+ token =(Token) entry.getValue();
+ bWriter.write("****** token [" + Integer.toString(index) + "] ******\r\n");
+ bWriter.write(" cName:" + token.cName + "\r\n");
+ for (usageIndex = 0; usageIndex < token.producers.size(); usageIndex ++) {
+ usageInstance =(UsageInstance)token.producers.get(usageIndex);
+ componentTypeName = CommonDefinition.getComponentTypeString(usageInstance.componentType);
+
+ if (usageInstance.isInherit) {
+ inheritString = "Inherit";
+ } else {
+ inheritString = "";
+ }
+ bWriter.write(String.format(" (Producer)#%d: %s:%s Package:%s %s\r\n",
+ usageIndex,
+ componentTypeName,
+ usageInstance.moduleName,
+ usageInstance.packageName,
+ inheritString
+ )
+ );
+ }
+ for (usageIndex = 0; usageIndex < token.consumers.size(); usageIndex ++) {
+ usageInstance =(UsageInstance)token.consumers.get(usageIndex);
+ componentTypeName = CommonDefinition.getComponentTypeString(usageInstance.componentType);
+ if (usageInstance.isInherit) {
+ inheritString = "Inherit";
+ } else {
+ inheritString = "";
+ }
+ bWriter.write(String.format(" (Consumer)#%d: %s:%s Package:%s %s\r\n",
+ usageIndex,
+ componentTypeName,
+ usageInstance.moduleName,
+ usageInstance.packageName,
+ inheritString
+ )
+ );
+ }
+ }
+ bWriter.close();
+ } catch (IOException exp) {
+ ActionMessage.warning(this, "Failed to open database log file: " + logFileName);
+ }
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/SkuInstance.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/SkuInstance.java
new file mode 100644
index 0000000000..2886506411
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/SkuInstance.java
@@ -0,0 +1,40 @@
+/** @file
+ SkuInstance class.
+
+ Sku instance contains ID and value, A pcd token maybe contains more than one Sku instance.
+
+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.entity;
+
+/** Sku instance contains ID and value, A pcd token maybe contains more than one Sku instance.
+**/
+public class SkuInstance {
+ ///
+ /// The id number of this SKU instance
+ ///
+ public int id;
+ ///
+ /// The value of this SKU instance
+ ///
+ public Object value;
+
+ /**
+ Constructure function
+
+ @param id sku id
+ @param value sku value for this id.
+ **/
+ public SkuInstance(int id, Object value) {
+ this.id = id;
+ this.value = value;
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java
new file mode 100644
index 0000000000..e4ecfc034c
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java
@@ -0,0 +1,641 @@
+/** @file
+ Token class.
+
+ This module contains all classes releted to PCD token.
+
+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.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.tianocore.build.pcd.action.ActionMessage;
+
+/** This class is to descript a PCD token object. The information of a token mainly
+ comes from MSA, SPD and setting produced by platform developer.
+**/
+public class Token {
+ ///
+ /// Enumeration macro defintion for PCD type.
+ /// BUGBUG: Not use upcase charater is to facility for reading. It may be changed
+ /// in coding review.
+ public enum PCD_TYPE {FEATURE_FLAG, FIXED_AT_BUILD, PATCHABLE_IN_MODULE, DYNAMIC,
+ DYNAMIC_EX, UNKNOWN}
+
+ ///
+ /// Enumeration macro definition for datum type. All type mainly comes from ProcessBind.h.
+ /// Wizard maybe expand this type as "int, unsigned int, short, unsigned short etc" in
+ /// prompt dialog.
+ ///
+ public enum DATUM_TYPE {UINT8, UINT16, UINT32, UINT64, BOOLEAN, POINTER, UNKNOWN}
+
+ ///
+ /// Enumeration macor defintion for usage of PCD
+ ///
+ public enum PCD_USAGE {ALWAYS_PRODUCED, ALWAYS_CONSUMED, SOMETIMES_PRODUCED,
+ SOMETIMES_CONSUMED, UNKNOWN}
+
+ ///
+ /// cName is to identify a PCD entry and will be used for generating autogen.h/autogen.c.
+ /// cName will be defined in MSA, SPD and FPD, can be regarded as primary key with token space guid.
+ ///
+ public String cName;
+
+ ///
+ /// Token space name is the guid defined by token itself in package or module level. This
+ /// name mainly for DynamicEx type. For other PCD type token, his token space name is the
+ /// assignedtokenSpaceName as follows.
+ /// tokenSpaceName is defined in MSA, SPD, FPD, can be regarded as primary key with cName.
+ ///
+ public UUID tokenSpaceName;
+
+ ///
+ /// tokenNumber is allocated by platform. tokenNumber indicate an index for this token in
+ /// platform token space.
+ /// tokenNumber is defined in SPD, FPD.
+ ///
+ public int tokenNumber;
+
+ ///
+ /// The token space name assigned by platform. For Non-DynamicEx driver this value is same.
+ /// assignedtokenSpaceName is defined in FPD.
+ ///
+ public UUID assignedtokenSpaceName;
+
+ ///
+ /// The token number assigned by platform. The number indiect the offset of this token in platform
+ /// token space.
+ /// AssgiendtokenNumber is defined in FPD.
+ ///
+ public int assignedtokenNumber;
+
+ ///
+ /// pcdType is the PCD item type defined by platform developer.
+ ///
+ public PCD_TYPE pcdType;
+
+ ///
+ /// PCDtype is set by platform developer. It is final PCD type of this token.
+ /// SupportedPcdType is defined in SPD.
+ ///
+ public PCD_TYPE[] supportedpcdType;
+
+ ///
+ /// datumSize is to descript the fix size or max size for this token.
+ /// datumSize is defined in SPD.
+ ///
+ public int datumSize;
+
+ ///
+ /// datum type is to descript what type can be expressed by a PCD token.
+ /// datumType is defined in SPD.
+ ///
+ public DATUM_TYPE datumType;
+
+ ///
+ /// Isplatform is to descript whether this token is defined in platform level.
+ /// If token is belong to platform level. The value can be different for every
+ /// module. All are determined by platform developer.
+ ///
+ public boolean isPlatform;
+
+ ///
+ /// hiiEnabled is to indicate whether the token support Hii functionality.
+ /// hiiEnabled is defined in FPD.
+ ///
+ public boolean hiiEnabled;
+
+ ///
+ /// variableName is valid only when this token support Hii functionality. variableName
+ /// indicates the value of token is associated with what variable.
+ /// variableName is defined in FPD.
+ ///
+ public String variableName;
+
+ ///
+ /// variableGuid is the GUID this token associated with.
+ /// variableGuid is defined in FPD.
+ ///
+ public UUID variableGuid;
+
+ ///
+ /// Variable offset indicate the associated variable's offset in NV storage.
+ /// variableOffset is defined in FPD.
+ ///
+ public int variableOffset;
+
+ ///
+ /// skuEnabled is to indicate whether the token support Sku functionality.
+ /// skuEnabled is defined in FPD.
+ ///
+ public boolean skuEnabled;
+
+ ///
+ /// skuDataArrayEnabled is to indicate wheter use the skuData array or default value.
+ ///
+ public boolean skuDataArrayEnabled;
+
+ ///
+ /// skuData contains all value for SkuNumber of token.
+ /// skuData is defined in FPD.
+ ///
+ public List<SkuInstance> skuData;
+
+ ///
+ /// maxSkuCount indicate the max count of sku data.
+ /// maxSkuCount is defined in FPD.
+ ///
+ public int maxSkuCount;
+
+ ///
+ /// SkuId is the id of current selected SKU.
+ /// SkuId is defined in FPD.
+ ///
+ public int skuId;
+
+ ///
+ /// datum is the value set by platform developer.
+ /// datum is defined in FPD.
+ ///
+ public Object datum;
+
+ ///
+ /// Default value of this token.
+ /// This default value is defined in SPD level.
+ ///
+ public Object defaultValue;
+
+ ///
+ /// BUGBUG: fix comment
+ /// vpdEnabled is defined in FPD.
+ ///
+ public boolean vpdEnabled;
+
+ ///
+ /// BUGBUG: fix comment
+ /// vpdOffset is defined in FPD.
+ ///
+ public long vpdOffset;
+
+ ///
+ /// producers array record all module private information who produce this PCD token.
+ ///
+ public List<UsageInstance> producers;
+
+ ///
+ /// consumers array record all module private information who consume this PCD token.
+ ///
+ public List<UsageInstance> consumers;
+
+ /**
+ Constructure function.
+
+ Initialize the value of token.
+
+ @param cName The cName of this token
+ @param tokenSpaceName The tokenSpaceName of this token, it is a GUID.
+ @param assignedtokenSpaceName The assignedtokenSpaceName of this token, it is a GUID.
+
+ **/
+ public Token(String cName, UUID tokenSpaceName, UUID assignedtokenSpaceName) {
+ UUID nullUUID = new UUID(0, 0);
+
+ this.cName = cName;
+ this.tokenSpaceName =(tokenSpaceName == null) ? nullUUID : tokenSpaceName;
+ this.assignedtokenSpaceName =(assignedtokenSpaceName == null) ? nullUUID : assignedtokenSpaceName;
+ this.tokenNumber = 0;
+ this.assignedtokenNumber = 0;
+ this.pcdType = PCD_TYPE.UNKNOWN;
+ this.supportedpcdType = null;
+ this.isPlatform = false;
+ this.datumType = DATUM_TYPE.UNKNOWN;
+ this.datumSize = -1;
+ this.defaultValue = null;
+ this.datum = null;
+ this.hiiEnabled = false;
+ this.variableGuid = null;
+ this.variableName = "";
+ this.variableOffset = -1;
+ this.skuEnabled = false;
+ this.skuDataArrayEnabled = false;
+ this.skuId = -1;
+ this.maxSkuCount = -1;
+ this.skuData = new ArrayList<SkuInstance>();
+ this.vpdEnabled = false;
+ this.vpdOffset = -1;
+
+ this.producers = new ArrayList<UsageInstance>();
+ this.consumers = new ArrayList<UsageInstance>();
+ }
+
+ /**
+ Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database
+
+ @param cName Token name.
+ @param tokenSpaceName The token space guid defined in MSA or SPD
+ @param platformtokenSpaceName The token space guid for current platform token space,
+
+ @return primary key for this token in token database.
+ **/
+ public static String getPrimaryKeyString(String cName, UUID tokenSpaceName,
+ UUID platformtokenSpaceName) {
+ UUID nullUUID = new UUID(0, 0);
+
+ if (platformtokenSpaceName == nullUUID) {
+ return cName + "-" + tokenSpaceName.toString();
+ } else {
+ return cName + "-" + platformtokenSpaceName.toString();
+ }
+ }
+
+ /**
+ Judge datumType is valid
+
+ @param type The datumType want to be judged.
+
+ @retval TRUE - The type is valid.
+ @retval FALSE - The type is invalid.
+ **/
+ public static boolean isValiddatumType(DATUM_TYPE type) {
+ if ((type.ordinal() < DATUM_TYPE.UINT8.ordinal() ) ||
+ (type.ordinal() > DATUM_TYPE.POINTER.ordinal())) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ Judge pcdType is valid
+
+ @param type The PCdType want to be judged.
+
+ @retval TRUE - The type is valid.
+ @retval FALSE - The type is invalid.
+ **/
+ public static boolean isValidpcdType(PCD_TYPE type) {
+ if ((type.ordinal() < PCD_TYPE.FEATURE_FLAG.ordinal() ) ||
+ (type.ordinal() > PCD_TYPE.DYNAMIC_EX.ordinal())) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ Add an usage instance for token
+
+ @param usageInstance The usage instance
+
+ @retval TRUE - Success to add usage instance.
+ @retval FALSE - Fail to add usage instance
+ **/
+ public boolean addUsageInstance(UsageInstance usageInstance) {
+ if (usageInstance.usage == PCD_USAGE.UNKNOWN) {
+ return false;
+ }
+
+ if ((usageInstance.usage == PCD_USAGE.ALWAYS_PRODUCED) ||
+ (usageInstance.usage == PCD_USAGE.SOMETIMES_PRODUCED)) {
+ producers.add(usageInstance);
+ } else {
+ consumers.add(usageInstance);
+ }
+ return true;
+ }
+
+ /**
+ Judge whether exist an usage instance for this token
+
+ @param moduleName Use xmlFilePath as keyword to search the usage instance
+
+ @retval PCD_USAGE - if UsageInstance exists.
+ @retval UNKNOWN - if UsageInstance does not exist, return UNKONW.
+ **/
+ public PCD_USAGE isUsageInstanceExist(String moduleName) {
+ int index;
+ UsageInstance usageInstance;
+
+ if (moduleName == null) {
+ ActionMessage.warning(this, "Error parameter for isUsageInstanceExist() function!");
+ return PCD_USAGE.UNKNOWN;
+ }
+
+ if (moduleName.length() == 0) {
+ return PCD_USAGE.UNKNOWN;
+ }
+
+ //
+ // Searching the usage instance in module's producer and consumer according to
+ // module's name.
+ //
+ for (index = 0; index < producers.size(); index ++) {
+ usageInstance =(UsageInstance)producers.get(index);
+ if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {
+ return usageInstance.usage;
+ }
+ }
+
+ for (index = 0; index < consumers.size(); index ++) {
+ usageInstance =(UsageInstance)consumers.get(index);
+ if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {
+ return usageInstance.usage;
+ }
+ }
+ return PCD_USAGE.UNKNOWN;
+ }
+
+ /**
+ Get usage instance according to a MSA file name
+
+ @param moduleName The file path string of MSA file.
+
+ @return usage instance object.
+ **/
+ public UsageInstance getUsageInstance(String moduleName) {
+ int usageIndex;
+ UsageInstance usageInstance;
+
+ if (moduleName == null) {
+ ActionMessage.warning(this, "Error parameter for isUsageInstanceExist() function!");
+ return null;
+ }
+
+ if (moduleName.length() == 0) {
+ return null;
+ }
+
+ if (producers.size() != 0) {
+ for (usageIndex = 0; usageIndex < producers.size(); usageIndex ++) {
+ usageInstance =(UsageInstance)producers.get(usageIndex);
+ if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {
+ return usageInstance;
+ }
+ }
+ }
+
+ if (consumers.size() != 0) {
+ for (usageIndex = 0; usageIndex < consumers.size(); usageIndex ++) {
+ usageInstance =(UsageInstance)consumers.get(usageIndex);
+ if (usageInstance.moduleName.equalsIgnoreCase(moduleName)) {
+ return usageInstance;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ Get the PCD_TYPE according to the string of PCD_TYPE
+
+ @param pcdTypeStr The string of PCD_TYPE
+
+ @return PCD_TYPE
+ **/
+ public static PCD_TYPE getpcdTypeFromString(String pcdTypeStr) {
+ if (pcdTypeStr == null) {
+ return PCD_TYPE.UNKNOWN;
+ }
+
+ if (pcdTypeStr.equalsIgnoreCase("FEATURE_FLAG")) {
+ return PCD_TYPE.FEATURE_FLAG;
+ } else if (pcdTypeStr.equalsIgnoreCase("FIXED_AT_BUILD")) {
+ return PCD_TYPE.FIXED_AT_BUILD;
+ } else if (pcdTypeStr.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {
+ return PCD_TYPE.PATCHABLE_IN_MODULE;
+ } else if (pcdTypeStr.equalsIgnoreCase("DYNAMIC")) {
+ return PCD_TYPE.DYNAMIC;
+ } else if (pcdTypeStr.equalsIgnoreCase("DYNAMIC_EX")) {
+ return PCD_TYPE.DYNAMIC_EX;
+ } else {
+ return PCD_TYPE.UNKNOWN;
+ }
+ }
+
+ /**
+ Get the string of given datumType. This string will be used for generating autogen files
+
+ @param datumType Given datumType
+
+ @return The string of datum type.
+ **/
+ public static String getStringOfdatumType(DATUM_TYPE datumType) {
+ switch (datumType) {
+ case UINT8:
+ return "UINT8";
+ case UINT16:
+ return "UINT16";
+ case UINT32:
+ return "UINT32";
+ case UINT64:
+ return "UINT64";
+ case POINTER:
+ return "POINTER";
+ case BOOLEAN:
+ return "BOOLEAN";
+ }
+ return "UNKNOWN";
+ }
+
+ /**
+ Get the datumType according to a string.
+
+ @param datumTypeStr The string of datumType
+
+ @return DATUM_TYPE
+ **/
+ public static DATUM_TYPE getdatumTypeFromString(String datumTypeStr) {
+ if (datumTypeStr.equalsIgnoreCase("UINT8")) {
+ return DATUM_TYPE.UINT8;
+ } else if (datumTypeStr.equalsIgnoreCase("UINT16")) {
+ return DATUM_TYPE.UINT16;
+ } else if (datumTypeStr.equalsIgnoreCase("UINT32")) {
+ return DATUM_TYPE.UINT32;
+ } else if (datumTypeStr.equalsIgnoreCase("UINT64")) {
+ return DATUM_TYPE.UINT64;
+ } else if (datumTypeStr.equalsIgnoreCase("VOID*")) {
+ return DATUM_TYPE.POINTER;
+ } else if (datumTypeStr.equalsIgnoreCase("BOOLEAN")) {
+ return DATUM_TYPE.BOOLEAN;
+ }
+ return DATUM_TYPE.UNKNOWN;
+ }
+
+ /**
+ Get string of given pcdType
+
+ @param pcdType The given PcdType
+
+ @return The string of PCD_TYPE.
+ **/
+ public static String getStringOfpcdType(PCD_TYPE pcdType) {
+ switch (pcdType) {
+ case FEATURE_FLAG:
+ return "FEATURE_FLAG";
+ case FIXED_AT_BUILD:
+ return "FIXED_AT_BUILD";
+ case PATCHABLE_IN_MODULE:
+ return "PATCHABLE_IN_MODULE";
+ case DYNAMIC:
+ return "DYNAMIC";
+ case DYNAMIC_EX:
+ return "DYNAMIC_EX";
+ }
+ return "UNKNOWN";
+ }
+
+ /**
+ Get the PCD_USAGE according to a string
+
+ @param usageStr The string of PCD_USAGE
+
+ @return The PCD_USAGE
+ **/
+ public static PCD_USAGE getUsageFromString(String usageStr) {
+ if (usageStr == null) {
+ return PCD_USAGE.UNKNOWN;
+ }
+
+ if (usageStr.equalsIgnoreCase("ALWAYS_PRODUCED")) {
+ return PCD_USAGE.ALWAYS_PRODUCED;
+ } else if (usageStr.equalsIgnoreCase("SOMETIMES_PRODUCED")) {
+ return PCD_USAGE.SOMETIMES_PRODUCED;
+ } else if (usageStr.equalsIgnoreCase("ALWAYS_CONSUMED")) {
+ return PCD_USAGE.ALWAYS_CONSUMED;
+ } else if (usageStr.equalsIgnoreCase("SOMETIMES_CONSUMED")) {
+ return PCD_USAGE.SOMETIMES_CONSUMED;
+ }
+
+ return PCD_USAGE.UNKNOWN;
+ }
+
+ /**
+ Get the string of given PCD_USAGE
+
+ @param usage The given PCD_USAGE
+
+ @return The string of PDC_USAGE.
+ **/
+ public static String getStringOfUsage(PCD_USAGE usage) {
+ switch (usage) {
+ case ALWAYS_PRODUCED:
+ return "ALWAYS_PRODUCED";
+ case ALWAYS_CONSUMED:
+ return "ALWAYS_CONSUMED";
+ case SOMETIMES_PRODUCED:
+ return "SOMETIMES_PRODUCED";
+ case SOMETIMES_CONSUMED:
+ return "SOMETIMES_CONSUMED";
+ }
+ return "UNKNOWN";
+ }
+
+ /**
+ Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h
+
+ @param datumType The given datumType
+
+ @return string of datum type for autogen.
+ **/
+ public static String GetAutogenDefinedatumTypeString(DATUM_TYPE datumType) {
+ switch (datumType) {
+
+ case UINT8:
+ return "8";
+ case UINT16:
+ return "16";
+ case BOOLEAN:
+ return "BOOL";
+ case POINTER:
+ return "PTR";
+ case UINT32:
+ return "32";
+ case UINT64:
+ return "64";
+ default:
+ return null;
+ }
+ }
+
+ /**
+ Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen
+
+ @param datumType The given datumType
+
+ @return string of datum type.
+ **/
+ public static String getAutogendatumTypeString(DATUM_TYPE datumType) {
+ switch (datumType) {
+ case UINT8:
+ return "UINT8";
+ case UINT16:
+ return "UINT16";
+ case UINT32:
+ return "UINT32";
+ case UINT64:
+ return "UINT64";
+ case POINTER:
+ return "VOID*";
+ case BOOLEAN:
+ return "BOOLEAN";
+ }
+ return null;
+ }
+
+ /**
+ Get the datumType string for generating some MACROs in autogen file of Library
+
+ @param datumType The given datumType
+
+ @return String of datum for genrating bit charater.
+ **/
+ public static String getAutogenLibrarydatumTypeString(DATUM_TYPE datumType) {
+ switch (datumType) {
+ case UINT8:
+ return "8";
+ case UINT16:
+ return "16";
+ case BOOLEAN:
+ return "Bool";
+ case POINTER:
+ return "Ptr";
+ case UINT32:
+ return "32";
+ case UINT64:
+ return "64";
+ default:
+ return null;
+ }
+ }
+
+ /**
+ UUID defined in Schems is object, this function is to tranlate this object
+ to UUID data.
+
+ @param uuidObj The object comes from schema.
+
+ @return The traslated UUID instance.
+ **/
+ public static UUID getGUIDFromSchemaObject(Object uuidObj) {
+ UUID uuid;
+ if (uuidObj.toString().equalsIgnoreCase("0")) {
+ uuid = new UUID(0,0);
+ } else {
+ uuid = UUID.fromString(uuidObj.toString());
+ }
+
+ return uuid;
+ }
+}
+
+
+
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java
new file mode 100644
index 0000000000..a11633d91b
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/entity/UsageInstance.java
@@ -0,0 +1,471 @@
+/** @file
+ UsageInstance class.
+
+ This class indicate an usage instance for a PCD token. This instance maybe a module
+ or platform setting. When a module produce or cosume a PCD token, then this module
+ is an usage instance for this PCD token.
+
+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.entity;
+
+
+import org.tianocore.build.pcd.exception.EntityException;
+import org.tianocore.build.pcd.action.ActionMessage;
+
+import org.tianocore.build.autogen.CommonDefinition;
+
+/**
+ This class indicate an usage instance for a PCD token. This instance maybe a module
+ or platform setting. When a module produce or cosume a PCD token, then this module
+ is an usage instance for this PCD token.
+**/
+public class UsageInstance {
+ ///
+ /// This parent that this usage instance belongs to.
+ ///
+ public Token parentToken;
+ ///
+ /// The usage of this token for platform or module.
+ ///
+ public Token.PCD_USAGE usage;
+ ///
+ /// Whether this usage instance inherit from library
+ ///
+ public boolean isInherit;
+ ///
+ /// The pcd type of this token for module.
+ ///
+ public Token.PCD_TYPE modulePcdType;
+ ///
+ /// The name of the module who contains this PCD.
+ ///
+ public String moduleName;
+ ///
+ /// The name of the package whose module contains this PCD.
+ ///
+ public String packageName;
+ ///
+ /// The component type for this usage instance.
+ ///
+ public int componentType;
+ ///
+ /// The default value defined in MSA has high prior than defined in SPD.
+ ///
+ public Object defaultValueInMSA;
+ ///
+ /// The default value defined in SPD.
+ ///
+ public Object defaultValueInSPD;
+ ///
+ /// Help text in MSA
+ ///
+ public String helpTextInMSA;
+ ///
+ /// Help text in SPD
+ ///
+ public String helpTextInSPD;
+ ///
+ /// Autogen string for header file.
+ ///
+ public String hAutogenStr;
+ /**
+ * Auotgen string for C code file.
+ */
+ public String cAutogenStr;
+
+ /**
+ Constructure function
+
+ @param parentToken Member variable.
+ @param usage Member variable.
+ @param pcdType Member variable.
+ @param componentType Member variable.
+ @param defaultValueInMSA Member variable.
+ @param defaultValueInSPD Member variable.
+ @param helpTextInMSA Member variable.
+ @param helpTextInSPD Member variable.
+ @param moduleName Member variable.
+ @param packageName Member variable.
+ @param isInherit Member variable.
+ **/
+ public UsageInstance(
+ Token parentToken,
+ Token.PCD_USAGE usage,
+ Token.PCD_TYPE pcdType,
+ int componentType,
+ Object defaultValueInMSA,
+ Object defaultValueInSPD,
+ String helpTextInMSA,
+ String helpTextInSPD,
+ String moduleName,
+ String packageName,
+ boolean isInherit
+ )
+ {
+ this.parentToken = parentToken;
+ this.usage = usage;
+ this.modulePcdType = pcdType;
+ this.componentType = componentType;
+ this.defaultValueInMSA = defaultValueInMSA;
+ this.defaultValueInSPD = defaultValueInSPD;
+ this.helpTextInMSA = helpTextInMSA;
+ this.helpTextInSPD = helpTextInSPD;
+ this.moduleName = moduleName;
+ this.packageName = packageName;
+ this.isInherit = isInherit;
+ }
+
+ /**
+ Generate autogen string for header file and C code file.
+
+ @throws EntityException Fail to generate.
+ **/
+ public void generateAutoGen() throws EntityException {
+ Object value = null;
+ int tokenNumber = 0;
+
+ hAutogenStr = "";
+ cAutogenStr = "";
+
+ value = this.parentToken.datum;
+
+ //
+ // If this pcd token's PCD_TYPE is DYNAMIC_EX, use itself token space name
+ // otherwices use assgined token space name from tool automatically.
+ //
+ if(parentToken.pcdType == Token.PCD_TYPE.DYNAMIC_EX) {
+ tokenNumber = parentToken.tokenNumber;
+ } else {
+ tokenNumber = parentToken.assignedtokenNumber;
+ }
+
+ hAutogenStr += String.format("#define _PCD_TOKEN_%s 0x%016x\r\n",
+ parentToken.cName, tokenNumber);
+
+ switch(modulePcdType) {
+ case FEATURE_FLAG:
+ //
+ // BUGBUG: The judegement of module PCD type and platform PCD type should not be
+ // done here, but in wizard tools, But here is just following something
+ // PcdEmulation driver.
+ //
+ if(parentToken.pcdType.ordinal() > Token.PCD_TYPE.FEATURE_FLAG.ordinal()) {
+ throw new EntityException(
+ String.format(
+ "%s:Platform PCD Type %d is not compatible with Module PCD Type %d\r\n",
+ parentToken.cName,
+ parentToken.pcdType.name(),
+ modulePcdType.name()
+ )
+ );
+ }
+
+ if(CommonDefinition.isLibraryComponent(componentType)) {
+ hAutogenStr += String.format(
+ "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n",
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n",
+ parentToken.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ } else {
+ hAutogenStr += String.format(
+ "#define _PCD_VALUE_%s %s\r\n",
+ parentToken.cName,
+ value.toString()
+ );
+ hAutogenStr += String.format(
+ "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n",
+ parentToken.cName
+ );
+ cAutogenStr += String.format(
+ "GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",
+ parentToken.cName,
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ }
+ break;
+ case FIXED_AT_BUILD:
+ //
+ // BUGBUG: The judegement of module PCD type and platform PCD type should not be
+ // done here, but in wizard tools, But here is just following something
+ // PcdEmulation driver.
+ //
+ if(parentToken.pcdType.ordinal() > Token.PCD_TYPE.FIXED_AT_BUILD.ordinal()) {
+ throw new EntityException(
+ String.format(
+ "%s:Platform PCD Type %d is not compatible with Module PCD Type %d\r\n",
+ parentToken.cName,
+ parentToken.pcdType.name(),
+ modulePcdType.name()
+ )
+ );
+ }
+
+ if(CommonDefinition.isLibraryComponent(componentType)) {
+ hAutogenStr += String.format(
+ "extern const %s _gPcd_FixedAtBuild_%s;\r\n",
+ Token.getAutogendatumTypeString(parentToken.datumType),
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ } else {
+ hAutogenStr += String.format(
+ "#define _PCD_VALUE_%s %s\r\n",
+ parentToken.cName,
+ value.toString()
+ );
+ hAutogenStr += String.format(
+ "extern const %s _gPcd_FixedAtBuild_%s;\r\n",
+ Token.getAutogendatumTypeString(parentToken.datumType),
+ parentToken.cName
+ );
+ cAutogenStr += String.format(
+ "GLOBAL_REMOVE_IF_UNREFERENCED const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",
+ Token.getAutogendatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ }
+ break;
+ case PATCHABLE_IN_MODULE:
+ //
+ // BUGBUG: The judegement of module PCD type and platform PCD type should not be
+ // done here, but in wizard tools, But here is just following something
+ // PcdEmulation driver.
+ //
+ if(parentToken.pcdType.ordinal() > Token.PCD_TYPE.PATCHABLE_IN_MODULE.ordinal()) {
+ throw new EntityException(
+ String.format(
+ "%s:Platform PCD Type %d is not compatible with Module PCD Type %d\r\n",
+ parentToken.cName,
+ parentToken.pcdType.name(),
+ modulePcdType.name()
+ )
+ );
+ }
+
+ if(CommonDefinition.isLibraryComponent(componentType)) {
+ hAutogenStr += String.format(
+ "extern %s _gPcd_BinaryPatch_%s;\r\n",
+ Token.getAutogendatumTypeString(parentToken.datumType),
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ } else {
+ hAutogenStr += String.format(
+ "#define _PCD_VALUE_%s %s\r\n",
+ parentToken.cName,
+ value
+ );
+ hAutogenStr += String.format(
+ "extern %s _gPcd_BinaryPatch_%s;\r\n",
+ Token.getAutogendatumTypeString(parentToken.datumType),
+ parentToken.cName
+ );
+ cAutogenStr += String.format(
+ "GLOBAL_REMOVE_IF_UNREFERENCED %s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;\r\n",
+ Token.getAutogendatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ }
+
+ break;
+ case DYNAMIC:
+ //
+ // BUGBUG: The judegement of module PCD type and platform PCD type should not be
+ // done here, but in wizard tools, But here is just following something
+ // PcdEmulation driver.
+ //
+ if(parentToken.pcdType.ordinal() > Token.PCD_TYPE.DYNAMIC.ordinal()) {
+ throw new EntityException(
+ String.format(
+ "%s:Platform PCD Type %d is not compatible with Module PCD Type %d\r\n",
+ parentToken.cName,
+ parentToken.pcdType.name(),
+ modulePcdType.name()
+ )
+ );
+ }
+
+ switch(parentToken.pcdType) {
+ case FEATURE_FLAG:
+ if(CommonDefinition.isLibraryComponent(componentType)) {
+ hAutogenStr += String.format(
+ "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n",
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ } else {
+ hAutogenStr += String.format(
+ "#define _PCD_VALUE_%s %s\r\n",
+ parentToken.cName,
+ value
+ );
+ hAutogenStr += String.format(
+ "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n",
+ parentToken.cName
+ );
+ cAutogenStr += String.format(
+ "const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",
+ parentToken.cName,
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ }
+ break;
+ case FIXED_AT_BUILD:
+ if(CommonDefinition.isLibraryComponent(componentType)) {
+ hAutogenStr += String.format(
+ "extern const %s _gPcd_FixedAtBuild_%s;\r\n",
+ Token.getAutogendatumTypeString(parentToken.datumType),
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _gPcd_FixedAtBuild_%s\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+
+ } else {
+ hAutogenStr += String.format(
+ "#define _PCD_VALUE_%s %s\r\n",
+ parentToken.cName,
+ value
+ );
+ hAutogenStr += String.format(
+ "extern const %s _gPcd_FixedAtBuild_%s\r\n",
+ Token.getAutogendatumTypeString(parentToken.datumType),
+ parentToken.cName
+ );
+ cAutogenStr += String.format(
+ "const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ }
+ break;
+ case PATCHABLE_IN_MODULE:
+ hAutogenStr += String.format(
+ "#define _PCD_VALUE_%s %s\r\n",
+ parentToken.cName,
+ value
+ );
+ hAutogenStr += String.format(
+ "extern %s _gPcd_BinaryPatch_%s;\r\n",
+ Token.getAutogendatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ cAutogenStr += String.format(
+ "%s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;",
+ Token.getAutogendatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ parentToken.cName
+ );
+ break;
+ case DYNAMIC:
+ hAutogenStr += String.format(
+ "#define _PCD_MODE_%s_%s LibPcdGet%s(_PCD_TOKEN_%s)\r\n",
+ Token.GetAutogenDefinedatumTypeString(parentToken.datumType),
+ parentToken.cName,
+ Token.getAutogenLibrarydatumTypeString(parentToken.datumType),
+ parentToken.cName
+ );
+ break;
+ default:
+ ActionMessage.log(
+ this,
+ "The PCD_TYPE setted by platform is unknown"
+ );
+ }
+ break;
+ case DYNAMIC_EX:
+ break;
+ }
+ }
+
+ /**
+ Get the autogen string for header file.
+
+ @return The string of header file.
+ **/
+ public String getHAutogenStr() {
+ return hAutogenStr;
+ }
+
+ /**
+ Get the autogen string for C code file.
+
+ @return The string of C Code file.
+ **/
+ public String getCAutogenStr() {
+ return cAutogenStr;
+ }
+}
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/BuildActionException.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/BuildActionException.java
new file mode 100644
index 0000000000..357ebf017a
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/BuildActionException.java
@@ -0,0 +1,33 @@
+/** @file
+ BuildActionException class.
+
+ BuildAction Exception deals with all build action exceptions.
+
+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.exception;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ BuildAction Exception deals with all build action exceptions.
+**/
+public class BuildActionException extends BuildException {
+ static final long serialVersionUID = -7034897190740066939L;
+ /**
+ Constructure function
+
+ @param reason exception message string.
+ **/
+ public BuildActionException(String reason) {
+ super(reason);
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java
new file mode 100644
index 0000000000..1e7ebfcbe1
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/EntityException.java
@@ -0,0 +1,31 @@
+/** @file
+ EntityException 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.pcd.exception;
+
+/**
+ The class handle the exception throwed by entity class.
+**/
+public class EntityException extends Exception {
+ static final long serialVersionUID = -8034897190740066939L;
+ /**
+ Constructure function
+
+ @param expStr exception message string.
+ **/
+ public EntityException(String expStr) {
+ super("[EntityException]:" + expStr);
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/UIException.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/UIException.java
new file mode 100644
index 0000000000..96575a1450
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/exception/UIException.java
@@ -0,0 +1,31 @@
+/** @file
+ UIException class.
+
+ The class handle the exception throwed by UI action 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.exception;
+
+/**
+ The class handle the exception throwed by UI action class.
+**/
+public class UIException extends Exception {
+ static final long serialVersionUID = -7034897190740066930L;
+ /**
+ Constructure function
+
+ @param reason exception message string.
+ **/
+ public UIException(String reason) {
+ super(reason);
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java b/Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java
new file mode 100644
index 0000000000..81eb63025b
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/pcd/ui/PCDDatabaseFrame.java
@@ -0,0 +1,184 @@
+/** @file
+ PCDDatabaseFrame class.
+
+ The class is the frame class for displaying PCD database in tree method.
+
+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.ui;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import org.tianocore.build.pcd.action.ActionMessage;
+import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
+import org.tianocore.build.pcd.entity.Token;
+import org.tianocore.build.pcd.entity.UsageInstance;
+
+/**
+ The class is the frame class for displaying PCD database in tree method.
+**/
+public class PCDDatabaseFrame extends JFrame {
+ static final long serialVersionUID = -7034897190740068939L;
+ ///
+ /// Database instance
+ ///
+ private MemoryDatabaseManager dbManager;
+ ///
+ /// The token and module tree
+ ///
+ private JTree databaseTree;
+
+ /**
+ Constructure function.
+
+ Create the UI component and display frame.
+
+ @param dbManager databaase manager instance.
+ **/
+ public PCDDatabaseFrame(MemoryDatabaseManager dbManager) {
+ if (dbManager != null) {
+ this.dbManager = dbManager;
+ }
+ //
+ // Put the frame into center of desktop.
+ //
+ setLocation(100, 100);
+ initializeComponent();
+
+ setTitle("PCD View Tool");
+ pack();
+ setVisible(true);
+ }
+
+ /**
+ Initliaze the UI component in Display frame.
+ **/
+ public void initializeComponent() {
+ JScrollPane scrollPane = new JScrollPane();
+ Container contentPane = getContentPane();
+
+ contentPane.setLayout(new BorderLayout());
+ scrollPane.setViewportView(initializeTree());
+ contentPane.add(scrollPane);
+
+ addWindowListener(new PCDDatabaseFrameAdapter());
+ }
+
+ /**
+ Initiliaze the TREE control.
+ **/
+ public JTree initializeTree() {
+ Token[] tokenArray = null;
+ Token token = null;
+ DefaultMutableTreeNode root = new DefaultMutableTreeNode(dbManager.getLogFileName());
+ DefaultMutableTreeNode rootByPCD = new DefaultMutableTreeNode("By PCD");
+ DefaultMutableTreeNode rootByModule = new DefaultMutableTreeNode("By Module");
+ DefaultMutableTreeNode tokenNode = null;
+ DefaultMutableTreeNode usageNode = null;
+ DefaultMutableTreeNode moduleNode = null;
+ java.util.List<String> moduleNames = null;
+ int index = 0;
+ int usageIndex = 0;
+ int moduleIndex = 0;
+ java.util.List<UsageInstance> usageArray = null;
+ UsageInstance usageInstance = null;
+
+ root.add(rootByPCD);
+ //
+ // By PCD Node
+ //
+
+ tokenArray = dbManager.getRecordArray();
+ for (index = 0; index < tokenArray.length; index ++) {
+ token = tokenArray[index];
+ ActionMessage.debug(this, token.cName);
+ tokenNode = new DefaultMutableTreeNode(token.cName);
+ tokenNode.add(new DefaultMutableTreeNode(String.format("TOKEN NUMBER: 0x%08x", token.tokenNumber)));
+ tokenNode.add(new DefaultMutableTreeNode(String.format("ASSIGNED TOKEN NUMBER: 0x%08x", token.assignedtokenNumber)));
+ tokenNode.add(new DefaultMutableTreeNode("TOKEN SPACE NAME: " + token.tokenSpaceName.toString()));
+ tokenNode.add(new DefaultMutableTreeNode("ASSIGNED TOKEN SPACE NAME: " + token.assignedtokenSpaceName.toString()));
+ tokenNode.add(new DefaultMutableTreeNode("PCD TYPE: " + Token.getStringOfpcdType(token.pcdType)));
+ tokenNode.add(new DefaultMutableTreeNode("DATUM TYPE: " +Token.getStringOfdatumType(token.datumType)));
+ tokenNode.add(new DefaultMutableTreeNode("DATUM: " + token.datum.toString()));
+ tokenNode.add(new DefaultMutableTreeNode("HIIENABLE: " +(token.hiiEnabled?"true":"false")));
+ tokenNode.add(new DefaultMutableTreeNode("VARIABLE NAME: " + token.variableName));
+ tokenNode.add(new DefaultMutableTreeNode("VARIABLE GUID: " + token.variableGuid.toString()));
+ tokenNode.add(new DefaultMutableTreeNode("SKUENABLE: " +(token.skuEnabled?"true":"false")));
+ tokenNode.add(new DefaultMutableTreeNode("SKUDATA ARRAY ENABLE: " +(token.skuDataArrayEnabled?"true":"false")));
+ tokenNode.add(new DefaultMutableTreeNode(String.format("SKUID: %d", token.skuId)));
+ tokenNode.add(new DefaultMutableTreeNode(String.format("MAX SKU COUNT: %d", token.maxSkuCount)));
+ tokenNode.add(new DefaultMutableTreeNode("VPDENABLE: " +(token.vpdEnabled?"true":"false")));
+
+ usageNode = new DefaultMutableTreeNode("PRODUCER");
+ tokenNode.add(usageNode);
+
+ //
+ // Prepare producer's leaf node
+ //
+
+ for (usageIndex = 0; usageIndex < token.producers.size(); usageIndex ++) {
+ usageNode.add(new DefaultMutableTreeNode(token.producers.get(usageIndex).moduleName));
+ }
+
+ //
+ // Prepare consumer's leaf node
+ //
+ usageNode = new DefaultMutableTreeNode("CONSUMER");
+ tokenNode.add(usageNode);
+
+ for (usageIndex = 0; usageIndex < token.consumers.size(); usageIndex ++) {
+ usageNode.add(new DefaultMutableTreeNode(token.consumers.get(usageIndex).moduleName));
+ }
+
+ rootByPCD.add(tokenNode);
+ }
+
+ //
+ // BY MODULE Node
+ //
+ root.add(rootByModule);
+ moduleNames = dbManager.getAllModuleArray();
+ for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {
+ ActionMessage.debug(this, "ModuleName:" + moduleNames.get(moduleIndex));
+ }
+ for (moduleIndex = 0; moduleIndex < moduleNames.size(); moduleIndex ++) {
+ moduleNode = new DefaultMutableTreeNode(moduleNames.get(moduleIndex));
+ usageArray = dbManager.getUsageInstanceArrayByModuleName(moduleNames.get(moduleIndex));
+ for (usageIndex = 0; usageIndex < usageArray.size(); usageIndex ++) {
+ usageInstance = usageArray.get(usageIndex);
+ usageNode = new DefaultMutableTreeNode(usageInstance.parentToken.cName);
+ usageNode.add(new DefaultMutableTreeNode("MODULE PCD TYPE: " + Token.getStringOfpcdType(usageInstance.modulePcdType)));
+ usageNode.add(new DefaultMutableTreeNode("HELP TEXT: " + usageInstance.helpTextInMSA));
+ usageNode.add(new DefaultMutableTreeNode("IS INHERIT: " +(usageInstance.isInherit?"true":"false")));
+ usageNode.add(new DefaultMutableTreeNode("USAGE: " + Token.getStringOfUsage(usageInstance.usage)));
+ moduleNode.add(usageNode);
+ }
+ rootByModule.add(moduleNode);
+ }
+
+ databaseTree = new JTree(root);
+ return databaseTree;
+ }
+}
+
+/**
+ The adatper class for PCDDatabaseFrame. This class instance many windows message
+ callback function.
+**/
+class PCDDatabaseFrameAdapter extends WindowAdapter {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java
new file mode 100644
index 0000000000..f48735966e
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java
@@ -0,0 +1,218 @@
+/** @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 java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+
+ 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 {
+
+ private static String confPath = ".";
+
+ /**
+ Public construct method.
+ **/
+ public ConfigReader () {
+ }
+
+ /**
+ Default filepath is ".".
+
+ @param filename the config file name like "target.txt"
+ @return the variables defined in file
+ **/
+ public static synchronized String[][] parse(String filename) {
+ return parse(confPath, filename);
+ }
+
+ /**
+ Get all variables defined in config file. the config file format is flat
+ with "A=B". If line started with '#' looks as comments.
+
+ @param confPath the path of config file
+ @param filename the file name of the config file
+ @return the variables defined in the config file
+ @throws BuildException
+ Config file's format is not valid
+ **/
+ public static synchronized String[][] parse(String confPath, String filename) throws BuildException {
+ try {
+ Map<String, String> map = new HashMap<String, String>(20);
+ File file = new File(confPath + File.separatorChar + filename);
+ FileReader reader = new FileReader(file);
+ BufferedReader in = new BufferedReader(reader);
+ String str;
+ while ((str = in.readLine()) != null) {
+ str = str.trim();
+ //
+ // if str is empty line or comments (start with '#')
+ //
+ if (str.equalsIgnoreCase("") || str.startsWith("#")) {
+ continue;
+ }
+ //
+ // if str without '=' or start with '='
+ //
+ if (str.indexOf('=') <= 0) {
+ continue;
+ }
+ //
+ // look as line "A = B"
+ //
+ int index = str.indexOf('=');
+ String key = str.substring(0, index).trim();
+ String value = str.substring(index + 1).trim();
+ //
+ // if key is existed, then update
+ //
+ if (map.containsKey(key)) {
+ map.remove(key);
+ }
+ map.put(key, value);
+ }
+ Set keyset = map.keySet();
+ Iterator iter = keyset.iterator();
+ String[][] result = new String[map.size()][2];
+ int i = 0;
+ while (iter.hasNext()) {
+ String key = (String) iter.next();
+ result[i][0] = key;
+ result[i++][1] = (String) map.get(key);
+ }
+ return result;
+ } catch (Exception e) {
+ throw new BuildException("Processor file [" + filename + "] error. \n" + e.getMessage());
+ }
+ }
+
+ /**
+ Parse global flags table. The format is like such(global flag name, value,
+ vendor_arch_cmd, [add flags], [sub flags]):
+
+ <pre>
+ # EFI_DEBUG
+ EFI_DEBUG YES MSFT_IA32_ASM ADD.["/Zi", "/DEBUG"]
+ EFI_DEBUG YES MSFT_IA32_CC ADD.["/Zi", "/Gm", "/D EFI_DEBUG"] SUB.["/nologo", "/WX"]
+ EFI_DEBUG YES MSFT_IA32_LINK ADD.["/DEBUG"]
+ EFI_DEBUG YES MSFT_NT32_CC ADD.["/DEBUG"]
+ </pre>
+
+ @param confPath the file path of config file
+ @param filename the file name of config file
+ @return the value list
+ @throws BuildException
+ Config file is not valid
+ **/
+ public static synchronized String[][] parseTable(String confPath,
+ String filename) throws BuildException {
+ try {
+ Vector<String[]> vector = new Vector<String[]>(20);
+ File file = new File(confPath + File.separatorChar + filename);
+ FileReader reader = new FileReader(file);
+ BufferedReader in = new BufferedReader(reader);
+ String str;
+ while ((str = in.readLine()) != null) {
+ str = str.trim();
+ //
+ // if str is empty line or comments (start with '#')
+ //
+ if (str.equalsIgnoreCase("") || str.startsWith("#")) {
+ continue;
+ }
+ String[] item = new String[5];
+ for(int i=0; i < item.length; i++){
+ item[i] = "";
+ }
+ //
+ // EFI_DEBUG YES MSFT_IA32_ASM ADD.["/Zi", "/DEBUG"]
+ // FLAGS: EFI_DEBUG
+ //
+ int index = str.indexOf(" ");
+ item[0] = str.substring(0, index);
+ str = str.substring(index + 1).trim();
+ //
+ // Setting: YES
+ //
+ index = str.indexOf(" ");
+ item[1] = str.substring(0, index);
+ str = str.substring(index + 1).trim();
+ //
+ // Vendor_Arch_Commandtype: MSFT_IA32_ASM
+ //
+ index = str.indexOf(" ");
+ item[2] = str.substring(0, index);
+ str = str.substring(index + 1).trim();
+ //
+ // Add or/and Sub
+ //
+ if (str.startsWith("ADD.")) {
+ index = str.indexOf("]");
+ if ( index > 0){
+ item[3] = str.substring(5, index);
+ str = str.substring(index + 1).trim();
+ }
+ }
+ else if(str.startsWith("SUB.")){
+ index = str.indexOf("]");
+ if ( index > 0){
+ item[4] = str.substring(5, index);
+ str = str.substring(index + 1).trim();
+ }
+ }
+ else {
+ throw new BuildException("File [" + filename + "] never conform to Global Flags Table format.");
+ }
+
+ if (str.startsWith("ADD.")) {
+ index = str.indexOf("]");
+ if ( index > 0){
+ item[3] = str.substring(5, index);
+ str = str.substring(index + 1).trim();
+ }
+ }
+ else if(str.startsWith("SUB.")){
+ index = str.indexOf("]");
+ if ( index > 0){
+ item[4] = str.substring(5, index);
+ str = str.substring(index + 1).trim();
+ }
+ }
+ vector.addElement(item);
+ }
+ String[][] result = new String[vector.size()][5];
+ for(int i=0; i < vector.size(); i++){
+ result[i] = (String[])vector.get(i);
+ }
+ return result;
+ } catch (Exception e) {
+ throw new BuildException("Processor file [" + filename + "] error. \n" + e.getMessage());
+ }
+ }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java
new file mode 100644
index 0000000000..e3010fccf4
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java
@@ -0,0 +1,529 @@
+/** @file
+ ToolChainFactory class.
+
+ ToolChainFactory class parse all config files and get STD_FLAGS, GLOBAL_FLAGS,
+ and also command path + name.
+
+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.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.io.File;
+
+import org.apache.tools.ant.Project;
+
+
+/**
+ This class parse all config files and get STD_FLAGS, GLOBAL_FLAGS, and also
+ command path + name.
+
+ @since GenBuild 1.0
+**/
+public class ToolChainFactory {
+ ///
+ /// list of Arch: EBC, ARM, IA32, X64, IPF, PPC
+ ///
+ public final static String[] arch = { "EBC", "ARM", "IA32", "X64", "IPF",
+ "PPC"};
+
+ ///
+ /// list of OS: Linux, Windows
+ ///
+ public final static String[] os = { "WINDOWS", "LINUX" };
+
+ ///
+ /// list of Command Type: CC, LIB, LINK, ASL, ASM, ASMLINK, PP
+ ///
+ public final static String[] commandType = { "CC", "LIB", "LINK", "ASL",
+ "ASM", "ASMLINK", "PP" };
+
+ ///
+ /// default command name for every command
+ ///
+ public final static String[][] defaultCmdName = { { "CC", "cl" },
+ { "LIB", "lib" }, { "LINK", "link" }, { "ASL", "iasl" },
+ { "ASM", "ml" }, { "ASMLINK", "link" }, { "PP", "cl" } };
+
+ private String confPath = ".";
+
+ private String toolChainName = "MSFT";
+
+ private String sTargetFilename = "target.txt";
+
+ private String sToolsdefFilename = "tools_def.txt";
+
+ private String sWorkspaceTarget = "WORKSPACE_TARGET";
+
+ private String sTargetArch = "TARGET_ARCH";
+
+ private HashMap<String,String[][]> filesMap = new HashMap<String,String[][]>();
+
+ private HashMap<String,String> globalFlagsMap = new HashMap<String,String>();
+
+ private String[][] globalFlagTable;
+
+ private String currentTarget = "RELEASE";
+
+ ///
+ /// toolchain array list all results by parsing config files
+ ///
+ public static String[][] toolchain = null;
+
+ /**
+ Public construct method.
+ **/
+ public ToolChainFactory () {
+ }
+
+ /**
+ Public construct method.
+
+ @param project current ANT Project.
+ **/
+ public ToolChainFactory (Project project) {
+ this.confPath = project.replaceProperties("${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "Conf");
+ }
+
+ /**
+ Public construct method.
+
+ @param confPath the path of config files
+ @param toolChainName TOOL_CHAIN name
+ **/
+ public ToolChainFactory (String confPath, String toolChainName) {
+ this.confPath = confPath;
+ //
+ // If set tool used the set one, otherwise use default one.
+ // toolChain used to define open tools define txt file.
+ //
+ if (toolChainName != null && toolChainName.length() > 0){
+ this.toolChainName = toolChainName;
+ }
+ }
+
+ /**
+ Parse all config files, following are the detail steps:
+
+ <ul>
+ <li>Parse target.txt file. This file define the current build TARGET
+ and supported ARCH list. </li>
+ <li>Parse tools_def.txt file. This file define every command name, path
+ and vendor. </li>
+ <li>For every supported ARCH and Command Type, find out STD_FLAGS,
+ GLOBAL_ADD_FLAGS, GLOBAL_SUB_FLAGS. </li>
+ </ul>
+
+ <p>Note that this method will be called only once during the whole build
+ process. </p>
+ **/
+ public void setupToolChain() {
+ if (toolchain != null) {
+ return ;
+ }
+ Map<String, String> map = new HashMap<String, String>(40);
+ //
+ // parse target.txt
+ //
+ String[][] target = ConfigReader.parse(confPath, sTargetFilename);
+ //
+ // get workspace_target and initialize global flags setting
+ //
+ currentTarget = getValue(sWorkspaceTarget, target);
+ parseGlobalSetting(currentTarget);
+ String[] archList = getArchs(getValue(sTargetArch, target));
+
+ //
+ // If user write the ${toolChain}_Tools_Def.txt use this one,
+ // otherwise used "tools_def.txt" file.
+ //
+ File tempFile = new File (confPath + File.separator + toolChainName.toLowerCase() + "_tools_def.txt");
+ if (tempFile.exists()){
+ sToolsdefFilename = toolChainName.toLowerCase() + "_tools_def.txt";
+ }
+
+ System.out.println("Tools definition file is: " + sToolsdefFilename);
+ //
+ // parse tools_def.txt
+ //
+ String[][] tools_def = ConfigReader.parse(confPath, sToolsdefFilename);
+ //
+ // for each arch find all command's path&name and flags
+ //
+ for (int i = 0; i < archList.length; i++) {
+ for (int j = 0; j < commandType.length; j++) {
+ //
+ // Path & Name
+ //
+ map.put(archList[i] + "_" + commandType[j], getAbsoluteCmdPath(
+ archList[i], commandType[j], tools_def));
+ //
+ // Flags: CMD_STD_FLAGS + CMD_GLOBAL_FLAGS + CMD_PROJ_FLAGS
+ // ARCH_CMD_STD_FLAGS
+ //
+ map.put(archList[i] + "_" + commandType[j] + "_STD_FLAGS",
+ getStdFlags(archList[i], commandType[j],
+ tools_def));
+ //
+ // Flags:ARCH_CMD_VENDOR or ARCH_VENDOR
+ //
+ map.put(archList[i]+ "_"+commandType[j]+"_VENDOR", getVendorFlag(archList[i],
+ commandType[j], tools_def));
+ //
+ // ARCH_CMD_GLOBAL_FLAGS
+ //
+ String[] globalFlags = getGlobalFlags(archList[i], commandType[j],
+ tools_def);
+ map.put(archList[i] + "_" + commandType[j] + "_GLOBAL_ADD_FLAGS",
+ globalFlags[0]);
+ map.put(archList[i] + "_" + commandType[j] + "_GLOBAL_SUB_FLAGS",
+ globalFlags[1]);
+ //
+ // ARCH_CMD_GLOBAL_FLAGS, default is "".
+ //
+ map.put(archList[i] + "_" + commandType[j] + "_PROJ_FLAGS", "");
+ }
+ map.put(archList[i]+"_VENDOR", getVendorFlag(archList[i], null, tools_def));
+ }
+ Set keyset = map.keySet();
+ Iterator iter = keyset.iterator();
+ String[][] result = new String[map.size()][2];
+ int i = 0;
+ while (iter.hasNext()) {
+ String key = (String) iter.next();
+ result[i][0] = key;
+ result[i++][1] = (String) map.get(key);
+ }
+ toolchain = result;
+ }
+
+ /**
+ Get the standard flags (STD_FLAGS) for specified arch and command type.
+
+ <ul>
+ <li>Find out Vendor that cmd Command Type with arch ARCH used. The
+ search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here
+ we suppose default Vendor is MSFT.</li>
+ <li>Search ${Vendor}_tools.txt file, and get the corrsponding flags.
+ </li>
+ </ul>
+
+ @param arch the ARCH
+ @param cmd the command type
+ @param map detail flags information of tools_def.txt
+ @return the standard flags of arch ARCH and cmd Command Type
+ **/
+ private String getStdFlags(String arch, String cmd, String[][] map) {
+ //
+ // first is to find out its Vendor in map
+ // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"
+ // Here we suppose default Vendor is MSFT.
+ //
+ String vendor = "MSFT";
+ String str;
+ if ((str = getValue(arch + "_" + cmd + "_VENDOR", map)) != null) {
+ vendor = str;
+ } else if ((str = getValue(arch + "_VENDOR", map)) != null) {
+ vendor = str;
+ }
+ //
+ // change to low letter
+ //
+ vendor = vendor.toLowerCase();
+ //
+ // parse the corresponding file and get arch_cmd value
+ //
+ String filename = vendor + "_tools.txt";
+ String[][] flagsMap;
+ if (filesMap.containsKey(filename)) {
+ flagsMap = (String[][]) filesMap.get(filename);
+ } else {
+ //
+ // read file and store in filesMap
+ //
+ flagsMap = ConfigReader.parse(confPath, vendor + "_tools.txt");
+ filesMap.put(filename, flagsMap);
+ }
+ if ((str = getValue(arch + "_" + cmd, flagsMap)) != null) {
+ return str;
+ }
+ return "";
+ }
+
+ /**
+ Get the global flags (GLOBAL_ADD_FLAGS & GLOBAL_SUB_FLAGS) for specified
+ arch and command type.
+
+ <ul>
+ <li>Find out Vendor that cmd Command Type with arch ARCH used. The
+ search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here
+ we suppose default Vendor is MSFT.</li>
+ <li>Search efi_flags_table.txt file, and get the corrsponding flags.
+ </li>
+ </ul>
+
+ @param arch the ARCH
+ @param cmd the command type
+ @param map detail flags information of tools_def.txt
+ @return two values, first is GLOBAL_ADD_FLAGS and another value is
+ GLOBAL_SUB_FLAGS
+ **/
+ private String[] getGlobalFlags(String arch, String cmd, String[][] map) {
+ String addStr = "";
+ String subStr = "";
+ //
+ // first is to find out its Vendor in map
+ // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"
+ // Here we suppose default Vendor is MSFT.
+ //
+ String vendor = "MSFT";
+ String str;
+ if ((str = getValue(arch + "_" + cmd + "_VENDOR", map)) != null) {
+ vendor = str;
+ } else if ((str = getValue(arch + "_VENDOR", map)) != null) {
+ vendor = str;
+ }
+ //
+ // parse global flags table
+ //
+ if (globalFlagTable == null) {
+ globalFlagTable = ConfigReader.parseTable(confPath, "efi_flags_table.txt");
+ }
+ for (int i=0; i < globalFlagTable.length; i++){
+ String[] item = globalFlagTable[i];
+ if (item[2].equalsIgnoreCase(vendor + "_" + arch + "_" + cmd)){
+ //
+ // if item[0] == item[1] is existed in globalFlagsMap
+ //
+ if (globalFlagsMap.containsKey(item[0])){
+ if( item[1].equalsIgnoreCase((String)globalFlagsMap.get(item[0]))){
+ addStr += item[3] + " ";
+ subStr += item[4] + " ";
+ }
+ }
+ }
+ }
+
+ return new String[]{addStr, subStr};
+ }
+
+ /**
+ Find out command path and command name.
+
+ <pre>
+ Command path searching sequence in tools_def.txt file:
+ Path: ARCH_CMD_PATH -> ARCH_PATH -> Set to "".
+
+ Command name searching sequence in tools_def.txt file:
+ Name: ARCH_CMD_NAME -> CMD_NAME -> Default Value.
+ </pre>
+
+ @param arch the ARCH
+ @param cmd the Command Type
+ @param map detail flags information of tools_def.txt
+ @return the absolute command path and name
+ **/
+ private String getAbsoluteCmdPath(String arch, String cmd, String[][] map) {
+ String path = "";
+ String name = "";
+ String str;
+ //
+ // find Path
+ //
+ if ((str = getValue(arch + "_" + cmd + "_PATH", map)) != null) {
+ path = str;
+ } else if ((str = getValue(arch + "_PATH", map)) != null) {
+ path = str;
+ }
+ //
+ // find Name
+ //
+ if ((str = getValue(arch + "_" + cmd + "_NAME", map)) != null) {
+ name = str;
+ } else if ((str = getValue(cmd + "_NAME", map)) != null) {
+ name = str;
+ } else {
+ name = getValue(cmd, defaultCmdName);
+ }
+ if (path.equalsIgnoreCase("")) {
+ return name;
+ }
+ return path + File.separatorChar + name;
+ }
+
+ /**
+ Find out all global flags value, such as EFI_DEBUG equal YES or NO. Here
+ are three type files: global_efi_flags.txt, ${TARGET}_efi_flags.txt,
+ my_efi_flags.txt. global_efi_flags.txt with the highest priority while
+ my_efi_flags.txt with the lowest priority.
+
+ <p>All global flags value will store in <code>globalFlagsMap</code> for
+ getGlobalFlags using. </p>
+
+ @param target current build TARGET value
+ **/
+ private void parseGlobalSetting(String target){
+ //
+ // parse global_efi_flags -> ${TARGET}_efi_flags -> my_efi_flags
+ // parse global_efi_flags
+ //
+ String[][] map = ConfigReader.parse(confPath, "global_efi_flags.txt");
+ for (int i = 0; i < map.length; i++){
+ if(globalFlagsMap.containsKey(map[i][0])){
+ globalFlagsMap.remove(map[i][0]);
+ }
+ globalFlagsMap.put(map[i][0], map[i][1]);
+ }
+ //
+ // parse ${TARGET}_efi_flags
+ //
+ map = ConfigReader.parse(confPath, target + "_efi_flags.txt");
+ for (int i = 0; i < map.length; i++){
+ if(globalFlagsMap.containsKey(map[i][0])){
+ globalFlagsMap.remove(map[i][0]);
+ }
+ globalFlagsMap.put(map[i][0], map[i][1]);
+ }
+ //
+ // parse my_efi_flags.txt
+ //
+ map = ConfigReader.parse(confPath, "my_efi_flags.txt");
+ for (int i = 0; i < map.length; i++){
+ if(globalFlagsMap.containsKey(map[i][0])){
+ globalFlagsMap.remove(map[i][0]);
+ }
+ globalFlagsMap.put(map[i][0], map[i][1]);
+ }
+ }
+
+ /**
+ Find value with key from map. If not found, return null.
+
+ <p>Note that default is case-insensitive</p>
+
+ @param key key value
+ @param map mapping information
+ @return the related value of key
+ **/
+ private String getValue(String key, String[][] map) {
+ return getValue(key, map, false);
+ }
+
+ /**
+ Find value with key from map. If not found, return null.
+
+ @param key key value
+ @param map mapping information
+ @param caseSensitive whether case sesitive or not
+ @return the related value of key
+ **/
+ private String getValue(String key, String[][] map, boolean caseSensitive) {
+ for (int i = 0; i < map.length; i++) {
+ if (caseSensitive) {
+ if (key.compareTo(map[i][0]) == 0) {
+ return map[i][1];
+ }
+ } else {
+ if (key.compareToIgnoreCase(map[i][0]) == 0) {
+ return map[i][1];
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ Find value with key from <code>toolchain</code>. If not found, return null.
+
+ @param key key value
+ @return the related value of key
+ **/
+ public static String getValue(String key){
+ for (int i = 0; i < toolchain.length; i++) {
+ if (key.compareToIgnoreCase(toolchain[i][0]) == 0) {
+ return toolchain[i][1];
+ }
+ }
+ return null;
+ }
+
+ /**
+ Get Arch list from a string separated with comma.
+
+ <pre>
+ For example:
+ If the arch string is "IA32, X64, EBC".
+ Then the result is {"IA32", "X64", "EBC"}.
+ </pre>
+
+ @param arch string separated with comma
+ @return Arch list
+ **/
+ public String[] getArchs(String arch) {
+ if (arch == null) {
+ return new String[0];
+ }
+ StringTokenizer st = new StringTokenizer(arch, " \t,");
+ String[] archs = new String[st.countTokens()];
+ int i = 0;
+ while (st.hasMoreTokens()) {
+ archs[i++] = st.nextToken().toUpperCase();
+ }
+ return archs;
+ }
+
+ /**
+ Get current target value.
+
+ @return current target value
+ **/
+ public String getCurrentTarget() {
+ return currentTarget;
+ }
+
+ /**
+ Find out Vendor that cmd Command Type with arch ARCH used. The
+ search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here
+ we suppose default Vendor is MSFT.
+
+ @param arch the ARCH
+ @param cmd the Command Type
+ @param map detail flags information of tools_def.txt
+ @return the related vendor name
+ **/
+ public String getVendorFlag (String arch, String cmdType, String[][] map){
+ //
+ // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"
+ // Here we suppose default Vendor is MSFT.
+ //
+ String str;
+ String vendor = "";
+ if (cmdType != null){
+ if ((str = getValue(arch + "_" + cmdType + "_VENDOR", map)) != null) {
+ vendor = str;
+ }else {
+ vendor = "";
+ }
+ }else if (arch != null){
+ if ((str = getValue(arch + "_VENDOR", map)) != null) {
+ vendor = str;
+ }else {
+ vendor = "";
+ }
+ }
+ return vendor;
+ }
+
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java
new file mode 100644
index 0000000000..04dab1c3e3
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java
@@ -0,0 +1,60 @@
+/** @file
+ ToolChainTask class.
+
+ ToolChainTask class's main fucntion is read all tool chain related config 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.toolchain;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ This class is an ANT task. The main function is to read all tool chain related
+ config files.
+
+ @since GenBuild 1.0
+**/
+public class ToolChainTask extends Task{
+
+ private String confPath = ".";
+
+ /**
+ Public construct method. It is necessary for ANT task.
+ **/
+ public ToolChainTask(){
+ }
+
+ /**
+ ANT task's entry point, will be called after init(). Using
+ <code>ToolChainFactory</code> to parse all config files, and
+ set TARGET property.
+
+ @throws BuildException
+ Config files are invalid.
+ **/
+ public void execute() throws BuildException {
+ String toolChain = getProject().getProperty("env.TOOL_CHAIN");
+ ToolChainFactory toolchain = new ToolChainFactory(confPath, toolChain);
+ toolchain.setupToolChain();
+ getProject().setProperty("TARGET", toolchain.getCurrentTarget());
+ }
+
+ /**
+ Set the path of config files.
+
+ @param confPath the path of config files
+ **/
+ public void setConfPath(String confPath) {
+ this.confPath = confPath;
+ }
+}