Initial import.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
bbahnsen
2006-04-21 22:54:32 +00:00
commit 878ddf1fc3
2651 changed files with 624620 additions and 0 deletions

View File

@@ -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

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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");
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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}"));
}
}
}
}

View File

@@ -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();
}
}

View File

@@ -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";
}
}
}

View File

@@ -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());
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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());
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}