Restructuring for better separation of Tool packages.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1674 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lhauch
2006-10-05 23:12:07 +00:00
parent 214b0d1914
commit feccee87a7
796 changed files with 32 additions and 32 deletions

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" >
<MsaHeader>
<ModuleName>GenBuild</ModuleName>
<ModuleType>TOOL</ModuleType>
<GuidValue>0FC76CF5-8ACF-49a7-82E9-EA5BE953CC48</GuidValue>
<Version>2.0</Version>
<Abstract>This is the EFI/Tiano Tool Resources Module</Abstract>
<Description>
This Module provides the EFI/Tiano Tools that are used to create EFI/Tiano
Modules and Platform Binary Files (PBF)
These tools require compilation only once if the Developer Workstation and
the Developer's choice of HOST tool chain are stable. If the developer
updates either the OS or the HOST tool chain, these tools should be rebuilt.
</Description>
<Copyright>Copyright 2005-2006, Intel Corporation</Copyright>
<License>
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.
</License>
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</MsaHeader>
<ModuleDefinitions>
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
<BinaryModule>false</BinaryModule>
<OutputFileBasename>NULL</OutputFileBasename>
</ModuleDefinitions>
<SourceFiles>
<Filename>build.xml</Filename>
<Filename>GenBuild.tasks</Filename>
<Filename>org/tianocore/build/autogen/AutoGen.java</Filename>
<Filename>org/tianocore/build/autogen/AutogenLibOrder.java</Filename>
<Filename>org/tianocore/build/autogen/CommonDefinition.java</Filename>
<Filename>org/tianocore/build/exception/AutoGenException.java</Filename>
<Filename>org/tianocore/build/exception/EdkException.java</Filename>
<Filename>org/tianocore/build/exception/GenBuildException.java</Filename>
<Filename>org/tianocore/build/exception/PcdAutogenException.java</Filename>
<Filename>org/tianocore/build/exception/TianoToolsException.java</Filename>
<Filename>org/tianocore/build/exception/XmlParseException.java</Filename>
<Filename>org/tianocore/build/FfsProcess.java</Filename>
<Filename>org/tianocore/build/FileProcess.java</Filename>
<Filename>org/tianocore/build/fpd/FpdParserTask.java</Filename>
<Filename>org/tianocore/build/fpd/PlatformBuildFileGenerator.java</Filename>
<Filename>org/tianocore/build/FrameworkBuildTask.java</Filename>
<Filename>org/tianocore/build/GenBuildTask.java</Filename>
<Filename>org/tianocore/build/global/DpFile.java</Filename>
<Filename>org/tianocore/build/global/DpFileList.java</Filename>
<Filename>org/tianocore/build/global/GenBuildLogger.java</Filename>
<Filename>org/tianocore/build/global/GlobalData.java</Filename>
<Filename>org/tianocore/build/global/OnDependency.java</Filename>
<Filename>org/tianocore/build/global/OutputManager.java</Filename>
<Filename>org/tianocore/build/global/Spd.java</Filename>
<Filename>org/tianocore/build/global/SurfaceAreaQuery.java</Filename>
<Filename>org/tianocore/build/global/VariableTask.java</Filename>
<Filename>org/tianocore/build/id/FpdModuleIdentification.java</Filename>
<Filename>org/tianocore/build/id/Identification.java</Filename>
<Filename>org/tianocore/build/id/ModuleIdentification.java</Filename>
<Filename>org/tianocore/build/id/PackageIdentification.java</Filename>
<Filename>org/tianocore/build/id/PlatformIdentification.java</Filename>
<Filename>org/tianocore/build/ModuleBuildFileGenerator.java</Filename>
<Filename>org/tianocore/build/OutputDirSetup.java</Filename>
<Filename>org/tianocore/build/pcd/action/CollectPCDAction.java</Filename>
<Filename>org/tianocore/build/pcd/action/PcdDatabase.java</Filename>
<Filename>org/tianocore/build/pcd/action/PCDAutoGenAction.java</Filename>
<Filename>org/tianocore/build/toolchain/ConfigReader.java</Filename>
<Filename>org/tianocore/build/toolchain/ToolChainAttribute.java</Filename>
<Filename>org/tianocore/build/toolchain/ToolChainConfig.java</Filename>
<Filename>org/tianocore/build/toolchain/ToolChainElement.java</Filename>
<Filename>org/tianocore/build/toolchain/ToolChainInfo.java</Filename>
<Filename>org/tianocore/build/toolchain/ToolChainKey.java</Filename>
<Filename>org/tianocore/build/toolchain/ToolChainMap.java</Filename>
<Filename>org/tianocore/build/toolchain/ToolChainTask.java</Filename>
<Filename>org/tianocore/build/tools/DefaultBuildFileGenerator.java</Filename>
<Filename>org/tianocore/build/tools/ModuleItem.java</Filename>
<Filename>org/tianocore/build/tools/PackageItem.java</Filename>
</SourceFiles>
</ModuleSurfaceArea>

View File

@ -0,0 +1,8 @@
FPDParser = org.tianocore.build.fpd.FpdParserTask
bl = org.tianocore.build.global.VariableTask
GenBuild = org.tianocore.build.GenBuildTask
FrameworkBuild = org.tianocore.build.FrameworkBuildTask
OnDependency = org.tianocore.build.global.OnDependency
sourcefiles = org.tianocore.build.global.DpFileList
targetfiles = org.tianocore.build.global.DpFileList
file = org.tianocore.build.global.DpFile

View File

@ -0,0 +1,54 @@
<?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="GenBuild" 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/Jars" includes="Common.jar"/>
<fileset dir="${WORKSPACE}/Tools/Jars" includes="PcdTools.jar"/>
<fileset dir="${env.XMLBEANS_HOME}/lib" includes="*.jar"/>
</path>
<property name="buildDir" value="build"/>
<property name="installLocation" value="${WORKSPACE}/Tools/Jars"/>
<target name="GenBuild" 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}"/>
<delete file="${installLocation}/GenBuild.jar"/>
<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,422 @@
/** @file
File is FfsProcess class which is used to get the corresponding FFS layout
information for driver module.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build;
import java.io.File;
import java.util.Vector;
import javax.xml.namespace.QName;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.xmlbeans.XmlCursor;
import org.tianocore.BuildOptionsDocument;
import org.tianocore.build.global.GlobalData;
import org.tianocore.build.global.SurfaceAreaQuery;
import org.tianocore.build.id.FpdModuleIdentification;
import org.tianocore.common.definitions.EdkDefinitions;
import org.tianocore.common.logger.EdkLog;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
<p><code>FfsProcess</code> is a class to find the corresponding FFS layout. </p>
<p>The FFS Layout is like following: </p>
<pre>
&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 {
private BuildOptionsDocument.BuildOptions.Ffs ffsXmlObject;
///
/// ANT script to call GenFfs
///
private Element ffsNode = null;
///
/// Module base name
///
private String basename;
///
/// Sections type: normal
///
private static int MODE_NONE = 0;
///
/// Sections type: compress
///
private static int MODE_COMPRESS = 1;
///
/// Sections type: guid-define
///
private static int MODE_GUID_DEFINED = 2;
///
/// mapping from section type to section output file extension
///
public static final String[][] sectionExt = EdkDefinitions.SectionTypeExtensions;
/**
search in the type, if componentType is listed in type, return true;
otherwise return false.
@param type a list supported component type separated by comma
@param componentType current module component type
@return whether componentType is one of type
**/
private boolean isMatch(String type, String componentType) {
String[] items = type.split("[ \t]*,[ \t]*");
for (int i = 0; i < items.length; i++) {
if (items[i].equalsIgnoreCase(componentType)) {
return true;
}
}
return false;
}
/**
Find the corresponding FFS layout in <code>FPD</code>.
@param buildType Current module's component type
@param project Ant project
@return whether find the corresponding FFS layout
@throws BuildException
If can't find FFS Layout in FPD.
**/
public boolean initSections(String buildType, Project project, FpdModuleIdentification fpdModuleId) throws BuildException {
//
// Try to find Ffs layout from FPD file
//
SurfaceAreaQuery saq = new SurfaceAreaQuery(GlobalData.getFpdBuildOptionsMap());
BuildOptionsDocument.BuildOptions.Ffs[] ffsArray = saq.getFpdFfs();
for (int i = 0; i < ffsArray.length; i++) {
if (isMatch(ffsArray[i].getFfsKey(), buildType)) {
ffsXmlObject = ffsArray[i];
return true;
}
}
//
// If FfsFormatKey is not null, report exception and fail build
// Otherwise report warning message
//
if (buildType == null) {
EdkLog.log(EdkLog.EDK_WARNING, "Warning: this module doesn't specify a FfsFormatKey. ");
} else {
throw new BuildException("Can't find the FfsFormatKey [" + buildType + "] attribute in the FPD file!");
}
return false;
}
/**
Recursive parse the FFS layout. Find out all section type here used.
@param document BaseName_build.xml Xml document
@param basename Module's base name
@param guid Module's GUID
@param targetFilename Module's final file name (GUID-BaseName.APP)
@return List of section type
**/
public String[] getGenSectionElements(Document document, String basename, String guid, String targetFilename) {
this.basename = basename;
if (ffsXmlObject == null) {
return new String[0];
}
Vector<String> sectionList = new Vector<String>();
XmlCursor cursor = null;
cursor = ffsXmlObject.newCursor();
int mode = MODE_NONE;
Element genffsfileEle = document.createElement("genffsfile");
genffsfileEle.setAttribute("outputDir", "${BIN_DIR}");
genffsfileEle.setAttribute("moduleType", "${MODULE_TYPE}");
genffsfileEle.setAttribute("BaseName", basename);
genffsfileEle.setAttribute("fileGuid", guid);
if (cursor.toFirstChild()) {
do {
if (cursor.getName().getLocalPart().equalsIgnoreCase("Attribute")) {
String name = cursor.getAttributeText(new QName("Name"));
String value = cursor.getAttributeText(new QName("Value"));
genffsfileEle.setAttribute(changeAttributeName(name), value);
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {
cursor.push();
dealSection(mode, document, genffsfileEle, cursor, sectionList);
cursor.pop();
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {
cursor.push();
dealSections(mode, document, genffsfileEle, cursor, sectionList);
cursor.pop();
}
} while (cursor.toNextSibling());
}
//
// Check dependency
//
Element outofdateEle = document.createElement("OnDependency");
Element sourceEle = document.createElement("sourcefiles");
String[] result = new String[sectionList.size()];
for (int i = 0; i < sectionList.size(); i++) {
result[i] = (String) sectionList.get(i);
Element pathEle = document.createElement("file");
pathEle.setAttribute("name", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename
+ getSectionExt(result[i]));
sourceEle.appendChild(pathEle);
}
outofdateEle.appendChild(sourceEle);
Element targetEle = document.createElement("targetfiles");
Element fileEle = document.createElement("file");
fileEle.setAttribute("name", "${BIN_DIR}" + File.separatorChar + targetFilename);
targetEle.appendChild(fileEle);
outofdateEle.appendChild(targetEle);
Element sequentialEle = document.createElement("sequential");
sequentialEle.appendChild(genffsfileEle);
outofdateEle.appendChild(sequentialEle);
ffsNode = outofdateEle;
return result;
}
/**
Change the attribute name. For example:
<pre>
Before change: FFS_ATTRIB_CHECKSUM
After change: ffsATTRIBCHECKSUM
</pre>
@param name Original attribute name
@return Changed attribute name
**/
private String changeAttributeName(String name) {
String[] strs = name.split("_");
String str = strs[0].toLowerCase();
for (int j = 1; j < strs.length; j++) {
str += strs[j];
}
return str;
}
/**
Recursively deal with Sections. If sections does not specify a type, then omit it.
@param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
@param doc Xml Document
@param root Root Node
@param cursor Current FFS layout cursor
@param list List of section type here used
**/
private void dealSections(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {
String type = cursor.getAttributeText(new QName("EncapsulationType"));
String toolName = cursor.getAttributeText(new QName("ToolName"));
String sectType = cursor.getAttributeText(new QName("SectionType"));
if (type == null && sectType == null) {
if (cursor.toFirstChild()) {
do {
if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {
cursor.push();
dealSection(mode, doc, root, cursor, list);
cursor.pop();
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {
cursor.push();
dealSections(mode, doc, root, cursor, list);
cursor.pop();
}
} while (cursor.toNextSibling());
}
return;
}
Element ele;
Element toolEle = null;
if (type.equalsIgnoreCase("COMPRESS") && (toolName == null || toolName.equalsIgnoreCase(""))) {
mode = MODE_COMPRESS;
//
// <gensection sectiontype="EFI_SECTION_COMPRESSION">
//
ele = doc.createElement("gensection");
ele.setAttribute("sectionType", "EFI_SECTION_COMPRESSION");
} else {
mode = MODE_GUID_DEFINED;
//
// <gensection sectiontype="EFI_SECTION_GUID_DEFINED">
//
ele = doc.createElement("gensection");
if (type != null) {
if (type.equalsIgnoreCase("COMPRESS")) {
ele.setAttribute("sectionType", "EFI_SECTION_COMPRESSION");
}else {
ele.setAttribute("sectiontype", "EFI_SECTION_GUID_DEFINED");
}
} else {
ele.setAttribute("sectiontype", sectType);
}
//
// <tool toolName="${OEMTOOLPATH}\toolname"
// outputPath = "${DEST_DIR_OUTPUT}">
//
toolEle = doc.createElement("tool");
if (toolName == null || toolName.equalsIgnoreCase("")) {
toolEle.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin"
+ File.separatorChar + "GenCRC32Section");
}else{
File toolExe = new File(toolName);
//
// If <Tool> element exist, add sub element under <tool> .
//
if (toolExe.isAbsolute()) {
toolEle.setAttribute("toolName", toolName);
} else {
toolEle.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin"
+ File.separatorChar + toolName);
}
}
toolEle.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");
ele.appendChild(toolEle);
}
if (cursor.toFirstChild()) {
do {
if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {
cursor.push();
if (toolEle == null) {
dealSection(mode, doc, ele, cursor, list);
} else {
dealSection(mode, doc, toolEle, cursor, list);
}
cursor.pop();
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {
cursor.push();
if (toolEle == null) {
dealSections(mode, doc, ele, cursor, list);
} else {
dealSections(mode, doc, toolEle, cursor, list);
}
cursor.pop();
}
} while (cursor.toNextSibling());
}
root.appendChild(ele);
}
/**
Recursively deal with section.
@param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
@param doc Xml Document
@param root Root Node
@param cursor Current FFS layout cursor
@param list List of section type here used
**/
private void dealSection(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {
String type = cursor.getAttributeText(new QName("SectionType"));
//
// Judge if file is specified? Yes, just use the file, else call Build Macro
// If fileName is null, means without FileNames specify in FPD file
//
String fileName = null;
cursor.push();
if (cursor.toFirstChild()) {
do {
if (cursor.getName().getLocalPart().equalsIgnoreCase("Filenames")) {
cursor.push();
if (cursor.toFirstChild()) {
do {
if (cursor.getName().getLocalPart().equalsIgnoreCase("Filename")) {
fileName = cursor.getTextValue();
}
} while (cursor.toNextSibling());
}
cursor.pop();
}
} while (cursor.toNextSibling());
}
cursor.pop();
if (fileName == null) {
list.addElement(type);
}
if (mode == MODE_GUID_DEFINED) {
//
// <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>
//
Element ele = doc.createElement("input");
if (fileName == null) {
ele.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));
} else {
ele.setAttribute("file", "${PLATFORM_DIR}" + File.separatorChar + fileName);
}
root.appendChild(ele);
} else {
//
// <sectFile fileName= "..."/>
//
Element ele = doc.createElement("sectFile");
if (fileName == null) {
ele.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));
} else {
ele.setAttribute("fileName", "${PLATFORM_DIR}" + File.separatorChar + fileName);
}
root.appendChild(ele);
}
}
/**
Get the corresponding section file suffix.
@param type Section type
@return Corresponding section file extension
**/
private String getSectionExt(String type) {
for (int i = 0; i < sectionExt.length; i++) {
if (sectionExt[i][0].equalsIgnoreCase(type)) {
return sectionExt[i][1];
}
}
return ".sec";
}
/**
Return the ANT script to call GenFfs Tool.
@return ANT script to call GenFfs Tool
**/
public Element getFfsNode() {
return ffsNode;
}
}

View File

@ -0,0 +1,263 @@
/** @file
File is FileProcess class which is used to generate ANT script to build
source files.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build;
import java.io.File;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
<p><code>FileProcess</code> is class to generate ANT script to build source
files.</p>
<p>If file does not specify file type, <code>FileProcess</code> will judge
by its extension. Following is the current supported extensions. </p>
<pre>
Source File Suffix File Type Description
.h CHeader C header file
.c CCode C source file
.inc ASMHeader Assembly header file
.asm ASM Assembly source file, usually for IA32 and X64 Arch and MSFT tool chain
.S ASM Assembly source file, usually for IPF Arch
.s ASM Assembly source file, usually for IA32 and X64 Arch and GCC tool chain
.uni UNI Unicode file
.vfr VFR Visual Forms Representation File
.fv FV Firmware Volume
.SEC FFS Firmware File System file
.PEI FFS Firmware File System file
.DXE FFS Firmware File System file
.APP FFS Firmware File System file
.FVI FFS Firmware File System file
.FFS FFS Firmware File System file
.bmp BMP Graphic File
.i PPCode IPF PreProcessor Code
</pre>
@since GenBuild 1.0
**/
public class FileProcess {
///
/// The mapping information about source suffix, result suffix, file type.
///
public final String[][] fileTypes = { {".h", "", "CHeader" },
{".c", "", "CCode" },
{".inc", "", "ASMHeader" },
{".asm", "", "ASM" },
{".S", "", "ASM" },
{".s", "", "ASM" },
{".uni", "", "UNI" },
{".vfr", "", "VFR" },
{".Vfr", "", "VFR" },
{".dxs", "", "DPX"},
{".fv", "", "FV" },
{".efi", "", "EFI" },
{".SEC", "", "FFS" },
{".PEI", "", "FFS" },
{".DXE", "", "FFS" },
{".APP", "", "FFS" },
{".FYI", "", "FFS" },
{".FFS", "", "FFS" },
{".bmp", "", "BMP" },
{".i", "", "PPCode"}};
///
/// Current ANT context.
///
private Project project;
///
/// Current module's include pathes
///
private String[] includes;
///
/// Xml Document.
///
private Document document;
///
/// The flag to ensure all unicode files build before others.
///
private boolean unicodeFirst = true;
///
/// The flag present whether current module contains Unicode files or not.
///
private boolean unicodeExist = false;
/**
Initialize the project, includes, sourceFiles, document members.
@param project ANT project
@param includes Module include pathes
@param sourceFiles Modules source files
@param document XML document
**/
public void init(Project project, String[] includes, Document document) {
this.document = document;
this.includes = includes;
this.project = project;
}
/**
Parse file without file type.
@param filename Source file name
@param root Root node
@param unicodeFirst whether build Unicode file firstly or not
**/
public synchronized void parseFile(String filename, Node root, boolean unicodeFirst) {
this.unicodeFirst = unicodeFirst;
parseFile(filename, root);
}
/**
Get whether current module contains Unicode files or not.
@return Whether current module contains Unicode files or not
**/
public boolean isUnicodeExist() {
return unicodeExist;
}
/**
Parse file.
@param filename Source file name
@param filetype Source file type
@param root Root node
@param unicodeFirst whether build Unicode file firstly or not
**/
public synchronized void parseFile(String filename, String filetype, Node root, boolean unicodeFirst) {
this.unicodeFirst = unicodeFirst;
parseFile(filename, filetype, root);
}
/**
Find out source file's type.
@param filename Source file name
@param root Root node
**/
public synchronized void parseFile(String filename, Node root) throws BuildException {
for (int i = 0; i < fileTypes.length; i++) {
if (filename.endsWith(fileTypes[i][0])) {
parseFile(filename, fileTypes[i][2], root);
return ;
}
}
}
/**
Parse file. If flag <code>unicodeFirst</code> is true, then build all
unicode files firstly.
<p>Note that AutoGen.c is processed specially. It's output path is always
<code>${DEST_DIR_OUTPUT}</code>, others are <code>${DEST_DIR_OUTPUT}</code>
and relative to module path. </p>
@param filename Source file name
@param filetype Source file type
@param root Root node
**/
public synchronized void parseFile(String filename, String filetype, Node root) {
if (unicodeFirst) {
if ( ! filetype.equalsIgnoreCase("UNI")){
return ;
}
unicodeExist= true;
} else {
if (filetype.equalsIgnoreCase("UNI")){
return ;
}
}
//
// If file is C or ASM header file, skip it
//
if (filetype.equalsIgnoreCase("CHeader") || filetype.equalsIgnoreCase("ASMHeader")) {
return;
}
//
// If file is pre-processor file, skip it
//
if (filetype.equalsIgnoreCase("PPCode")) {
return;
}
//
// If define CC_EXT in tools_def.txt file, the source file with
// different suffix is skipped
//
String toolsDefExtName = project.getProperty(filetype + "_EXT");
if (toolsDefExtName != null) {
String[] exts = toolsDefExtName.split(" ");
for (int i = 0; i < exts.length; i++) {
if ( ! filename.endsWith(exts[i])) {
return ;
}
}
}
String module_path = project.getProperty("MODULE_DIR");
File moduleFile = new File(module_path);
File sourceFile = new File(filename);
//
// If source file is AutoGen.c, then Filepath is .
//
String sourceFilepath = "";
String sourceFilename = "";
String sourceFileext = "";
if (sourceFile.getPath().endsWith("AutoGen.c")) {
sourceFilepath = ".";
sourceFilename = "AutoGen";
sourceFileext = ".c";
filetype = "AUTOGEN";
} else {
// sourceFile.
String str = sourceFile.getPath().substring(moduleFile.getPath().length() + 1);
int index = str.lastIndexOf(File.separatorChar);
sourceFilepath = ".";
if (index > 0) {
sourceFilepath = str.substring(0, index);
str = str.substring(index + 1);
}
sourceFilename = str;
index = str.lastIndexOf('.');
if (index > 0) {
sourceFilename = str.substring(0, index);
sourceFileext = str.substring(index);
}
}
// <Build_filetype FILEPATH="" FILENAME="" />
Element ele = document.createElement("Build_" + filetype);
ele.setAttribute("FILEPATH", sourceFilepath);
ele.setAttribute("FILENAME", sourceFilename);
ele.setAttribute("FILEEXT", sourceFileext.substring(1));
Element includesEle = document.createElement("EXTRA.INC");
for (int i = 0; i < includes.length; i++) {
Element includeEle = document.createElement("includepath");
includeEle.setAttribute("path", project.replaceProperties(includes[i]));
includesEle.appendChild(includeEle);
}
ele.appendChild(includesEle);
root.appendChild(ele);
}
}

View File

@ -0,0 +1,448 @@
/** @file FrameworkBuildTask.java
The file is ANT task to find MSA or FPD file and build them.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.tianocore.build.exception.AutoGenException;
import org.tianocore.build.exception.GenBuildException;
import org.tianocore.build.exception.PcdAutogenException;
import org.tianocore.build.exception.PlatformPcdPreprocessBuildException;
import org.tianocore.build.fpd.FpdParserForThread;
import org.tianocore.build.fpd.FpdParserTask;
import org.tianocore.build.global.GenBuildLogger;
import org.tianocore.build.global.GlobalData;
import org.tianocore.build.toolchain.ConfigReader;
import org.tianocore.build.toolchain.ToolChainInfo;
import org.tianocore.common.definitions.ToolDefinitions;
import org.tianocore.common.exception.EdkException;
import org.tianocore.common.logger.EdkLog;
/**
<p>
<code>FrameworkBuildTask</code> is an Ant task. The main function is finding
and processing a FPD or MSA file, then building a platform or stand-alone
module.
<p>
The task search current directory and find out all MSA and FPD files by file
extension. Base on ACTIVE_PLATFORM policy, decide to build a platform or a
stand-alone module. The ACTIVE_PLATFORM policy is:
<pre>
1. More than one MSA files, report error;
2. Only one MSA file, but ACTIVE_PLATFORM is not specified, report error;
3. Only one MSA file, and ACTIVE_PLATFORM is also specified, build this module;
4. No MSA file, and ACTIVE_PLATFORM is specified, build the active platform;
5. No MSA file, no ACTIVE_PLATFORM, and no FPD file, report error;
6. No MSA file, no ACTIVE_PLATFORM, and only one FPD file, build the platform;
7. No MSA file, no ACTIVE_PLATFORM, and more than one FPD files, list all platform
and let user choose one.
</pre>
<p>
Framework build task also parse target file [${WORKSPACE_DIR}/Tools/Conf/target.txt].
And load all system environment variables to Ant properties.
<p>
The usage for this task is :
<pre>
&lt;FrameworkBuild type="cleanall" /&gt;
</pre>
@since GenBuild 1.0
**/
public class FrameworkBuildTask extends Task{
private Set<File> buildFiles = new LinkedHashSet<File>();
private Set<File> fpdFiles = new LinkedHashSet<File>();
private Set<File> msaFiles = new LinkedHashSet<File>();
//
// This is only for none-multi-thread build to reduce overriding message
//
public static Hashtable<String, String> originalProperties = new Hashtable<String, String>();
String toolsDefFilename = ToolDefinitions.DEFAULT_TOOLS_DEF_FILE_PATH;
String targetFilename = ToolDefinitions.TARGET_FILE_PATH;
String dbFilename = ToolDefinitions.FRAMEWORK_DATABASE_FILE_PATH;
String activePlatform = null;
///
/// The flag to present current is multi-thread enabled
///
public static boolean multithread = false;
///
/// The concurrent thread number
///
public static int MAX_CONCURRENT_THREAD_NUMBER = 2;
///
/// there are three type: all (build), clean and cleanall
///
private String type = "all";
public void execute() throws BuildException {
//
// set Logger
//
GenBuildLogger logger = new GenBuildLogger(getProject());
EdkLog.setLogLevel(getProject().getProperty("env.LOGLEVEL"));
EdkLog.setLogger(logger);
try {
processFrameworkBuild();
} catch (PcdAutogenException e) {
//
// Add more logic process here
//
throw new BuildException(e.getMessage());
} catch (AutoGenException e) {
//
// Add more logic process here
//
throw new BuildException(e.getMessage());
} catch (PlatformPcdPreprocessBuildException e) {
//
// Add more logic process here
//
throw new BuildException(e.getMessage());
} catch (GenBuildException e) {
//
// Add more logic process here
//
throw new BuildException(e.getMessage());
} catch (EdkException e) {
//
// Add more logic process here
//
throw new BuildException(e.getMessage());
}
}
private void processFrameworkBuild() throws EdkException, GenBuildException, AutoGenException, PcdAutogenException, PlatformPcdPreprocessBuildException {
//
// Seach build.xml -> .FPD -> .MSA file
//
try {
//
// Gen Current Working Directory
//
File dummyFile = new File(".");
File cwd = dummyFile.getCanonicalFile();
File[] files = cwd.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) {
if (files[i].getName().equalsIgnoreCase("build.xml")) {
//
// First, search build.xml, if found, ANT call it
//
buildFiles.add(files[i]);
} else if (files[i].getName().endsWith(ToolDefinitions.FPD_EXTENSION)) {
//
// Second, search FPD file, if found, build it
//
fpdFiles.add(files[i]);
} else if (files[i].getName().endsWith(ToolDefinitions.MSA_EXTENSION)) {
//
// Third, search MSA file, if found, build it
//
msaFiles.add(files[i]);
}
}
}
} catch (IOException ex) {
BuildException buildException = new BuildException("Scanning current directory error. \n" + ex.getMessage());
buildException.setStackTrace(ex.getStackTrace());
throw buildException;
}
//
// Deal with all environment variable (Add them to properties)
//
backupSystemProperties();
//
// Read target.txt file
//
readTargetFile();
//
// Global Data initialization
//
File workspacePath = new File(getProject().getProperty("WORKSPACE"));
getProject().setProperty("WORKSPACE_DIR", workspacePath.getPath().replaceAll("(\\\\)", "/"));
GlobalData.initInfo(dbFilename, workspacePath.getPath(), toolsDefFilename);
//
// If find MSA file and ACTIVE_PLATFORM is set, build the module;
// else fail build.
// If without MSA file, and ACTIVE_PLATFORM is set, build the ACTIVE_PLATFORM.
// If ACTIVE_PLATFORM is not set, and only find one FPD file, build the platform;
// If find more than one FPD files, let user select one.
//
File buildFile = null;
if (msaFiles.size() > 1) {
throw new BuildException("Having more than one MSA file in a directory is not allowed!");
} else if (msaFiles.size() == 1 && activePlatform == null) {
throw new BuildException("If trying to build a single module, please set ACTIVE_PLATFORM in file [" + targetFilename + "]. ");
} else if (msaFiles.size() == 1 && activePlatform != null) {
//
// Build the single module
//
buildFile = msaFiles.toArray(new File[1])[0];
} else if (activePlatform != null) {
buildFile = new File(GlobalData.getWorkspacePath() + File.separatorChar + activePlatform);
} else if (fpdFiles.size() == 1) {
buildFile = fpdFiles.toArray(new File[1])[0];
} else if (fpdFiles.size() > 1) {
buildFile = intercommuniteWithUser();
}
//
// If there is no build files or FPD files or MSA files, stop build
//
else {
throw new BuildException("Can't find any FPD or MSA files in the current directory. ");
}
//
// Build every FPD files (PLATFORM build)
//
if (buildFile.getName().endsWith(ToolDefinitions.FPD_EXTENSION)) {
EdkLog.log(this, "Processing the FPD file [" + buildFile.getPath() + "] ..>> ");
//
// Iff for platform build will enable the multi-thread if set in target.txt
//
if (multithread && type.equalsIgnoreCase("all")) {
EdkLog.log(this, "Multi-thread build is enabled. ");
FpdParserForThread fpdParserForThread = new FpdParserForThread();
fpdParserForThread.setType(type);
fpdParserForThread.setProject(getProject());
fpdParserForThread.setFpdFile(buildFile);
fpdParserForThread.perform();
return ;
}
FpdParserTask fpdParserTask = new FpdParserTask();
fpdParserTask.setType(type);
fpdParserTask.setProject(getProject());
fpdParserTask.setFpdFile(buildFile);
fpdParserTask.perform();
//
// If cleanall delete the Platform_build.xml
//
if (type.compareTo("cleanall") == 0) {
File platformBuildFile =
new File(getProject().getProperty("BUILD_DIR")
+ File.separatorChar
+ getProject().getProperty("PLATFORM")
+ "_build.xml");
platformBuildFile.deleteOnExit();
}
}
//
// Build every MSA files (SINGLE MODULE BUILD)
//
else if (buildFile.getName().endsWith(ToolDefinitions.MSA_EXTENSION)) {
if (multithread) {
EdkLog.log(this, EdkLog.EDK_WARNING, "Multi-Thead do not take effect on Stand-Alone (Single) module build. ");
multithread = false;
}
File tmpFile = new File(GlobalData.getWorkspacePath() + File.separatorChar + activePlatform);
EdkLog.log(this, "Using the FPD file [" + tmpFile.getPath() + "] for the active platform. ");
EdkLog.log(this, "Processing the MSA file [" + buildFile.getPath() + "] ..>> ");
GenBuildTask genBuildTask = new GenBuildTask();
genBuildTask.setSingleModuleBuild(true);
genBuildTask.setType(type);
getProject().setProperty("PLATFORM_FILE", activePlatform);
if( !multithread) {
originalProperties.put("PLATFORM_FILE", activePlatform);
}
genBuildTask.setProject(getProject());
genBuildTask.setMsaFile(buildFile);
genBuildTask.perform();
}
}
/**
Transfer system environment variables to ANT properties. If system variable
already exiests in ANT properties, skip it.
**/
private void backupSystemProperties() {
Map<String, String> sysProperties = System.getenv();
Iterator<String> iter = sysProperties.keySet().iterator();
while (iter.hasNext()) {
String name = iter.next();
//
// If system environment variable is not in ANT properties, add it
//
if (getProject().getProperty(name) == null) {
getProject().setProperty(name, sysProperties.get(name));
}
}
Hashtable allProperties = getProject().getProperties();
Iterator piter = allProperties.keySet().iterator();
while (piter.hasNext()) {
String name = (String)piter.next();
originalProperties.put(new String(name), new String((String)allProperties.get(name)));
}
}
private File intercommuniteWithUser(){
File file = null;
if (fpdFiles.size() > 1) {
File[] allFiles = new File[fpdFiles.size()];
int index = 0;
Iterator<File> iter = fpdFiles.iterator();
while (iter.hasNext()) {
allFiles[index] = iter.next();
index++;
}
EdkLog.log(this, "Finding " + allFiles.length + " FPD files: ");
for (int i = 0; i < allFiles.length; i++) {
System.out.println("[" + (i + 1) + "]: " + allFiles[i].getName());
}
boolean flag = true;
EdkLog.log(this, "Please select one of the following FPD files to build:[1] ");
do{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String str = br.readLine();
if (str.trim().length() == 0) {
file = allFiles[0];
flag = false;
continue ;
}
int indexSelect = Integer.parseInt(str);
if (indexSelect <=0 || indexSelect > allFiles.length) {
EdkLog.log(this, "Please enter a number between [1.." + allFiles.length + "]:[1] ");
continue ;
} else {
file = allFiles[indexSelect - 1];
flag = false;
continue ;
}
} catch (Exception e) {
EdkLog.log(this, "Please enter a valid number:[1] ");
flag = true;
}
} while (flag);
} else if (fpdFiles.size() == 1) {
file = fpdFiles.toArray(new File[1])[0];
}
return file;
}
public void setType(String type) {
if (type.equalsIgnoreCase("clean") || type.equalsIgnoreCase("cleanall")) {
this.type = type.toLowerCase();
} else {
this.type = "all";
}
}
private void readTargetFile() throws EdkException{
String targetFile = getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + targetFilename;
String[][] targetFileInfo = ConfigReader.parse(targetFile);
//
// Get ToolChain Info from target.txt
//
ToolChainInfo envToolChainInfo = new ToolChainInfo();
String str = getValue(ToolDefinitions.TARGET_KEY_TARGET, targetFileInfo);
if (str == null || str.trim().equals("")) {
envToolChainInfo.addTargets("*");
} else {
envToolChainInfo.addTargets(str);
}
str = getValue(ToolDefinitions.TARGET_KEY_TOOLCHAIN, targetFileInfo);
if (str == null || str.trim().equals("")) {
envToolChainInfo.addTagnames("*");
} else {
envToolChainInfo.addTagnames(str);
}
str = getValue(ToolDefinitions.TARGET_KEY_ARCH, targetFileInfo);
if (str == null || str.trim().equals("")) {
envToolChainInfo.addArchs("*");
} else {
envToolChainInfo.addArchs(str);
}
GlobalData.setToolChainEnvInfo(envToolChainInfo);
str = getValue(ToolDefinitions.TARGET_KEY_TOOLS_DEF, targetFileInfo);
if (str != null && str.trim().length() > 0) {
toolsDefFilename = str;
}
str = getValue(ToolDefinitions.TARGET_KEY_ACTIVE_PLATFORM, targetFileInfo);
if (str != null && ! str.trim().equals("")) {
if ( ! str.endsWith(".fpd")) {
throw new BuildException("FPD file's extension must be \"" + ToolDefinitions.FPD_EXTENSION + "\"!");
}
activePlatform = str;
}
str = getValue(ToolDefinitions.TARGET_KEY_MULTIPLE_THREAD, targetFileInfo);
if (str != null && str.trim().equalsIgnoreCase("Enable")) {
multithread = true;
}
str = getValue(ToolDefinitions.TARGET_KEY_MAX_CONCURRENT_THREAD_NUMBER, targetFileInfo);
if (str != null ) {
try {
int threadNum = Integer.parseInt(str);
if (threadNum > 0) {
MAX_CONCURRENT_THREAD_NUMBER = threadNum;
}
} catch (Exception ex) {
}
}
}
private String getValue(String key, String[][] map) {
for (int i = 0; i < map[0].length; i++){
if (key.equalsIgnoreCase(map[0][i])) {
return map[1][i];
}
}
return null;
}
}

View File

@ -0,0 +1,840 @@
/** @file
This file is ANT task GenBuild.
The file is used to parse a specified Module, and generate its build time
ANT script build.xml, then call the the ANT script to build the module.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build;
import java.io.File;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Ant;
import org.apache.tools.ant.taskdefs.Property;
import org.apache.xmlbeans.XmlObject;
import org.tianocore.common.definitions.ToolDefinitions;
import org.tianocore.common.exception.EdkException;
import org.tianocore.common.logger.EdkLog;
import org.tianocore.build.autogen.AutoGen;
import org.tianocore.build.exception.AutoGenException;
import org.tianocore.build.exception.GenBuildException;
import org.tianocore.build.exception.PcdAutogenException;
import org.tianocore.build.exception.PlatformPcdPreprocessBuildException;
import org.tianocore.build.fpd.FpdParserTask;
import org.tianocore.build.global.GlobalData;
import org.tianocore.build.global.OutputManager;
import org.tianocore.build.global.SurfaceAreaQuery;
import org.tianocore.build.id.FpdModuleIdentification;
import org.tianocore.build.id.ModuleIdentification;
import org.tianocore.build.id.PackageIdentification;
import org.tianocore.build.id.PlatformIdentification;
import org.tianocore.build.tools.ModuleItem;
/**
<p>
<code>GenBuildTask</code> is an ANT task that can be used in ANT build
system.
<p>The main function of this task is to parse module's surface area (MSA),
then generate the corresponding <em>BaseName_build.xml</em> (the real ANT
build script) and call this to build the module. The whole process including:
<pre>
1. generate AutoGen.c and AutoGen.h;
2. build all dependent library instances;
3. build all source files inlcude AutoGen.c;
4. generate sections;
5. generate FFS file if it is driver module while LIB file if it is Library module.
</pre>
<p>
The usage is (take module <em>HelloWorld</em> for example):
</p>
<pre>
&lt;GenBuild
msaFile="${PACKAGE_DIR}/Application/HelloWorld/HelloWorld.msa"
type="cleanall" /&gt;
</pre>
<p>
This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and
<em>AutoGen.h</em>.
</p>
<p>
This task will also set properties for current module, such as PACKAGE,
PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
(relative to Workspace), MODULE or BASE_NAME, GUID, VERSION, MODULE_DIR,
MODULE_RELATIVE_DIR (relative to Package), CONFIG_DIR, BIN_DIR,
DEST_DIR_DEBUG, DEST_DIR_OUTPUT, TARGET, ARCH, TOOLCHAIN, TOOLCHAIN_FAMILY,
SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH, all compiler command related
properties (CC, CC_FLAGS, CC_DPATH, CC_SPATH, CC_FAMILY, CC_EXT).
</p>
@since GenBuild 1.0
**/
public class GenBuildTask extends Ant {
///
/// Module surface area file.
///
File msaFile;
public ModuleIdentification parentId;
private String type = "all";
///
/// Module's Identification.
///
private ModuleIdentification moduleId;
private Vector<Property> properties = new Vector<Property>();
private boolean isSingleModuleBuild = false;
private SurfaceAreaQuery saq = null;
/**
Public construct method. It is necessary for ANT task.
**/
public GenBuildTask() {
}
/**
@throws BuildException
From module build, exception from module surface area invalid.
**/
public void execute() throws BuildException {
this.setTaskName("GenBuild");
try {
processGenBuild();
} catch (PcdAutogenException e) {
//
// Add more logic process here
//
throw new BuildException(e.getMessage());
} catch (AutoGenException e) {
//
// Add more logic process here
//
throw new BuildException(e.getMessage());
} catch (PlatformPcdPreprocessBuildException e) {
//
// Add more logic process here
//
throw new BuildException(e.getMessage());
} catch (GenBuildException e) {
//
// Add more logic process here
//
throw new BuildException(e.getMessage());
} catch (EdkException e) {
//
// Add more logic process here
//
throw new BuildException(e.getMessage());
}
}
private void processGenBuild() throws EdkException, BuildException, GenBuildException, AutoGenException, PcdAutogenException, PlatformPcdPreprocessBuildException {
if (!FrameworkBuildTask.multithread) {
cleanupProperties();
}
//
// Enable all specified properties
//
Iterator<Property> iter = properties.iterator();
while (iter.hasNext()) {
Property item = iter.next();
getProject().setProperty(item.getName(), item.getValue());
}
//
// GenBuild should specify either msaFile or moduleGuid & packageGuid
//
if (msaFile == null ) {
String moduleGuid = getProject().getProperty("MODULE_GUID");
String moduleVersion = getProject().getProperty("MODULE_VERSION");
String packageGuid = getProject().getProperty("PACKAGE_GUID");
String packageVersion = getProject().getProperty("PACKAGE_VERSION");
//
// If one of module Guid or package Guid is not specified, report error
//
if (moduleGuid == null || packageGuid == null) {
throw new BuildException("GenBuild parameter error.");
}
PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);
GlobalData.refreshPackageIdentification(packageId);
moduleId = new ModuleIdentification(moduleGuid, moduleVersion);
moduleId.setPackage(packageId);
GlobalData.refreshModuleIdentification(moduleId);
Map<String, XmlObject> doc = GlobalData.getNativeMsa(moduleId);
saq = new SurfaceAreaQuery(doc);
} else {
Map<String, XmlObject> doc = GlobalData.getNativeMsa(msaFile);
saq = new SurfaceAreaQuery(doc);
moduleId = saq.getMsaHeader();
moduleId.setMsaFile(msaFile);
}
String[] producedLibraryClasses = saq.getLibraryClasses("ALWAYS_PRODUCED",null);
if (producedLibraryClasses.length == 0) {
moduleId.setLibrary(false);
} else {
moduleId.setLibrary(true);
}
//
// Judge whether it is single module build or not
//
if (isSingleModuleBuild) {
//
// Single Module build
//
prepareSingleModuleBuild();
}
//
// If single module : get arch from pass down, otherwise intersection MSA
// supported ARCHs and tools def
//
Set<String> archListSupByToolChain = new LinkedHashSet<String>();
String[] archs = GlobalData.getToolChainInfo().getArchs();
for (int i = 0; i < archs.length; i ++) {
archListSupByToolChain.add(archs[i]);
}
Set<String> archSet = new LinkedHashSet<String>();
if ( getProject().getProperty("ARCH") != null) {
String[] fpdArchList = getProject().getProperty("ARCH").split(" ");
for (int i = 0; i < fpdArchList.length; i++) {
if (archListSupByToolChain.contains(fpdArchList[i])) {
archSet.add(fpdArchList[i]);
}
}
} else {
archSet = archListSupByToolChain;
}
String[] archList = archSet.toArray(new String[archSet.size()]);
//
// Judge if arch is all supported by current module. If not, throw Exception.
//
List moduleSupportedArchs = saq.getModuleSupportedArchs();
if (moduleSupportedArchs != null) {
for (int k = 0; k < archList.length; k++) {
if ( ! moduleSupportedArchs.contains(archList[k])) {
throw new BuildException("Specified architecture [" + archList[k] + "] is not supported by " + moduleId + ". The module " + moduleId + " only supports [" + moduleSupportedArchs + "] architectures.");
}
}
}
for (int k = 0; k < archList.length; k++) {
getProject().setProperty("ARCH", archList[k]);
FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]);
//
// Whether the module is built before
//
if (moduleId.isLibrary() == false && GlobalData.hasFpdModuleSA(fpdModuleId) == false) {
EdkLog.log(this, EdkLog.EDK_WARNING, "Warning: " + moduleId + " for " + archList[k] + " was not found in current platform FPD file!\n");
continue;
} else if (GlobalData.isModuleBuilt(fpdModuleId)) {
break;
} else {
GlobalData.registerBuiltModule(fpdModuleId);
}
//
// For Every TOOLCHAIN, TARGET
//
String[] targetList = GlobalData.getToolChainInfo().getTargets();
for (int i = 0; i < targetList.length; i ++){
//
// Prepare for target related common properties
// TARGET
//
getProject().setProperty("TARGET", targetList[i]);
String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
for(int j = 0; j < toolchainList.length; j ++){
//
// check if any tool is defined for current target + toolchain + arch
// don't do anything if no tools found
//
if (GlobalData.isCommandSet(targetList[i], toolchainList[j], archList[k]) == false) {
EdkLog.log(this, EdkLog.EDK_WARNING, "Warning: No build issued. No tools were found for [target=" + targetList[i] + " toolchain=" + toolchainList[j] + " arch=" + archList[k] + "]\n");
continue;
}
//
// Prepare for toolchain related common properties
// TOOLCHAIN
//
getProject().setProperty("TOOLCHAIN", toolchainList[j]);
EdkLog.log(this, "Build " + moduleId + " start >>>");
EdkLog.log(this, "Target: " + targetList[i] + " Tagname: " + toolchainList[j] + " Arch: " + archList[k]);
saq.push(GlobalData.getDoc(fpdModuleId));
//
// Prepare for all other common properties
// PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
// MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE
// MODULE_DIR, MODULE_RELATIVE_DIR
// SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH
//
setModuleCommonProperties(archList[k]);
//
// OutputManage prepare for
// BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR
//
OutputManager.getInstance().update(getProject());
if (type.equalsIgnoreCase("all") || type.equalsIgnoreCase("build")) {
applyBuild(targetList[i], toolchainList[j], fpdModuleId);
} else if (type.equalsIgnoreCase("clean")) {
applyClean(fpdModuleId);
} else if (type.equalsIgnoreCase("cleanall")) {
applyCleanall(fpdModuleId);
}
}
}
}
}
/**
This method is used to prepare Platform-related information.
<p>In Single Module Build mode, platform-related information is not ready.
The method read the system environment variable <code>ACTIVE_PLATFORM</code>
and search in the Framework Database. Note that platform name in the Framework
Database must be unique. </p>
**/
private void prepareSingleModuleBuild() throws EdkException {
//
// Find out the package which the module belongs to
//
PackageIdentification packageId = GlobalData.getPackageForModule(moduleId);
GlobalData.refreshPackageIdentification(packageId);
moduleId.setPackage(packageId);
GlobalData.refreshModuleIdentification(moduleId);
//
// Read ACTIVE_PLATFORM's FPD file
//
String filename = getProject().getProperty("PLATFORM_FILE");
if (filename == null){
throw new BuildException("Please set ACTIVE_PLATFORM in the file: Tools/Conf/target.txt if you want to build a single module!");
}
PlatformIdentification platformId = GlobalData.getPlatform(filename);
//
// Read FPD file (Call FpdParserTask's method)
//
FpdParserTask fpdParser = new FpdParserTask();
fpdParser.setProject(getProject());
fpdParser.parseFpdFile(platformId.getFpdFile());
getProject().setProperty("ARCH", fpdParser.getAllArchForModule(moduleId));
}
private void cleanupProperties() {
Project newProject = new Project();
Hashtable<String, String> passdownProperties = FrameworkBuildTask.originalProperties;
Iterator<String> iter = passdownProperties.keySet().iterator();
while (iter.hasNext()) {
String item = iter.next();
newProject.setProperty(item, passdownProperties.get(item));
}
newProject.setInputHandler(getProject().getInputHandler());
Iterator listenerIter = getProject().getBuildListeners().iterator();
while (listenerIter.hasNext()) {
newProject.addBuildListener((BuildListener) listenerIter.next());
}
getProject().initSubProject(newProject);
setProject(newProject);
}
/**
Set Module-Related information to properties.
@param arch current build ARCH
**/
private void setModuleCommonProperties(String arch) {
//
// Prepare for all other common properties
// PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
//
PackageIdentification packageId = moduleId.getPackage();
getProject().setProperty("PACKAGE", packageId.getName());
getProject().setProperty("PACKAGE_GUID", packageId.getGuid());
getProject().setProperty("PACKAGE_VERSION", packageId.getVersion());
getProject().setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/"));
getProject().setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/"));
//
// MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE
// MODULE_DIR, MODULE_RELATIVE_DIR
//
getProject().setProperty("MODULE", moduleId.getName());
String baseName = saq.getModuleOutputFileBasename();
if (baseName == null) {
getProject().setProperty("BASE_NAME", moduleId.getName());
} else {
getProject().setProperty("BASE_NAME", baseName);
}
getProject().setProperty("GUID", moduleId.getGuid());
getProject().setProperty("FILE_GUID", moduleId.getGuid());
getProject().setProperty("VERSION", moduleId.getVersion());
getProject().setProperty("MODULE_TYPE", moduleId.getModuleType());
getProject().setProperty("MODULE_DIR", moduleId.getMsaFile().getParent().replaceAll("(\\\\)", "/"));
getProject().setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/"));
//
// SUBSYSTEM
//
String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},
{ "SEC", "EFI_BOOT_SERVICE_DRIVER" },
{ "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" },
{ "PEIM", "EFI_BOOT_SERVICE_DRIVER" },
{ "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },
{ "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
{ "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" },
{ "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
{ "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
{ "TOOL", "EFI_BOOT_SERVICE_DRIVER" },
{ "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
{ "UEFI_APPLICATION", "EFI_APPLICATION" },
{ "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} };
String subsystem = "EFI_BOOT_SERVICE_DRIVER";
for (int i = 0; i < subsystemMap.length; i++) {
if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) {
subsystem = subsystemMap[i][1];
break ;
}
}
getProject().setProperty("SUBSYSTEM", subsystem);
//
// ENTRYPOINT
//
if (arch.equalsIgnoreCase("EBC")) {
getProject().setProperty("ENTRYPOINT", "EfiStart");
} else {
getProject().setProperty("ENTRYPOINT", "_ModuleEntryPoint");
}
getProject().setProperty("OBJECTS", "");
}
private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException {
String[] cmd = GlobalData.getToolChainInfo().getCommands();
for ( int m = 0; m < cmd.length; m++) {
//
// Set cmd, like CC, DLINK
//
String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_PATH;
String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME;
String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);
File cmdFile = new File(cmdPath + File.separatorChar + cmdName);
getProject().setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));
//
// set CC_FLAGS
//
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS;
String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);
if (cmdFlags != null)
{
// Set<String> addset = new LinkedHashSet<String>();
// Set<String> subset = new LinkedHashSet<String>();
// putFlagsToSet(addset, cmdFlags);
// getProject().setProperty(cmd[m] + "_FLAGS", getProject().replaceProperties(getFlags(addset, subset)));
getProject().setProperty(cmd[m] + "_FLAGS", cmdFlags);
}
else
{
getProject().setProperty(cmd[m] + "_FLAGS", "");
}
//
// Set CC_EXT
//
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_EXT;
String extName = GlobalData.getCommandSetting(key, fpdModuleId);
if ( extName != null && ! extName.equalsIgnoreCase("")) {
getProject().setProperty(cmd[m] + "_EXT", extName);
} else {
getProject().setProperty(cmd[m] + "_EXT", "");
}
//
// set CC_FAMILY
//
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY;
String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);
if (toolChainFamily != null) {
getProject().setProperty(cmd[m] + "_FAMILY", toolChainFamily);
}
//
// set CC_SPATH
//
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_SPATH;
String spath = GlobalData.getCommandSetting(key, fpdModuleId);
if (spath != null) {
getProject().setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));
} else {
getProject().setProperty(cmd[m] + "_SPATH", "");
}
//
// set CC_DPATH
//
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_DPATH;
String dpath = GlobalData.getCommandSetting(key, fpdModuleId);
if (dpath != null) {
getProject().setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));
} else {
getProject().setProperty(cmd[m] + "_DPATH", "");
}
}
}
public void setMsaFile(File msaFile) {
this.msaFile = msaFile;
}
/**
Method is for ANT to initialize MSA file.
@param msaFilename MSA file name
**/
public void setMsaFile(String msaFilename) {
String moduleDir = getProject().getProperty("MODULE_DIR");
//
// If is Single Module Build, then use the Base Dir defined in build.xml
//
if (moduleDir == null) {
moduleDir = getProject().getBaseDir().getPath();
}
msaFile = new File(moduleDir + File.separatorChar + msaFilename);
}
public void addConfiguredModuleItem(ModuleItem moduleItem) {
PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion());
ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion());
moduleId.setPackage(packageId);
this.moduleId = moduleId;
}
/**
Add a property.
@param p property
**/
public void addProperty(Property p) {
properties.addElement(p);
}
public void setType(String type) {
this.type = type;
}
private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws EdkException {
//
// Call AutoGen to generate AutoGen.c and AutoGen.h
//
AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch(), saq, parentId);
autogen.genAutogen();
//
// Get compiler flags
//
try {
getCompilerFlags(buildTarget, buildTagname, fpdModuleId);
}
catch (EdkException ee) {
throw new BuildException(ee.getMessage());
}
//
// Prepare LIBS
//
ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());
String propertyLibs = "";
for (int i = 0; i < libinstances.length; i++) {
propertyLibs += getProject().getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib" + " ";
}
getProject().setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));
//
// Get all includepath and set to INCLUDE_PATHS
//
String[] includes = prepareIncludePaths(fpdModuleId);
//
// if it is CUSTOM_BUILD
// then call the exist BaseName_build.xml directly.
//
if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
EdkLog.log(this, "Call user-defined " + moduleId.getName() + "_build.xml");
String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";
antCall(antFilename, null);
return ;
}
//
// Generate ${BASE_NAME}_build.xml
// TBD
//
String ffsKeyword = saq.getModuleFfsKeyword();
ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId, includes, saq);
String buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
fileGenerator.genBuildFile(buildFilename);
//
// Ant call ${BASE_NAME}_build.xml
//
String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
antCall(antFilename, null);
}
private void applyClean(FpdModuleIdentification fpdModuleId){
//
// if it is CUSTOM_BUILD
// then call the exist BaseName_build.xml directly.
//
if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");
String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";
antCall(antFilename, "clean");
return ;
}
String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
antCall(antFilename, "clean");
}
private void applyCleanall(FpdModuleIdentification fpdModuleId){
//
// if it is CUSTOM_BUILD
// then call the exist BaseName_build.xml directly.
//
if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");
String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";
antCall(antFilename, "cleanall");
return ;
}
String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
antCall(antFilename, "cleanall");
}
private void antCall(String antFilename, String target) {
Ant ant = new Ant();
ant.setProject(getProject());
ant.setAntfile(antFilename);
if (target != null) {
ant.setTarget(target);
}
ant.setInheritAll(true);
ant.init();
ant.execute();
}
/**
Separate the string and instore in set.
<p> String is separated by Java Regulation Expression
"[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
<p>For example: </p>
<pre>
"/nologo", "/W3", "/WX"
"/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
</pre>
@param set store the separated string
@param str string to separate
**/
private void putFlagsToSet(Set<String> set, String str) {
if (str == null || str.length() == 0) {
return;
}
Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
Matcher matcher = myPattern.matcher(str + " ");
while (matcher.find()) {
String item = str.substring(matcher.start(1), matcher.end(1));
set.add(item);
}
}
/**
Generate the final flags string will be used by compile command.
@param add the add flags set
@param sub the sub flags set
@return final flags after add set substract sub set
**/
private String getFlags(Set<String> add, Set<String> sub) {
String result = "";
add.removeAll(sub);
Iterator iter = add.iterator();
while (iter.hasNext()) {
String str = (String) iter.next();
result += str.substring(1, str.length() - 1) + " ";
}
return result;
}
public void setSingleModuleBuild(boolean isSingleModuleBuild) {
this.isSingleModuleBuild = isSingleModuleBuild;
}
private String[] prepareIncludePaths(FpdModuleIdentification fpdModuleId) throws EdkException{
//
// Prepare the includes: PackageDependencies and Output debug direactory
//
Set<String> includes = new LinkedHashSet<String>();
String arch = fpdModuleId.getArch();
//
// WORKSPACE
//
includes.add("${WORKSPACE_DIR}" + File.separatorChar);
//
// Module iteself
//
includes.add("${MODULE_DIR}");
includes.add("${MODULE_DIR}" + File.separatorChar + archDir(arch));
//
// Packages in PackageDenpendencies
//
PackageIdentification[] packageDependencies = saq.getDependencePkg(fpdModuleId.getArch());
for (int i = 0; i < packageDependencies.length; i++) {
GlobalData.refreshPackageIdentification(packageDependencies[i]);
File packageFile = packageDependencies[i].getSpdFile();
includes.add(packageFile.getParent() + File.separatorChar + "Include");
includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));
}
//
// All Dependency Library Instance's PackageDependencies
//
ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());
for (int i = 0; i < libinstances.length; i++) {
saq.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch()));
PackageIdentification[] libraryPackageDependencies = saq.getDependencePkg(fpdModuleId.getArch());
for (int j = 0; j < libraryPackageDependencies.length; j++) {
GlobalData.refreshPackageIdentification(libraryPackageDependencies[j]);
File packageFile = libraryPackageDependencies[j].getSpdFile();
includes.add(packageFile.getParent() + File.separatorChar + "Include");
includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));
}
saq.pop();
}
//
// The package which the module belongs to
// TBD
includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include");
includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));
//
// Debug files output directory
//
includes.add("${DEST_DIR_DEBUG}");
//
// set to INCLUDE_PATHS property
//
Iterator<String> iter = includes.iterator();
StringBuffer includePaths = new StringBuffer();
while (iter.hasNext()) {
includePaths.append(iter.next());
includePaths.append("; ");
}
getProject().setProperty("INCLUDE_PATHS", getProject().replaceProperties(includePaths.toString()).replaceAll("(\\\\)", "/"));
return includes.toArray(new String[includes.size()]);
}
/**
Return the name of the directory that corresponds to the architecture.
This is a translation from the XML Schema tag to a directory that
corresponds to our directory name coding convention.
**/
private String archDir(String arch) {
return arch.replaceFirst("X64", "x64")
.replaceFirst("IPF", "Ipf")
.replaceFirst("IA32", "Ia32")
.replaceFirst("ARM", "Arm")
.replaceFirst("EBC", "Ebc");
}
public void setExternalProperties(Vector<Property> v) {
this.properties = v;
}
}

View File

@ -0,0 +1,242 @@
/** @file
This file is for single module thread definition.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.Vector;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Property;
import org.tianocore.build.GenBuildTask;
import org.tianocore.build.fpd.FpdParserForThread;
import org.tianocore.build.global.GenBuildLogger;
import org.tianocore.build.id.FpdModuleIdentification;
import org.tianocore.build.id.ModuleIdentification;
import org.tianocore.common.logger.EdkLog;
/**
Add more comment here.
@since GenBuild 1.0
**/
public class GenBuildThread implements Runnable {
private ModuleIdentification parentModuleId = null;
private ModuleIdentification moduleId = null;
private Set<FpdModuleIdentification> dependencies = new LinkedHashSet<FpdModuleIdentification>();
private int status = FpdParserForThread.STATUS_DEPENDENCY_NOT_READY;
private Project project = null;
public Object semaphore = new Object();
private String arch = null;
private boolean highPriority = false;
private Thread thread;
public GenBuildThread(ModuleIdentification moduleId, String arch) {
this.moduleId = moduleId;
this.arch = arch;
thread = new Thread(FpdParserForThread.tg, this, moduleId + ":" + arch);
}
public boolean start() {
if (highPriority) {
thread.setPriority(Thread.MAX_PRIORITY);
}
status = FpdParserForThread.STATUS_START_RUN;
thread.start();
return true;
}
public void run() {
FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);
try {
//
// Prepare pass down properties
// ARCH, MODULE_GUID, MODULE_VERSION, PACKAGE_GUID, PACKAGE_VERSION, PLATFORM_FILE
//
Vector<Property> properties = new Vector<Property>();
Property property = new Property();
property.setName("ARCH");
property.setValue(arch);
properties.add(property);
property = new Property();
property.setName("MODULE_GUID");
property.setValue(moduleId.getGuid());
properties.add(property);
property = new Property();
property.setName("MODULE_VERSION");
if (moduleId.getVersion() == null) {
property.setValue("");
} else {
property.setValue(moduleId.getVersion());
}
properties.add(property);
property = new Property();
property.setName("PACKAGE_GUID");
property.setValue(moduleId.getPackage().getGuid());
properties.add(property);
property = new Property();
property.setName("PACKAGE_VERSION");
if (moduleId.getPackage().getVersion() == null) {
property.setValue("");
} else {
property.setValue(moduleId.getPackage().getVersion());
}
properties.add(property);
//
// Build the Module
//
GenBuildTask genBuildTask = new GenBuildTask();
Project newProject = new Project();
Hashtable passdownProperties = project.getProperties();
Iterator iter = passdownProperties.keySet().iterator();
while (iter.hasNext()) {
String item = (String) iter.next();
newProject.setProperty(item, (String) passdownProperties.get(item));
}
newProject.setInputHandler(project.getInputHandler());
Iterator listenerIter = project.getBuildListeners().iterator();
GenBuildLogger newLogger = null;
while (listenerIter.hasNext()) {
BuildListener item = (BuildListener)listenerIter.next();
if (item instanceof GenBuildLogger) {
newLogger = (GenBuildLogger)((GenBuildLogger)item).clone();
newLogger.setId(fpdModuleId);
newProject.addBuildListener(newLogger);
} else {
newProject.addBuildListener(item);
}
}
project.initSubProject(newProject);
genBuildTask.setProject(newProject);
genBuildTask.setExternalProperties(properties);
genBuildTask.parentId = parentModuleId;
genBuildTask.perform();
} catch (BuildException be) {
EdkLog.log("GenBuild", EdkLog.EDK_ALWAYS, fpdModuleId + " build error. \n" + be.getMessage());
if (FpdParserForThread.errorModule == null) {
FpdParserForThread.errorModule = fpdModuleId;
}
synchronized (FpdParserForThread.deamonSemaphore) {
FpdParserForThread.subCount();
FpdParserForThread.deamonSemaphore.notifyAll();
}
return ;
}
status = FpdParserForThread.STATUS_END_RUN;
EdkLog.log("GenBuild", EdkLog.EDK_ALWAYS, fpdModuleId + " build finished. ");
//
//
//
synchronized (FpdParserForThread.deamonSemaphore) {
FpdParserForThread.subCount();
FpdParserForThread.deamonSemaphore.notifyAll();
}
}
public void setArch(String arch) {
this.arch = arch;
}
public void setDependencies(Set<FpdModuleIdentification> dependencies) {
this.dependencies = dependencies;
}
public void setModuleId(ModuleIdentification moduleId) {
this.moduleId = moduleId;
}
public void setParentModuleId(ModuleIdentification parentModuleId) {
this.parentModuleId = parentModuleId;
}
public void setProject(Project project) {
this.project = project;
}
public void setHighPriority(boolean highPriority) {
this.highPriority = highPriority;
}
public Set<FpdModuleIdentification> getDependencies() {
return dependencies;
}
public ModuleIdentification getModuleId() {
return moduleId;
}
public int getStatus() {
//
// Add code here to judge dependency
//
if (status == FpdParserForThread.STATUS_DEPENDENCY_NOT_READY) {
Iterator<FpdModuleIdentification> iter = dependencies.iterator();
boolean flag = true;
while (iter.hasNext()) {
FpdModuleIdentification item = iter.next();
if (FpdParserForThread.allThreads.get(item).getStatus() == 1) {
flag = false;
break ;
}
}
if (flag) {
status = FpdParserForThread.STATUS_DEPENDENCY_READY;
}
}
return status;
}
public void setStatus(int status) {
this.status = status;
}
}

View File

@ -0,0 +1,493 @@
/** @file
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.Map;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.tianocore.build.exception.GenBuildException;
import org.tianocore.build.fpd.FpdParserTask;
import org.tianocore.build.global.SurfaceAreaQuery;
import org.tianocore.build.id.FpdModuleIdentification;
import org.tianocore.build.id.ModuleIdentification;
import org.tianocore.build.id.PackageIdentification;
import org.tianocore.common.exception.EdkException;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class ModuleBuildFileGenerator {
///
/// Pass: TARGET, TOOLCHAIN, ARCH
/// PACKAGE, PACKAGE_GUID, PACKAGE_VERSION
///
String[] inheritProperties = {"ARCH", "MODULE_GUID", "MODULE_VERSION", "PACKAGE_GUID", "PACKAGE_VERSION"};
///
/// The information at the header of <em>build.xml</em>.
///
private String info = "DO NOT EDIT \n"
+ "This file is auto-generated by the build utility\n"
+ "\n"
+ "Abstract:\n"
+ "Auto-generated ANT build file for build EFI Modules and Platforms\n";
private FpdModuleIdentification fpdModuleId;
private Project project;
private String ffsKeyword;
private String[] includes;
private SurfaceAreaQuery saq = null;
public ModuleBuildFileGenerator(Project project, String ffsKeyword, FpdModuleIdentification fpdModuleId, String[] includes, SurfaceAreaQuery saq) {
this.project = project;
this.fpdModuleId = fpdModuleId;
this.ffsKeyword = ffsKeyword;
this.includes = includes;
this.saq = saq;
}
/**
The whole BaseName_build.xml is composed of seven part.
<ul>
<li> ANT properties; </li>
<li> Dependent module (dependent library instances in most case); </li>
<li> Source files; </li>
<li> Sections if module is not library; </li>
<li> Output (different for library module and driver module); </li>
<li> Clean; </li>
<li> Clean all. </li>
</ul>
@throws BuildException
Error throws during BaseName_build.xml generating.
**/
public void genBuildFile(String buildFilename) throws GenBuildException, EdkException {
FfsProcess fp = new FfsProcess();
DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder dombuilder = domfac.newDocumentBuilder();
Document document = dombuilder.newDocument();
Comment rootComment = document.createComment(info);
//
// create root element and its attributes
//
Element root = document.createElement("project");
root.setAttribute("name", fpdModuleId.getModule().getName());
root.setAttribute("default", "all");
root.setAttribute("basedir", ".");
//
// element for External ANT tasks
//
root.appendChild(document.createComment("Apply external ANT tasks"));
Element ele = document.createElement("taskdef");
ele.setAttribute("resource", "frameworktasks.tasks");
root.appendChild(ele);
ele = document.createElement("taskdef");
ele.setAttribute("resource", "cpptasks.tasks");
root.appendChild(ele);
ele = document.createElement("typedef");
ele.setAttribute("resource", "cpptasks.types");
root.appendChild(ele);
ele = document.createElement("taskdef");
ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
root.appendChild(ele);
//
// Generate the default target,
// which depends on init, sections and output target
//
root.appendChild(document.createComment("Default target"));
ele = document.createElement("target");
ele.setAttribute("name", "all");
ele.setAttribute("depends", "libraries, sourcefiles, sections, output");
root.appendChild(ele);
//
// compile all source files
//
root.appendChild(document.createComment("Compile all dependency Library instances."));
ele = document.createElement("target");
ele.setAttribute("name", "libraries");
//
// Parse all sourfiles but files specified in sections
//
if (!FrameworkBuildTask.multithread) {
applyLibraryInstance(document, ele);
}
root.appendChild(ele);
//
// compile all source files
//
root.appendChild(document.createComment("sourcefiles target"));
ele = document.createElement("target");
ele.setAttribute("name", "sourcefiles");
//
// Parse all sourfiles but files specified in sections
//
applyCompileElement(document, ele);
root.appendChild(ele);
//
// generate the init target
// main purpose is create all nessary pathes
// generate the sections target
//
root.appendChild(document.createComment("sections target"));
ele = document.createElement("target");
ele.setAttribute("name", "sections");
applySectionsElement(document, ele, fp);
root.appendChild(ele);
//
// generate the output target
//
root.appendChild(document.createComment("output target"));
ele = document.createElement("target");
ele.setAttribute("name", "output");
applyOutputElement(document, ele, fp);
root.appendChild(ele);
//
// generate the clean target
//
root.appendChild(document.createComment("clean target"));
ele = document.createElement("target");
ele.setAttribute("name", "clean");
applyCleanElement(document, ele);
root.appendChild(ele);
//
// generate the Clean All target
//
root.appendChild(document.createComment("Clean All target"));
ele = document.createElement("target");
ele.setAttribute("name", "cleanall");
applyDeepcleanElement(document, ele);
root.appendChild(ele);
//
// add the root element to the document
//
document.appendChild(rootComment);
document.appendChild(root);
//
// Prepare the DOM document for writing
//
Source source = new DOMSource(document);
//
// Prepare the output file
//
File file = new File(buildFilename);
//
// generate all directory path
//
(new File(file.getParent())).mkdirs();
FileOutputStream outputStream = new FileOutputStream(file);
Result result = new StreamResult(new OutputStreamWriter(outputStream));
//
// Write the DOM document to the file
//
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
xformer.setOutputProperty(OutputKeys.INDENT, "yes");
xformer.transform(source, result);
} catch (ParserConfigurationException ex) {
GenBuildException e = new GenBuildException("Generating the module [" + fpdModuleId.getModule().getName() + "] build.xml file failed!.\n" + ex.getMessage());
e.setStackTrace(ex.getStackTrace());
throw e;
} catch (FileNotFoundException ex) {
GenBuildException e = new GenBuildException("Generating the module [" + fpdModuleId.getModule().getName() + "] build.xml file failed!.\n" + ex.getMessage());
e.setStackTrace(ex.getStackTrace());
throw e;
} catch (TransformerConfigurationException ex) {
GenBuildException e = new GenBuildException("Generating the module [" + fpdModuleId.getModule().getName() + "] build.xml file failed!.\n" + ex.getMessage());
e.setStackTrace(ex.getStackTrace());
throw e;
} catch (TransformerException ex) {
GenBuildException e = new GenBuildException("Generating the module [" + fpdModuleId.getModule().getName() + "] build.xml file failed!.\n" + ex.getMessage());
e.setStackTrace(ex.getStackTrace());
throw e;
}
}
/**
Generate the clean elements for BaseName_build.xml.
@param document current BaseName_build.xml XML document
@param root Root element for current
**/
private void applyCleanElement(Document document, Node root) {
//
// <delete includeemptydirs="true">
// <fileset dir="${DEST_DIR_OUTPUT}" includes="" excludes="" />
// </delete>
//
Element deleteEle = document.createElement("delete");
deleteEle.setAttribute("includeemptydirs", "true");
Element filesetEle = document.createElement("fileset");
filesetEle.setAttribute("dir", "${DEST_DIR_OUTPUT}");
filesetEle.setAttribute("includes", "**/*");
filesetEle.setAttribute("excludes", "*.xml");
deleteEle.appendChild(filesetEle);
root.appendChild(deleteEle);
}
/**
Generate the cleanall elements for BaseName_build.xml.
@param document current BaseName_build.xml XML document
@param root Root element for current
**/
private void applyDeepcleanElement(Document document, Node root) {
//
// <delete includeemptydirs="true">
// <fileset dir="${DEST_DIR_OUTPUT}" includes="" excludes="" />
// </delete>
//
Element deleteEle = document.createElement("delete");
deleteEle.setAttribute("includeemptydirs", "true");
Element filesetEle = document.createElement("fileset");
filesetEle.setAttribute("dir", "${DEST_DIR_OUTPUT}");
filesetEle.setAttribute("includes", "**/*");
filesetEle.setAttribute("excludes", "*.xml");
deleteEle.appendChild(filesetEle);
root.appendChild(deleteEle);
//
// <delete includeemptydirs="true">
// <fileset dir="${DEST_DIR_DEBUG}" includes="" />
// </delete>
//
deleteEle = document.createElement("delete");
deleteEle.setAttribute("includeemptydirs", "true");
filesetEle = document.createElement("fileset");
filesetEle.setAttribute("dir", "${DEST_DIR_DEBUG}");
filesetEle.setAttribute("includes", "**/*");
deleteEle.appendChild(filesetEle);
root.appendChild(deleteEle);
}
/**
Generate the dependent library instances elements for BaseName_build.xml.
@param document current BaseName_build.xml XML document
@param root Root element for current
**/
private void applyLibraryInstance(Document document, Node root) throws EdkException {
ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());
for (int i = 0; i < libinstances.length; i++) {
//
// Put package file path to module identification
//
PackageIdentification packageId = libinstances[i].getPackage();
//
// Generate ANT script to build library instances
//
Element ele = document.createElement("GenBuild");
ele.setAttribute("type", "build");
//
// Prepare pass down information
//
Map<String, String> passDownMap = new LinkedHashMap<String, String>();
for (int j = 0; j < inheritProperties.length; j ++){
passDownMap.put(inheritProperties[j], "${" + inheritProperties[j] + "}");
}
passDownMap.put("MODULE_GUID", libinstances[i].getGuid());
passDownMap.put("MODULE_VERSION", libinstances[i].getVersion());
passDownMap.put("PACKAGE_GUID", packageId.getGuid());
passDownMap.put("PACKAGE_VERSION", packageId.getVersion());
for (int j = 0; j < inheritProperties.length; j ++){
Element property = document.createElement("property");
property.setAttribute("name", inheritProperties[j]);
property.setAttribute("value", passDownMap.get(inheritProperties[j]));
ele.appendChild(property);
}
root.appendChild(ele);
}
}
/**
Generate the build source files elements for BaseName_build.xml.
@param document current BaseName_build.xml XML document
@param root Root element for current
**/
private void applyCompileElement(Document document, Node root) {
//
// sourceFiles[][0] is FileType, [][1] is File name relative to Module_Dir
//
String[][] sourceFiles = saq.getSourceFiles(fpdModuleId.getArch());
FileProcess fileProcess = new FileProcess();
fileProcess.init(project, includes, document);
//
// Initialize some properties by user
//
Element initEle = document.createElement("Build_Init");
root.appendChild(initEle);
String moduleDir = project.getProperty("MODULE_DIR");
//
// Parse all Unicode files
//
for (int i = 0; i < sourceFiles.length; i++) {
//
// Go through all source files. Add MODULE_DIR to preffix
//
File sourceFile = new File(moduleDir + File.separatorChar + sourceFiles[i][1]);
sourceFiles[i][1] = sourceFile.getPath();
String filetype = sourceFiles[i][0];
if (filetype != null) {
fileProcess.parseFile(sourceFiles[i][1], filetype, root, true);
} else {
fileProcess.parseFile(sourceFiles[i][1], root, true);
}
}
//
// If exist Unicode file
//
if (fileProcess.isUnicodeExist()) {
Element ele = document.createElement("Build_Unicode_Database");
ele.setAttribute("FILEPATH", ".");
ele.setAttribute("FILENAME", "${BASE_NAME}");
Element includesEle = document.createElement("EXTRA.INC");
for (int i = 0; i < includes.length; i++) {
Element includeEle = document.createElement("includepath");
includeEle.setAttribute("path", includes[i]);
includesEle.appendChild(includeEle);
}
ele.appendChild(includesEle);
root.appendChild(ele);
}
//
// Parse AutoGen.c & AutoGen.h
//
if ( ! fpdModuleId.getModule().getName().equalsIgnoreCase("Shell")) {
fileProcess.parseFile(project.getProperty("DEST_DIR_DEBUG") + File.separatorChar + "AutoGen.c", root, false);
}
//
// Parse all source files but Unicode files
//
for (int i = 0; i < sourceFiles.length; i++) {
String filetype = sourceFiles[i][0];
if (filetype != null) {
fileProcess.parseFile(sourceFiles[i][1], filetype, root, false);
} else {
fileProcess.parseFile(sourceFiles[i][1], root, false);
}
}
//
// Initialize SOURCE_FILES for dependcy check use
//
String str = "";
for (int i = 0; i < sourceFiles.length; i++) {
str += " " + sourceFiles[i][1];
}
project.setProperty("SOURCE_FILES", str.replaceAll("(\\\\)", "/"));
}
/**
Generate the section elements for BaseName_build.xml. Library module will
skip this process.
@param document current BaseName_build.xml XML document
@param root Root element for current
**/
private void applySectionsElement(Document document, Node root, FfsProcess fp) {
if (fpdModuleId.getModule().isLibrary()) {
return ;
}
if (fp.initSections(ffsKeyword, project, fpdModuleId)) {
String targetFilename = fpdModuleId.getModule().getGuid() + "-" + "${BASE_NAME}" + FpdParserTask.getSuffix(fpdModuleId.getModule().getModuleType());
String[] list = fp.getGenSectionElements(document, "${BASE_NAME}", fpdModuleId.getModule().getGuid(), targetFilename);
for (int i = 0; i < list.length; i++) {
Element ele = document.createElement(list[i]);
ele.setAttribute("FILEPATH", ".");
ele.setAttribute("FILENAME", "${BASE_NAME}");
root.appendChild(ele);
}
}
}
/**
Generate the output elements for BaseName_build.xml. If module is library,
call the <em>LIB</em> command, else call the <em>GenFfs</em> command.
@param document current BaseName_build.xml XML document
@param root Root element for current
**/
private void applyOutputElement(Document document, Node root, FfsProcess fp) {
if (fpdModuleId.getModule().isLibrary()) {
//
// call Lib command
//
Element cc = document.createElement("Build_Library");
cc.setAttribute("FILENAME", fpdModuleId.getModule().getName());
root.appendChild(cc);
}
//
// if it is a module but library
//
else {
if (fp.getFfsNode() != null) {
root.appendChild(fp.getFfsNode());
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,317 @@
/**@file
AutogenLibOrder class.
This class is to reorder library instance sequence according to library
dependence.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.autogen;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.xmlbeans.XmlObject;
import org.tianocore.build.exception.AutoGenException;
import org.tianocore.build.global.GlobalData;
import org.tianocore.build.global.SurfaceAreaQuery;
import org.tianocore.build.id.ModuleIdentification;
import org.tianocore.common.exception.EdkException;
/**
This class This class is to reorder library instance sequence according to
library dependence.
**/
public class AutogenLibOrder {
///
/// The map of library class and its library instance.
///
private Map<String, ModuleIdentification> libClassMap = new HashMap<String, ModuleIdentification>();
///
/// The map of library instance and its implemet libraryClass.
///
private Map<ModuleIdentification, String[]> libInstanceMap = new HashMap<ModuleIdentification, String[]>();
///
/// List of library instance. It is String[3] list, String[0] is libraryName,
/// String[1] is libraryConstructor name, String[2] is libDestructor name.
///
private List<LibraryInstanceNode> libInstanceList = new ArrayList<LibraryInstanceNode>();
/**
Constructor function
This function mainly initialize some member variable.
@param libraryList List of the library instance.
@throws Exception
**/
AutogenLibOrder(ModuleIdentification[] libraryList, String arch) throws EdkException {
LibraryInstanceNode libInstanceNode;
String[] libClassDeclList = null;
String[] libClassConsmList = null;
for (int i = 0; i < libraryList.length; i++) {
//
// Add libraryInstance in to libInstanceList.
//
Map<String, XmlObject> libDoc = GlobalData.getDoc(libraryList[i], arch);
SurfaceAreaQuery saq = new SurfaceAreaQuery(libDoc);
libInstanceNode = new LibraryInstanceNode (libraryList[i],saq.getLibConstructorName(), saq.getLibDestructorName());
libInstanceList.add(libInstanceNode);
//
// Add library instance and consumed library class list to
// libInstanceMap.
//
libClassConsmList = saq.getLibraryClasses(CommonDefinition.ALWAYSCONSUMED, arch);
if (libClassConsmList != null) {
String[] classStr = new String[libClassConsmList.length];
for (int k = 0; k < libClassConsmList.length; k++) {
classStr[k] = libClassConsmList[k];
}
if (this.libInstanceMap.containsKey(libraryList[i])) {
throw new AutoGenException(
libraryList[i].getName()
+ "-- this library instance already exists, please check the library instance list!");
} else {
this.libInstanceMap.put(libraryList[i], classStr);
}
}
//
// Add library class and library instance map.
//
libClassDeclList = saq.getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, arch);
if (libClassDeclList != null) {
for (int j = 0; j < libClassDeclList.length; j++) {
if (this.libClassMap.containsKey(libClassDeclList[j])) {
System.out.println(libClassDeclList[j]
+ " class is already implement by "
+ this.libClassMap.get(libClassDeclList[j]));
throw new AutoGenException("Library Class: " + libClassDeclList
+ " already has a library instance!");
} else {
this.libClassMap.put(libClassDeclList[j], libraryList[i]);
}
}
}
}
//
// Check is the library instance list meet the require;
//
//for (int s = 0; s < this.libInstanceList.size(); s++) {
// String[] libClass = this.libInstanceMap.get(this.libInstanceList
// .get(s));
// if (libClass != null) {
// for (int t = 0; t < libClass.length; t++) {
// if (this.libClassMap.get(libClass[t]) == null) {
//
// Note: There exist a kind of module which depend on
// library class with no instance or whose instance will
// never be linked into the module.
// For this satuation, the module has the description of
// library class in MSA file but no description of
// corresponding library instance in MBD file. There
// will be a warnig message given here after a standard
// log way has been decided.
//
// }
// }
// }
//}
}
/**
orderLibInstance
This function reorder the library instance according the library class
dependency.
@return List which content the ordered library instance.
**/
List<ModuleIdentification> orderLibInstance() {
List<ModuleIdentification> orderList = new ArrayList<ModuleIdentification>();
//
// Stack of node which track the library instance name ant its visiting
// flag.
//
List<Node> stackList = new ArrayList<Node>();
int stackSize = 0;
ModuleIdentification libInstanceId = null;
if (libInstanceList.size() < 0) {
return null;
}
//
// Reorder the library instance.
//
for (int i = 0; i < libInstanceList.size(); i++) {
//
// If library instance is already in the order list skip it.
//
if (isInLibInstance(orderList, libInstanceList.get(i).libId)) {
continue;
}
Node node = new Node(libInstanceList.get(i).libId, false);
//
// Use stack to reorder library instance.
// Push node to stack.
//
stackList.add(node);
while (stackList.size() > 0) {
stackSize = stackList.size() - 1;
//
// Pop the first node in stack. If the node flag has been visited
// add this node to orderlist and remove it from stack.
//
if (stackList.get(stackSize).isVisit) {
if (!isInLibInstance(orderList,
stackList.get(stackSize).nodeId)) {
orderList.add(stackList.get(stackSize).nodeId);
stackList.remove(stackSize);
}
} else {
//
// Get the node value and set visit flag as true.
//
stackList.get(stackList.size() - 1).isVisit = true;
String[] libClassList = this.libInstanceMap.get(stackList
.get(stackSize).nodeId);
//
// Push the node dependence library instance to the stack.
//
if (libClassList != null) {
for (int j = 0; j < libClassList.length; j++) {
libInstanceId = this.libClassMap.get(libClassList[j]);
if (libInstanceId != null
&& !isInLibInstance(orderList, libInstanceId)) {
//
// If and only if the currently library instance
// is not in stack and it have constructor or
// destructor function, push this library
// instacne in stack.
//
if (!isInStackList(stackList, this.libClassMap
.get(libClassList[j])) && isHaveConsDestructor(libInstanceId)) {
stackList.add(new Node(this.libClassMap
.get(libClassList[j]), false));
}
}
}
}
}
}
}
return orderList;
}
/**
isInLibInstance
This function check does the library instance already in the list.
@param list List of the library instance.
@param instanceName Name of library instance.
@return "true" the library instance in list |
"false" the library instance is not in list.
**/
private boolean isInLibInstance(List<ModuleIdentification> list, ModuleIdentification instanceId) {
for (int i = 0; i < list.size(); i++) {
if (instanceId.equals(list.get(i))) {
return true;
}
}
return false;
}
/**
isInStackList
This function check if the node already in the stack.
@param list Stack.
@param nodeName Name of node.
@return "true" if node have in stack |
"false" if node don't in stack.
**/
private boolean isInStackList(List<Node> list, ModuleIdentification instanceId) {
for (int i = 0; i < list.size(); i++) {
if (instanceId.equals(list.get(i).nodeId)) {
return true;
}
}
return false;
}
/**
isHaveConsDestructor
This function check if the library have constructor or destructor
function.
@param libName Name of library
@return "true" if library have constructor or desconstructor |
"false" if library don't have constructor
and desconstructor.
**/
private boolean isHaveConsDestructor (ModuleIdentification libNode){
for (int i = 0; i < libInstanceList.size(); i++){
if (libInstanceList.get(i).libId.equals(libNode)){
if (libInstanceList.get(i).constructorName != null || libInstanceList.get(i).deconstructorName != null){
return true;
}
}
}
return false;
}
}
/**
Node
This class is used as stack node.
**/
class Node {
ModuleIdentification nodeId;
boolean isVisit;
Node(ModuleIdentification nodeId, boolean isVisit) {
this.nodeId = nodeId;
this.isVisit = false;
}
}
/**
LibraryInstance Node
This class is used to store LibrayInstance and it's deconstructor and constructor
**/
class LibraryInstanceNode {
ModuleIdentification libId;
String deconstructorName;
String constructorName;
LibraryInstanceNode (ModuleIdentification libId, String deconstructor, String constructor){
this.libId = libId;
this.deconstructorName = deconstructor;
this.constructorName = constructor;
}
}

View File

@ -0,0 +1,285 @@
/** @file
CommonDefinition class.
This class is to define some common marcos and funcions, which used by AutoGen.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.autogen;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import org.tianocore.common.definitions.EdkDefinitions;
import org.tianocore.common.definitions.ToolDefinitions;
/**
CommonDefinition
This class is to define some common marcos, which used by AutoGen.
**/
public class CommonDefinition {
///
/// final static string
///
public final static String LIBRARY = "LIBRARY";
public final static String AUTOGENHBEGIN = "extern int __make_me_compile_correctly;"
+ ToolDefinitions.LINE_SEPARATOR;
public final static String INCLUDE = "#include";
//public final static String DEBUGPROPERYMASK = "const UINT8 _gDebugPropertyMask "
// + "= DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED"
// + " | DEBUG_PROPERTY_DEBUG_PRINT_ENABLED"
// + " | DEBUG_PROPERTY_DEBUG_CODE_ENABLED;"
// + ToolDefinitions.LINE_SEPARATOR;
//public final static String DEFAULERROLEVEL = "const UINTN _gModuleDefaultErrorLevel"
// + " = EFI_D_ERROR | EFI_D_LOAD;"
// + ToolDefinitions.LINE_SEPARATOR;
public final static String INCLUDEAUTOGENH = INCLUDE
+ " <AutoGen.h>"
+ ToolDefinitions.LINE_SEPARATOR;
public final static String DEFINE = "#define ";
public final static String GEFI = "gEfi";
public final static String PRTOCOLGUID = "ProtocolGuid";
public final static String PPIGUID = "PpiGuid";
public final static String GUID = "Guid";
public final static String TIANOR8PLASHMAPH = "TianoR8FlashMap.h";
public final static String FLASHMAPH = "FlashMap.h";
public final static String IFNDEF = "#ifndef ";
public final static String AUTOGENH = "_AUTOGENH_";
///
/// AutoGen.h and AutoGen.c file's header
///
public final static String AUTOGENHNOTATION = "/**"
+ ToolDefinitions.LINE_SEPARATOR
+ " DO NOT EDIT"
+ ToolDefinitions.LINE_SEPARATOR
+ " FILE auto-generated by GenBuild tasks"
+ ToolDefinitions.LINE_SEPARATOR
+ " Module name:"
+ ToolDefinitions.LINE_SEPARATOR
+ " AutoGen.h"
+ ToolDefinitions.LINE_SEPARATOR
+ " Abstract:"
+ " Auto-generated AutoGen.h for building module or library."
+ ToolDefinitions.LINE_SEPARATOR
+ "**/"
+ ToolDefinitions.LINE_SEPARATOR
+ ToolDefinitions.LINE_SEPARATOR;
public final static String AUTOGENCNOTATION = "/**"
+ ToolDefinitions.LINE_SEPARATOR
+ " DO NOT EDIT"
+ ToolDefinitions.LINE_SEPARATOR
+ " FILE auto-generated by GenBuild tasks"
+ ToolDefinitions.LINE_SEPARATOR
+ " Module name:"
+ ToolDefinitions.LINE_SEPARATOR
+ " AutoGen.c"
+ ToolDefinitions.LINE_SEPARATOR
+ " Abstract:"
+ " Auto-generated AutoGen.c for building module or library."
+ ToolDefinitions.LINE_SEPARATOR
+ "**/"
+ ToolDefinitions.LINE_SEPARATOR
+ ToolDefinitions.LINE_SEPARATOR;
///
/// The defintions for identifying current module
/// is PEI Pcd driver or Dxe Pcd driver.
///
public static enum PCD_DRIVER_TYPE { NOT_PCD_DRIVER,
PEI_PCD_DRIVER,
DXE_PCD_DRIVER,
UNKNOWN_PCD_DRIVER
};
///
/// module type
///
public final static int ModuleTypeBase = 0;
public final static int ModuleTypeSec = 1;
public final static int ModuleTypePeiCore = 2;
public final static int ModuleTypePeim = 3;
public final static int ModuleTypeDxeCore = 4;
public final static int ModuleTypeDxeDriver = 5;
public final static int ModuleTypeDxeRuntimeDriver = 6;
public final static int ModuleTypeDxeSmmDriver = 7;
public final static int ModuleTypeDxeSalDriver = 8;
public final static int ModuleTypeUefiDriver = 9;
public final static int ModuleTypeUefiApplication = 10;
public final static int ModuleTypeUnknown = 11;
///
/// Usaged style
///
public final static String ALWAYSCONSUMED = "ALWAYS_CONSUMED";
public final static String ALWAYSPRODUCED = "ALWAYS_PRODUCED";
public static class MyEnum {
String moduleTypeStr;
int type;
MyEnum (String str, int type) {
this.type = type;
this.moduleTypeStr = str;
}
int ForInt(String str) {
if (str.equals(this.moduleTypeStr)) {
return this.type;
} else
return -1;
}
}
///
/// Module type
///
public static final MyEnum[] moduleEnum = new MyEnum[] {
new MyEnum(EdkDefinitions.MODULE_TYPE_BASE, ModuleTypeBase),
new MyEnum(EdkDefinitions.MODULE_TYPE_SEC, ModuleTypeSec),
new MyEnum(EdkDefinitions.MODULE_TYPE_PEI_CORE, ModuleTypePeiCore),
new MyEnum(EdkDefinitions.MODULE_TYPE_PEIM, ModuleTypePeim),
new MyEnum(EdkDefinitions.MODULE_TYPE_DXE_CORE, ModuleTypeDxeCore),
new MyEnum(EdkDefinitions.MODULE_TYPE_DXE_DRIVER, ModuleTypeDxeDriver),
new MyEnum(EdkDefinitions.MODULE_TYPE_DXE_RUNTIME_DRIVER, ModuleTypeDxeRuntimeDriver),
new MyEnum(EdkDefinitions.MODULE_TYPE_DXE_SAL_DRIVER, ModuleTypeDxeSalDriver),
new MyEnum(EdkDefinitions.MODULE_TYPE_DXE_SMM_DRIVER, ModuleTypeDxeSmmDriver),
new MyEnum(EdkDefinitions.MODULE_TYPE_UEFI_DRIVER, ModuleTypeUefiDriver),
new MyEnum(EdkDefinitions.MODULE_TYPE_UEFI_APPLICATION, ModuleTypeUefiApplication)};
/**
getModuleType
This function get the module type value according module type string.
@param moduleTypeStr String of modlue type.
@return
**/
public static int getModuleType(String moduleTypeStr) {
int returnValue = -1;
for (int i = 0; i < CommonDefinition.moduleEnum.length; i++) {
returnValue = CommonDefinition.moduleEnum[i].ForInt(moduleTypeStr);
if (returnValue != -1) {
return returnValue;
}
}
return CommonDefinition.ModuleTypeUnknown;
}
/**
formateGuidName
This function is to formate GUID to ANSI c form.
@param guidNameCon
String of GUID.
@return Formated GUID.
**/
public static String formatGuidName(String guidNameConv) {
String[] strList;
String guid = "";
int index = 0;
if (guidNameConv
.matches("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}")) {
strList = guidNameConv.split("-");
guid = "0x" + strList[0] + ", ";
guid = guid + "0x" + strList[1] + ", ";
guid = guid + "0x" + strList[2] + ", ";
guid = guid + "{";
guid = guid + "0x" + strList[3].substring(0, 2) + ", ";
guid = guid + "0x" + strList[3].substring(2, 4);
while (index < strList[4].length()) {
guid = guid + ", ";
guid = guid + "0x" + strList[4].substring(index, index + 2);
index = index + 2;
}
guid = guid + "}";
return guid;
} else if (guidNameConv
.matches("0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},( )*0x[a-fA-F0-9]{1,4}(,( )*\\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\\})?")) {
strList = guidNameConv.split(",");
//
// chang Microsoft specific form to ANSI c form
//
for (int i = 0; i < 3; i++) {
guid = guid + strList[i] + ",";
}
guid = guid + "{";
for (int i = 3; i < strList.length; i++) {
if (i == strList.length - 1) {
guid = guid + strList[i];
} else {
guid = guid + strList[i] + ",";
}
}
guid = guid + "}";
return guid;
} else {
System.out
.println("Check GUID Value, It doesn't conform to the registry format specified in the schema!!!");
return "0";
}
}
/**
Remove deuplicat string in list
This function is to duplicat string in list
@param String[]
String list.
@return String[] String list which remove the duplicate string.
**/
public static String[] remDupString (String[] orgList){
Set<String> strList = new LinkedHashSet<String>();
String[] desList ;
if (orgList == null) {
return new String[0];
}
for (int i = 0; i < orgList.length; i++) {
strList.add(orgList[i]);
}
desList = new String[strList.size()];
Iterator item = strList.iterator();
int index = 0;
while (item.hasNext()) {
desList[index] = (String)item.next();
index++;
}
return desList;
}
}

View File

@ -0,0 +1,40 @@
/** @file
AutoGenException class.
The class handle the exception throwed by entity class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.exception;
/**
The class handle the exception throwed by entity class.
**/
public class AutoGenException extends GenBuildException {
static final long serialVersionUID = -8034897190740066939L;
/**
Constructure function
@param expStr exception message string.
**/
public AutoGenException(String expStr) {
super(expStr);
}
public AutoGenException() {
}
public AutoGenException(Exception e, String messsge){
super(e, messsge);
}
}

View File

@ -0,0 +1,40 @@
/** @file
GenBuildException class.
The class handle the exception throwed by entity class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.exception;
import org.tianocore.common.exception.EdkException;
/**
The class handle the exception throwed by entity class.
**/
public class GenBuildException extends EdkException {
static final long serialVersionUID = -8034897190740066937L;
/**
Constructure function
@param expStr exception message string.
**/
public GenBuildException(String expStr) {
super(expStr);
}
public GenBuildException() {
super();
}
public GenBuildException(Exception e, String message){
super(e, message);
}
}

View File

@ -0,0 +1,35 @@
/** @file
AutoGenException class.
The class handle the exception throwed by entity class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.exception;
/**
The class handle the exception throwed by entity class.
**/
public class PcdAutogenException extends AutoGenException {
static final long serialVersionUID = -8034897190740066936L;
/**
Constructure function
@param expStr exception message string.
**/
public PcdAutogenException(String expStr) {
super(expStr);
}
public PcdAutogenException() {
super();
}
}

View File

@ -0,0 +1,36 @@
/** @file
PlatformPcdPreprocessBuildException class.
The class handle the exception throwed by PlatformPcdPreprocessActionForBuilding class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.exception;
public class PlatformPcdPreprocessBuildException extends GenBuildException {
/**
serial version ID
**/
private static final long serialVersionUID = -1014589090055424954L;
/**
Constructure function
@param expStr exception message string.
**/
public PlatformPcdPreprocessBuildException(String expStr) {
super(expStr);
}
public PlatformPcdPreprocessBuildException() {
super();
}
}

View File

@ -0,0 +1,35 @@
/** @file
XmlParseException class.
The class handle the exception throwed by entity class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.exception;
/**
The class handle the exception throwed by entity class.
**/
public class XmlParseException extends GenBuildException {
static final long serialVersionUID = -8034897190740066934L;
/**
Constructure function
@param expStr exception message string.
**/
public XmlParseException(String expStr) {
super(expStr);
}
public XmlParseException() {
super();
}
}

View File

@ -0,0 +1,409 @@
/** @file
This file is ANT task FpdParserTask.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.fpd;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.Ant;
import org.apache.xmlbeans.XmlObject;
import org.tianocore.build.global.GenBuildLogger;
import org.tianocore.build.global.GlobalData;
import org.tianocore.build.global.OutputManager;
import org.tianocore.build.id.FpdModuleIdentification;
import org.tianocore.build.id.ModuleIdentification;
import org.tianocore.build.FrameworkBuildTask;
import org.tianocore.build.GenBuildThread;
import org.tianocore.common.exception.EdkException;
import org.tianocore.common.logger.EdkLog;
/**
@since GenBuild 1.0
**/
public class FpdParserForThread extends FpdParserTask {
public static Map<FpdModuleIdentification, GenBuildThread> allThreads = new LinkedHashMap<FpdModuleIdentification, GenBuildThread>();
List<String> queueList = new ArrayList<String>();
public final static Object deamonSemaphore = new Object();
private final static Object countSemaphore = new Object();
public static int STATUS_DEPENDENCY_NOT_READY = 1;
public static int STATUS_DEPENDENCY_READY = 2;
public static int STATUS_START_RUN = 3;
public static int STATUS_END_RUN = 4;
private int currentQueueCode = 0;
public static int currentRunNumber = 0;
public static int totalNumber = 0;
public static int remainNumber = 0;
public static ThreadGroup tg = new ThreadGroup("Framework");
public static FpdModuleIdentification errorModule = null;
/**
Public construct method. It is necessary for ANT task.
**/
public FpdParserForThread() {
}
/**
**/
public void execute() throws BuildException {
this.setTaskName(".........");
//
// Parse FPD file
//
parseFpdFile();
//
// Prepare BUILD_DIR
//
isUnified = OutputManager.getInstance().prepareBuildDir(getProject());
String buildDir = getProject().getProperty("BUILD_DIR");
//
// For every Target and ToolChain
//
String[] targetList = GlobalData.getToolChainInfo().getTargets();
for (int i = 0; i < targetList.length; i++) {
String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
for(int j = 0; j < toolchainList.length; j++) {
//
// Prepare FV_DIR
//
String ffsCommonDir = buildDir + File.separatorChar
+ targetList[i] + "_"
+ toolchainList[j];
File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
fvDir.mkdirs();
getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/"));
//
// Gen Fv.inf files
//
genFvInfFiles(ffsCommonDir);
}
}
//
// Gen build.xml
//
String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml";
PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile);
fileGenerator.genBuildFile();
//
// Prepare Queue
//
queueList.add("libqueue");
String[] validFv = saq.getFpdValidImageNames();
for (int i = 0; i < validFv.length; i++) {
queueList.add(validFv[i]);
}
Iterator<String> fvsNameIter = fvs.keySet().iterator();
while (fvsNameIter.hasNext()) {
String fvName = fvsNameIter.next();
if (!isContain(validFv, fvName)) {
queueList.add(fvName);
}
}
//
// Ant call ${PLATFORM}_build.xml
//
Ant ant = new Ant();
ant.setProject(getProject());
ant.setAntfile(platformBuildFile);
ant.setTarget("prebuild");
ant.setInheritAll(true);
ant.init();
ant.execute();
remainNumber = totalNumber = allThreads.size();
EdkLog.log(this, EdkLog.EDK_ALWAYS, "Total thread number is " + totalNumber);
GenBuildLogger.setCacheEnable(true);
//
// Waiting for all thread over, or time out
//
synchronized (deamonSemaphore) {
while (true) {
//
// If all modules are already built
//
if (currentQueueCode >= queueList.size()) {
break ;
}
int percentage = (totalNumber - remainNumber) * 100 / totalNumber;
updateTaskName(percentage);
EdkLog.log(this, EdkLog.EDK_ALWAYS, percentage + "% finished. Has built " + (totalNumber - remainNumber) + " modules of " + totalNumber + " total. ");
Set<FpdModuleIdentification> currentQueueModules = fvs.get(queueList.get(currentQueueCode));
if (currentQueueModules == null) {
++currentQueueCode;
continue ;
}
Iterator<FpdModuleIdentification> currentIter = currentQueueModules.iterator();
GenBuildThread a = null;
boolean existNoneReady = false;
while (currentIter.hasNext()) {
GenBuildThread item = allThreads.get(currentIter.next());
if (item.getStatus() == STATUS_DEPENDENCY_NOT_READY) {
existNoneReady = true;
} else if (item.getStatus() == STATUS_DEPENDENCY_READY) {
a = item;
addCount();
a.start();
if (currentRunNumber == FrameworkBuildTask.MAX_CONCURRENT_THREAD_NUMBER) {
break ;
}
}
}
if (a != null) {
//
// Exist ready thread
//
EdkLog.log(this, EdkLog.EDK_DEBUG, "Exist ready thread");
} else if (existNoneReady && currentRunNumber == 0) {
//
// No active thread, but still have dependency not read thread
//
throw new BuildException("Existing some modules can't resolve depedencies. ");
} else if (!existNoneReady && currentRunNumber == 0) {
//
// Current queue build finish, move to next
//
EdkLog.log(this, EdkLog.EDK_DEBUG, "Current queue build finish, move to next");
++currentQueueCode;
continue ;
} else {
//
// active thread exist, but no ready thread
//
EdkLog.log(this, EdkLog.EDK_DEBUG, "Active thread exist, but no ready thread. Current running number is " + currentRunNumber);
}
try {
deamonSemaphore.wait();
//
// if find error. Waiting running threads to finish
//
if (errorModule != null) {
while (currentRunNumber > 0) {
deamonSemaphore.wait();
}
GenBuildLogger.setCacheEnable(false);
GenBuildLogger.flushErrorModuleLog(errorModule);
EdkLog.flushLogToFile(new File(buildDir + File.separatorChar + "build.log"));
throw new BuildException(errorModule + " build error. ");
}
} catch (InterruptedException ex) {
BuildException e = new BuildException("Thread wait Error. \n" + ex.getMessage());
e.setStackTrace(ex.getStackTrace());
throw e;
}
}
}
GenBuildLogger.setCacheEnable(false);
//
// call fvs, postbuild
//
ant = new Ant();
ant.setProject(getProject());
ant.setAntfile(platformBuildFile);
ant.setTarget("fvs");
ant.setInheritAll(true);
ant.init();
ant.execute();
ant = new Ant();
ant.setProject(getProject());
ant.setAntfile(platformBuildFile);
ant.setTarget("postbuild");
ant.setInheritAll(true);
ant.init();
ant.execute();
EdkLog.flushLogToFile(new File(buildDir + File.separatorChar + "build.log"));
}
/**
Parse all modules listed in FPD file.
**/
void parseModuleSAFiles() throws EdkException{
Map<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = saq.getFpdModules();
//
// For every Module lists in FPD file.
//
Set<FpdModuleIdentification> keys = moduleSAs.keySet();
Iterator<FpdModuleIdentification> iter = keys.iterator();
while (iter.hasNext()) {
FpdModuleIdentification fpdModuleId = iter.next();
//
// Generate GenBuildThread
//
GenBuildThread genBuildThread = new GenBuildThread(fpdModuleId.getModule(), fpdModuleId.getArch());
genBuildThread.setParentModuleId(null);
genBuildThread.setProject(getProject());
Set<FpdModuleIdentification> dependencies = new LinkedHashSet<FpdModuleIdentification>();
GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId));
//
// Add all dependent Library Instance
//
saq.push(GlobalData.getDoc(fpdModuleId));
ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());
saq.pop();
for (int i = 0; i < libinstances.length; i++) {
FpdModuleIdentification libFpdModuleId = new FpdModuleIdentification(libinstances[i], fpdModuleId.getArch());
//
// Add to dependencies
//
dependencies.add(libFpdModuleId);
//
// Create thread for library instances
//
GenBuildThread liBuildThread = new GenBuildThread(libinstances[i], fpdModuleId.getArch());
liBuildThread.setParentModuleId(fpdModuleId.getModule());
liBuildThread.setProject(getProject());
liBuildThread.setStatus(STATUS_DEPENDENCY_READY);
liBuildThread.setHighPriority(true);
allThreads.put(libFpdModuleId, liBuildThread);
updateFvs("libqueue", libFpdModuleId);
}
genBuildThread.setDependencies(dependencies);
// if (dependencies.size() == 0) {
genBuildThread.setStatus(STATUS_DEPENDENCY_READY);
// }
allThreads.put(fpdModuleId, genBuildThread);
//
// Put fpdModuleId to the corresponding FV
//
saq.push(GlobalData.getDoc(fpdModuleId));
String fvBinding = saq.getModuleFvBindingKeyword();
fpdModuleId.setFvBinding(fvBinding);
updateFvs(fvBinding, fpdModuleId);
//
// Prepare for out put file name
//
ModuleIdentification moduleId = fpdModuleId.getModule();
String baseName = saq.getModuleOutputFileBasename();
if (baseName == null) {
baseName = moduleId.getName();
}
outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar
+ moduleId.getGuid() + "-" + baseName
+ getSuffix(moduleId.getModuleType()));
//
// parse module build options, if any
//
GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false));
GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true));
saq.pop();
}
}
private boolean isContain(String[] list, String item) {
for (int i = 0; i < list.length; i++) {
if (list[i].equalsIgnoreCase(item)) {
return true;
}
}
return false;
}
public synchronized static void addCount() {
synchronized (countSemaphore) {
++currentRunNumber;
}
}
public synchronized static void subCount() {
synchronized (countSemaphore) {
--currentRunNumber;
--remainNumber;
}
}
private void updateTaskName(int percentage){
int number = percentage/10;
StringBuffer str = new StringBuffer(9);
for(int i = 0; i < 9; i++) {
if (i < number) {
str.append('>');
} else {
str.append('.');
}
}
this.setTaskName(str.toString());
}
}

View File

@ -0,0 +1,756 @@
/** @file
This file is ANT task FpdParserTask.
FpdParserTask is used to parse FPD (Framework Platform Description) and generate
build.out.xml. It is for Package or Platform build use.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.fpd;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Ant;
import org.apache.tools.ant.taskdefs.Property;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.tianocore.common.definitions.EdkDefinitions;
import org.tianocore.common.exception.EdkException;
import org.tianocore.common.logger.EdkLog;
import org.tianocore.build.FrameworkBuildTask;
import org.tianocore.build.global.GlobalData;
import org.tianocore.build.global.OutputManager;
import org.tianocore.build.global.SurfaceAreaQuery;
import org.tianocore.build.id.FpdModuleIdentification;
import org.tianocore.build.id.ModuleIdentification;
import org.tianocore.build.id.PackageIdentification;
import org.tianocore.build.id.PlatformIdentification;
import org.tianocore.build.pcd.action.PlatformPcdPreprocessActionForBuilding;
import org.tianocore.build.toolchain.ToolChainAttribute;
import org.tianocore.build.toolchain.ToolChainElement;
import org.tianocore.build.toolchain.ToolChainMap;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
<code>FpdParserTask</code> is an ANT task. The main function is parsing Framework
Platform Descritpion (FPD) XML file and generating its ANT build script for
corresponding platform.
<p>The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR
and BUILD_DIR. </p>
<p>The task generates ${PLATFORM}_build.xml file which will be called by top level
build.xml. The task also generate Fv.inf files (File is for Tool GenFvImage). </p>
<p>FpdParserTask task stores all FPD information to GlobalData. And parse
tools definition file to set up compiler options for different Target and
different ToolChainTag. </p>
<p>The method parseFpdFile is also prepared for single module build. </p>
@since GenBuild 1.0
**/
public class FpdParserTask extends Task {
private File fpdFile = null;
PlatformIdentification platformId;
private String type;
///
/// Mapping from modules identification to out put file name
///
Map<FpdModuleIdentification, String> outfiles = new LinkedHashMap<FpdModuleIdentification, String>();
///
/// Mapping from FV name to its modules
///
Map<String, Set<FpdModuleIdentification>> fvs = new HashMap<String, Set<FpdModuleIdentification>>();
///
/// FpdParserTask can specify some ANT properties.
///
private Vector<Property> properties = new Vector<Property>();
SurfaceAreaQuery saq = null;
boolean isUnified = true;
/**
Public construct method. It is necessary for ANT task.
**/
public FpdParserTask() {
}
/**
ANT task's entry method. The main steps is described as following:
<ul>
<li>Initialize global information (Framework DB, SPD files and all MSA files
listed in SPD). This step will execute only once in whole build process;</li>
<li>Parse specified FPD file; </li>
<li>Generate FV.inf files; </li>
<li>Generate PlatformName_build.xml file for Flatform build; </li>
<li>Collect PCD information. </li>
</ul>
@throws BuildException
Surface area is not valid.
**/
public void execute() throws BuildException {
this.setTaskName("FpdParser");
//
// Parse FPD file
//
parseFpdFile();
//
// Prepare BUILD_DIR
//
isUnified = OutputManager.getInstance().prepareBuildDir(getProject());
String buildDir = getProject().getProperty("BUILD_DIR");
//
// For every Target and ToolChain
//
String[] targetList = GlobalData.getToolChainInfo().getTargets();
for (int i = 0; i < targetList.length; i++) {
String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
for(int j = 0; j < toolchainList.length; j++) {
//
// Prepare FV_DIR
//
String ffsCommonDir = buildDir + File.separatorChar
+ targetList[i] + "_"
+ toolchainList[j];
File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
fvDir.mkdirs();
getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/"));
//
// Gen Fv.inf files
//
genFvInfFiles(ffsCommonDir);
}
}
//
// Gen build.xml
//
String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml";
PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile);
fileGenerator.genBuildFile();
//
// Ant call ${PLATFORM}_build.xml
//
Ant ant = new Ant();
ant.setProject(getProject());
ant.setAntfile(platformBuildFile);
ant.setTarget(type);
ant.setInheritAll(true);
ant.init();
ant.execute();
}
/**
Generate Fv.inf files. The Fv.inf file is composed with four
parts: Options, Attributes, Components and Files. The Fv.inf files
will be under FV_DIR.
@throws BuildException
File write FV.inf files error.
**/
void genFvInfFiles(String ffsCommonDir) throws BuildException {
String[] validFv = saq.getFpdValidImageNames();
for (int i = 0; i < validFv.length; i++) {
//
// Get all global variables from FPD and set them to properties
//
String[][] globalVariables = saq.getFpdGlobalVariable();
for (int j = 0; j < globalVariables.length; j++) {
getProject().setProperty(globalVariables[j][0], globalVariables[j][1]);
}
getProject().setProperty("FV_FILENAME", validFv[i]);
File fvFile = new File(getProject().replaceProperties( getProject().getProperty("FV_DIR") + File.separatorChar + validFv[i] + ".inf"));
if (fvFile.exists() && (fvFile.lastModified() >= fpdFile.lastModified())) {
//
// don't re-generate FV.inf if fpd has not been changed
//
continue;
}
fvFile.getParentFile().mkdirs();
try {
FileWriter fw = new FileWriter(fvFile);
BufferedWriter bw = new BufferedWriter(fw);
//
// Options
//
String[][] options = saq.getFpdOptions(validFv[i]);
if (options.length > 0) {
bw.write("[options]");
bw.newLine();
for (int j = 0; j < options.length; j++) {
StringBuffer str = new StringBuffer(100);
str.append(options[j][0]);
while (str.length() < 40) {
str.append(' ');
}
str.append("= ");
str.append(options[j][1]);
bw.write(getProject().replaceProperties(str.toString()));
bw.newLine();
}
bw.newLine();
}
//
// Attributes;
//
String[][] attributes = saq.getFpdAttributes(validFv[i]);
if (attributes.length > 0) {
bw.write("[attributes]");
bw.newLine();
for (int j = 0; j < attributes.length; j++) {
StringBuffer str = new StringBuffer(100);
str.append(attributes[j][0]);
while (str.length() < 40) {
str.append(' ');
}
str.append("= ");
str.append(attributes[j][1]);
bw.write(getProject().replaceProperties(str.toString()));
bw.newLine();
}
bw.newLine();
}
//
// Components
//
String[][] components = saq.getFpdComponents(validFv[i]);
if (components.length > 0) {
bw.write("[components]");
bw.newLine();
for (int j = 0; j < components.length; j++) {
StringBuffer str = new StringBuffer(100);
str.append(components[j][0]);
while (str.length() < 40) {
str.append(' ');
}
str.append("= ");
str.append(components[j][1]);
bw.write(getProject().replaceProperties(str.toString()));
bw.newLine();
}
bw.newLine();
}
//
// Files
//
Set<FpdModuleIdentification> moduleSeqSet = getModuleSequenceForFv(validFv[i]);
Set<FpdModuleIdentification> filesSet = fvs.get(validFv[i]);
FpdModuleIdentification[] files = null;
if (moduleSeqSet == null) {
if (filesSet != null) {
files = filesSet.toArray(new FpdModuleIdentification[filesSet.size()]);
}
} else if (filesSet == null) {
if (moduleSeqSet.size() != 0) {
throw new BuildException("Can not find any modules belongs to FV[" + validFv[i] + "], but listed some in BuildOptions.UserExtensions[@UserID='IMAGES' @Identifier='1']");
}
} else {
//
// if moduleSeqSet and filesSet is inconsistent, report error
//
if(moduleSeqSet.size() != filesSet.size()){
throw new BuildException("Modules for FV[" + validFv[i] + "] defined in FrameworkModules and in BuildOptions.UserExtensions[@UserID='IMAGES' @Identifier='1'] are inconsistent. ");
} else {
//
// whether all modules in moduleSeqSet listed in filesSet
//
Iterator<FpdModuleIdentification> iter = moduleSeqSet.iterator();
while (iter.hasNext()) {
FpdModuleIdentification item = iter.next();
if (!filesSet.contains(item)) {
throw new BuildException("Can not find " + item + " belongs to FV[" + validFv[i] + "]");
}
}
}
files = moduleSeqSet.toArray(new FpdModuleIdentification[moduleSeqSet.size()]);
}
if (files != null) {
bw.write("[files]");
bw.newLine();
for (int j = 0; j < files.length; j++) {
String str = ffsCommonDir + File.separatorChar + outfiles.get(files[j]);
bw.write(getProject().replaceProperties("EFI_FILE_NAME = " + str));
bw.newLine();
}
}
bw.flush();
bw.close();
fw.close();
} catch (IOException ex) {
BuildException buildException = new BuildException("Generation of the FV file [" + fvFile.getPath() + "] failed!\n" + ex.getMessage());
buildException.setStackTrace(ex.getStackTrace());
throw buildException;
} catch (EdkException ex) {
BuildException buildException = new BuildException("Generation of the FV file [" + fvFile.getPath() + "] failed!\n" + ex.getMessage());
buildException.setStackTrace(ex.getStackTrace());
throw buildException;
}
}
}
/**
This method is used for Single Module Build.
@throws BuildException
FPD file is not valid.
**/
public void parseFpdFile(File fpdFile) throws BuildException, EdkException {
this.fpdFile = fpdFile;
parseFpdFile();
//
// Call Platform_build.xml prebuild firstly in stand-alone build
// Prepare BUILD_DIR
//
isUnified = OutputManager.getInstance().prepareBuildDir(getProject());
String buildDir = getProject().getProperty("BUILD_DIR");
//
// For every Target and ToolChain
//
String[] targetList = GlobalData.getToolChainInfo().getTargets();
for (int i = 0; i < targetList.length; i++) {
String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
for(int j = 0; j < toolchainList.length; j++) {
//
// Prepare FV_DIR
//
String ffsCommonDir = buildDir + File.separatorChar
+ targetList[i] + "_"
+ toolchainList[j];
File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
fvDir.mkdirs();
}
}
String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml";
PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile);
fileGenerator.genBuildFile();
Ant ant = new Ant();
ant.setProject(getProject());
ant.setAntfile(platformBuildFile);
ant.setTarget("prebuild");
ant.setInheritAll(true);
ant.init();
ant.execute();
}
/**
Parse FPD file.
@throws BuildException
FPD file is not valid.
**/
void parseFpdFile() throws BuildException {
try {
XmlObject doc = XmlObject.Factory.parse(fpdFile);
if (!doc.validate()) {
throw new BuildException("Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!");
}
Map<String, XmlObject> map = new HashMap<String, XmlObject>();
map.put("PlatformSurfaceArea", doc);
saq = new SurfaceAreaQuery(map);
//
// Initialize
//
platformId = saq.getFpdHeader();
platformId.setFpdFile(fpdFile);
getProject().setProperty("PLATFORM", platformId.getName());
getProject().setProperty("PLATFORM_FILE", platformId.getRelativeFpdFile().replaceAll("(\\\\)", "/"));
getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
if( !FrameworkBuildTask.multithread) {
FrameworkBuildTask.originalProperties.put("PLATFORM", platformId.getName());
FrameworkBuildTask.originalProperties.put("PLATFORM_FILE", platformId.getRelativeFpdFile().replaceAll("(\\\\)", "/"));
FrameworkBuildTask.originalProperties.put("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
FrameworkBuildTask.originalProperties.put("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
}
//
// Build mode. User-defined output dir.
//
String buildMode = saq.getFpdIntermediateDirectories();
String userDefinedOutputDir = saq.getFpdOutputDirectory();
OutputManager.getInstance().setup(userDefinedOutputDir, buildMode);
//
// TBD. Deal PCD and BuildOption related Info
//
GlobalData.setFpdBuildOptions(saq.getFpdBuildOptions());
GlobalData.setToolChainPlatformInfo(saq.getFpdToolChainInfo());
//
// Parse all list modules SA
//
parseModuleSAFiles();
//
// TBD. Deal PCD and BuildOption related Info
//
parseToolChainFamilyOptions();
parseToolChainOptions();
saq.push(map);
//
// Pcd Collection. Call CollectPCDAction to collect pcd info.
//
PlatformPcdPreprocessActionForBuilding ca = new PlatformPcdPreprocessActionForBuilding();
ca.perform(platformId.getFpdFile().getPath());
} catch (IOException ex) {
BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());
buildException.setStackTrace(ex.getStackTrace());
throw buildException;
} catch (XmlException ex) {
BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());
buildException.setStackTrace(ex.getStackTrace());
throw buildException;
} catch (EdkException ex) {
BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());
buildException.setStackTrace(ex.getStackTrace());
throw buildException;
}
}
/**
Parse all modules listed in FPD file.
**/
void parseModuleSAFiles() throws EdkException{
Map<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = saq.getFpdModules();
//
// For every Module lists in FPD file.
//
Set<FpdModuleIdentification> keys = moduleSAs.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
//
// Judge if Module is existed?
// TBD
GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId));
//
// Put fpdModuleId to the corresponding FV
//
saq.push(GlobalData.getDoc(fpdModuleId));
String fvBinding = saq.getModuleFvBindingKeyword();
fpdModuleId.setFvBinding(fvBinding);
updateFvs(fvBinding, fpdModuleId);
//
// Prepare for out put file name
//
ModuleIdentification moduleId = fpdModuleId.getModule();
String baseName = saq.getModuleOutputFileBasename();
if (baseName == null) {
baseName = moduleId.getName();
}
outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar
+ moduleId.getGuid() + "-" + baseName
+ getSuffix(moduleId.getModuleType()));
//
// parse module build options, if any
//
GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false));
GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true));
saq.pop();
}
}
ToolChainMap parseModuleBuildOptions(boolean toolChainFamilyFlag) throws EdkException {
String[][] options = saq.getModuleBuildOptions(toolChainFamilyFlag);
if (options == null || options.length == 0) {
return new ToolChainMap();
}
return parseOptions(options);
}
private ToolChainMap parsePlatformBuildOptions(boolean toolChainFamilyFlag) throws EdkException {
String[][] options = saq.getPlatformBuildOptions(toolChainFamilyFlag);
if (options == null || options.length == 0) {
return new ToolChainMap();
}
return parseOptions(options);
}
private ToolChainMap parseOptions(String[][] options) throws EdkException {
ToolChainMap map = new ToolChainMap();
int flagIndex = ToolChainElement.ATTRIBUTE.value;
for (int i = 0; i < options.length; ++i) {
String flagString = options[i][flagIndex];
if (flagString == null) {
flagString = "";
}
options[i][flagIndex] = ToolChainAttribute.FLAGS + "";
map.put(options[i], flagString.trim());
}
return map;
}
private void parseToolChainFamilyOptions() throws EdkException {
GlobalData.setPlatformToolChainFamilyOption(parsePlatformBuildOptions(true));
}
private void parseToolChainOptions() throws EdkException {
GlobalData.setPlatformToolChainOption(parsePlatformBuildOptions(false));
}
/**
Add the current module to corresponding FV.
@param fvName current FV name
@param moduleName current module identification
**/
void updateFvs(String fvName, FpdModuleIdentification fpdModuleId) {
if (fvName == null || fvName.trim().length() == 0) {
fvName = "NULL";
}
String[] fvNameArray = fvName.split("[, \t]+");
for (int i = 0; i < fvNameArray.length; i++) {
//
// Put module to corresponding fvName
//
if (fvs.containsKey(fvNameArray[i])) {
Set<FpdModuleIdentification> set = fvs.get(fvNameArray[i]);
set.add(fpdModuleId);
} else {
Set<FpdModuleIdentification> set = new LinkedHashSet<FpdModuleIdentification>();
set.add(fpdModuleId);
fvs.put(fvNameArray[i], set);
}
}
}
/**
Get the suffix based on module type. Current relationship are listed:
<pre>
<b>ModuleType</b> <b>Suffix</b>
BASE .FFS
SEC .SEC
PEI_CORE .PEI
PEIM .PEI
DXE_CORE .DXE
DXE_DRIVER .DXE
DXE_RUNTIME_DRIVER .DXE
DXE_SAL_DRIVER .DXE
DXE_SMM_DRIVER .DXE
TOOL .FFS
UEFI_DRIVER .DXE
UEFI_APPLICATION .APP
USER_DEFINED .FFS
</pre>
@param moduleType module type
@return
@throws BuildException
If module type is null
**/
public static String getSuffix(String moduleType) throws BuildException {
if (moduleType == null) {
throw new BuildException("Module type is not specified.");
}
String[][] suffix = EdkDefinitions.ModuleTypeExtensions;
for (int i = 0; i < suffix.length; i++) {
if (suffix[i][0].equalsIgnoreCase(moduleType)) {
return suffix[i][1];
}
}
//
// Default is '.FFS'
//
return ".FFS";
}
/**
Add a property.
@param p property
**/
public void addProperty(Property p) {
properties.addElement(p);
}
public void setFpdFile(File fpdFile) {
this.fpdFile = fpdFile;
}
public void setType(String type) {
this.type = type;
}
public String getAllArchForModule(ModuleIdentification moduleId) {
String archs = "";
Iterator<FpdModuleIdentification> iter = outfiles.keySet().iterator();
while (iter.hasNext()) {
FpdModuleIdentification fpdModuleId = iter.next();
if (fpdModuleId.getModule().equals(moduleId)) {
archs += fpdModuleId.getArch() + " ";
}
}
return archs;
}
private Set<FpdModuleIdentification> getModuleSequenceForFv(String fvName) throws EdkException {
Node node = saq.getFpdModuleSequence(fvName);
Set<FpdModuleIdentification> result = new LinkedHashSet<FpdModuleIdentification>();
if ( node == null) {
EdkLog.log(this, EdkLog.EDK_WARNING, "FV[" + fvName + "] does not specify module sequence in FPD. Assuming present sequence as default sequence in FV. ");
return null;
} else {
NodeList childNodes = node.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node childItem = childNodes.item(i);
if (childItem.getNodeType() == Node.ELEMENT_NODE) {
//
// Find child elements "IncludeModules"
//
if (childItem.getNodeName().compareTo("IncludeModules") == 0) {
//
// result will be updated
//
processNodes(childItem, result);
} else if (childItem.getNodeName().compareTo("FvName") == 0) {
} else if (childItem.getNodeName().compareTo("InfFileName") == 0) {
} else {
//
// Report Warning
//
EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised element " + childItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1']");
}
}
}
}
return result;
}
private void processNodes(Node node, Set<FpdModuleIdentification> result) throws EdkException {
//
// Found out all elements "Module"
//
NodeList childNodes = node.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
Node childItem = childNodes.item(j);
if (childItem.getNodeType() == Node.ELEMENT_NODE) {
if (childItem.getNodeName().compareTo("Module") == 0) {
String moduleGuid = null;
String moduleVersion = null;
String packageGuid = null;
String packageVersion = null;
String arch = null;
NamedNodeMap attr = childItem.getAttributes();
for (int i = 0; i < attr.getLength(); i++) {
Node attrItem = attr.item(i);
if (attrItem.getNodeName().compareTo("ModuleGuid") == 0) {
moduleGuid = attrItem.getNodeValue();
} else if (attrItem.getNodeName().compareTo("ModuleVersion") == 0) {
moduleVersion = attrItem.getNodeValue();
} else if (attrItem.getNodeName().compareTo("PackageGuid") == 0) {
packageGuid = attrItem.getNodeValue();
} else if (attrItem.getNodeName().compareTo("PackageVersion") == 0) {
packageVersion = attrItem.getNodeValue();
} else if (attrItem.getNodeName().compareTo("Arch") == 0) {
arch = attrItem.getNodeValue();
} else {
//
// Report warning
//
EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised attribute " + attrItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules.Module");
}
}
PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);
GlobalData.refreshPackageIdentification(packageId);
ModuleIdentification moduleId = new ModuleIdentification(moduleGuid, moduleVersion);
moduleId.setPackage(packageId);
GlobalData.refreshModuleIdentification(moduleId);
if (arch == null) {
throw new EdkException("Attribute [Arch] is required for element FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules.Module. ");
}
result.add(new FpdModuleIdentification(moduleId, arch));
} else {
//
// Report Warning
//
EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised element " + childItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules");
}
}
}
}
}

View File

@ -0,0 +1,619 @@
/** @file
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.fpd;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.tianocore.build.global.GlobalData;
import org.tianocore.build.global.SurfaceAreaQuery;
import org.tianocore.build.id.FpdModuleIdentification;
import org.tianocore.build.id.ModuleIdentification;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
class PlatformBuildFileGenerator is used to generate ${PLATFORM}_build.xml file.
@since GenBuild 1.0
**/
public class PlatformBuildFileGenerator {
///
/// Mapping from modules identification to out put file name
///
private Map<FpdModuleIdentification, String> outfiles;
///
/// Mapping from FV name to its modules
///
private Map<String, Set<FpdModuleIdentification>> fvs = new HashMap<String, Set<FpdModuleIdentification>>();
private boolean isUnified = true;
private SurfaceAreaQuery saq = null;
private File platformBuildFile = null;
private Project project;
private String info = "DO NOT EDIT \n"
+ "This file is auto-generated by the build utility\n"
+ "\n"
+ "Abstract:\n"
+ "Auto-generated ANT build file for building EFI Modules and Platforms\n";
public PlatformBuildFileGenerator(Project project, Map<FpdModuleIdentification, String> outfiles, Map<String, Set<FpdModuleIdentification>> fvs, boolean isUnified, SurfaceAreaQuery saq, String platformBuildFile){
this.project = project;
this.outfiles = outfiles;
this.isUnified = isUnified;
this.fvs = fvs;
this.saq = saq;
this.platformBuildFile = new File(platformBuildFile);
}
/**
Generate build.out.xml file.
@throws BuildException
build.out.xml XML document create error
**/
public void genBuildFile() throws BuildException {
DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder dombuilder = domfac.newDocumentBuilder();
Document document = dombuilder.newDocument();
Comment rootComment = document.createComment(info);
//
// create root element and its attributes
//
Element root = document.createElement("project");
root.setAttribute("name", project.getProperty("PLATFORM"));
root.setAttribute("default", "all");
root.setAttribute("basedir", ".");
//
// element for External ANT tasks
//
root.appendChild(document.createComment("Apply external ANT tasks"));
Element ele = document.createElement("taskdef");
ele.setAttribute("resource", "GenBuild.tasks");
root.appendChild(ele);
ele = document.createElement("taskdef");
ele.setAttribute("resource", "frameworktasks.tasks");
root.appendChild(ele);
ele = document.createElement("taskdef");
ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
root.appendChild(ele);
ele = document.createElement("property");
ele.setAttribute("environment", "env");
root.appendChild(ele);
//
// Default Target
//
root.appendChild(document.createComment("Default target"));
ele = document.createElement("target");
ele.setAttribute("name", "all");
ele.setAttribute("depends", "prebuild, modules, fvs, postbuild");
root.appendChild(ele);
//
// Modules and Fvs Target
//
applyModules(document, root);
applyFvs(document, root);
//
// Clean Target
//
applyClean(document, root);
//
// Deep Clean Target
//
applyCleanall(document, root);
//
// User Extension pre build
//
applyUserExtensionsPreBuild(document, root);
//
// User Extension Post build
//
applyUserExtensionsPostBuild(document, root);
document.appendChild(rootComment);
document.appendChild(root);
//
// Prepare the DOM document for writing
//
Source source = new DOMSource(document);
//
// generate all directory path
//
(new File(platformBuildFile.getParent())).mkdirs();
Result result = new StreamResult(platformBuildFile);
//
// Write the DOM document to the file
//
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
xformer.setOutputProperty(OutputKeys.INDENT, "yes");
xformer.transform(source, result);
} catch (Exception ex) {
throw new BuildException("Generating platform build file [" + platformBuildFile.getPath() + "_build.xml] failed. \n" + ex.getMessage());
}
}
/**
1. Get All valid Fv Image Names in sequence
2. For each FV, get modules by sequences
3. Get other modules
@param document XML document
@param root Node
**/
private void applyModules(Document document, Node root) {
root.appendChild(document.createComment("Modules target"));
Element ele = document.createElement("target");
ele.setAttribute("name", "modules");
//
// Get all valid FV name
//
String[] validFv = saq.getFpdValidImageNames();
//
// For each valid FV, get all modules in sequence
//
for (int i = 0; i < validFv.length; i++) {
if (fvs.containsKey(validFv[i])) {
Set<FpdModuleIdentification> set = fvs.get(validFv[i]);
Iterator<FpdModuleIdentification> iter = set.iterator();
while (iter.hasNext()) {
FpdModuleIdentification fpdModuleId = iter.next();
applySingleModule(document, ele, fpdModuleId);
}
}
}
//
// Get all other modules
//
Iterator<String> fvsNameIter = fvs.keySet().iterator();
while (fvsNameIter.hasNext()) {
String fvName = fvsNameIter.next();
if (!isContain(validFv, fvName)) {
Set<FpdModuleIdentification> set = fvs.get(fvName);
Iterator iter = set.iterator();
while (iter.hasNext()) {
FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
applySingleModule(document, ele, fpdModuleId);
}
}
}
root.appendChild(ele);
}
private void applySingleModule(Document document, Node root, FpdModuleIdentification fpdModuleId) {
ModuleIdentification moduleId = fpdModuleId.getModule();
Element moduleEle = document.createElement("GenBuild");
moduleEle.setAttribute("type", "build");
//
// Inherit Properties.
//{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
//
//
// ARCH
//
Element property = document.createElement("property");
property.setAttribute("name", "ARCH");
property.setAttribute("value", fpdModuleId.getArch());
moduleEle.appendChild(property);
//
// MODULE_GUID
//
property = document.createElement("property");
property.setAttribute("name", "MODULE_GUID");
property.setAttribute("value", moduleId.getGuid());
moduleEle.appendChild(property);
//
// MODULE_VERSION
//
property = document.createElement("property");
property.setAttribute("name", "MODULE_VERSION");
property.setAttribute("value", moduleId.getVersion());
moduleEle.appendChild(property);
//
// PACKAGE_GUID
//
property = document.createElement("property");
property.setAttribute("name", "PACKAGE_GUID");
property.setAttribute("value", moduleId.getPackage().getGuid());
moduleEle.appendChild(property);
//
// PACKAGE_VERSION
//
property = document.createElement("property");
property.setAttribute("name", "PACKAGE_VERSION");
property.setAttribute("value", moduleId.getPackage().getVersion());
moduleEle.appendChild(property);
root.appendChild(moduleEle);
}
private boolean isContain(String[] list, String item) {
for (int i = 0; i < list.length; i++) {
if (list[i].equalsIgnoreCase(item)) {
return true;
}
}
return false;
}
private void applyFvs(Document document, Node root) {
//
// FVS Target
//
root.appendChild(document.createComment("FVs target"));
Element ele = document.createElement("target");
ele.setAttribute("name", "fvs");
//
// For every Target and ToolChain
//
String[] targetList = GlobalData.getToolChainInfo().getTargets();
for (int i = 0; i < targetList.length; i++){
String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
for(int j = 0; j < toolchainList.length; j++){
String fvOutputDir = project.getProperty("BUILD_DIR") + File.separatorChar
+ targetList[i] + "_"
+ toolchainList[j] + File.separatorChar + "FV";
String[] validFv = saq.getFpdValidImageNames();
for (int k = 0; k < validFv.length; k++) {
String inputFile = fvOutputDir + "" + File.separatorChar + validFv[k].toUpperCase() + ".inf";
Element fvEle = document.createElement("genfvimage");
fvEle.setAttribute("infFile", inputFile);
fvEle.setAttribute("outputDir", fvOutputDir);
ele.appendChild(fvEle);
}
}
}
root.appendChild(ele);
}
private void applyClean(Document document, Node root) {
//
// Clean Target
//
root.appendChild(document.createComment("Clean target"));
Element ele = document.createElement("target");
ele.setAttribute("name", "clean");
if (isUnified) {
Element cleanEle = document.createElement("delete");
cleanEle.setAttribute("includeemptydirs", "true");
Element filesetEle = document.createElement("fileset");
filesetEle.setAttribute("dir", project.getProperty("BUILD_DIR"));
filesetEle.setAttribute("includes", "**\\OUTPUT\\**");
cleanEle.appendChild(filesetEle);
ele.appendChild(cleanEle);
} else {
Set set = outfiles.keySet();
Iterator iter = set.iterator();
while (iter.hasNext()) {
FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
ModuleIdentification moduleId = fpdModuleId.getModule();
Element ifEle = document.createElement("if");
Element availableEle = document.createElement("available");
availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
+ "build.xml");
ifEle.appendChild(availableEle);
Element elseEle = document.createElement("then");
Element moduleEle = document.createElement("ant");
moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
+ "build.xml");
moduleEle.setAttribute("target", "clean");
//
// Inherit Properties.
//{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
//
//
// ARCH
//
Element property = document.createElement("property");
property.setAttribute("name", "ARCH");
property.setAttribute("value", fpdModuleId.getArch());
moduleEle.appendChild(property);
//
// PACKAGE
//
property = document.createElement("property");
property.setAttribute("name", "PACKAGE");
property.setAttribute("value", moduleId.getPackage().getName());
moduleEle.appendChild(property);
//
// PACKAGE_GUID
//
property = document.createElement("property");
property.setAttribute("name", "PACKAGE_GUID");
property.setAttribute("value", moduleId.getPackage().getGuid());
moduleEle.appendChild(property);
//
// PACKAGE_VERSION
//
property = document.createElement("property");
property.setAttribute("name", "PACKAGE_VERSION");
property.setAttribute("value", moduleId.getPackage().getVersion());
moduleEle.appendChild(property);
//
// MODULE_DIR
//
property = document.createElement("property");
property.setAttribute("name", "MODULE_DIR");
property.setAttribute("value", moduleId.getMsaFile().getParent());
moduleEle.appendChild(property);
elseEle.appendChild(moduleEle);
ifEle.appendChild(elseEle);
ele.appendChild(ifEle);
}
}
root.appendChild(ele);
}
private void applyCleanall(Document document, Node root) {
//
// Deep Clean Target
//
root.appendChild(document.createComment("Target: cleanall"));
Element ele = document.createElement("target");
ele.setAttribute("name", "cleanall");
if (isUnified) {
String[] targetList = GlobalData.getToolChainInfo().getTargets();
for (int i = 0; i < targetList.length; ++i) {
String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
for(int j = 0; j < toolchainList.length; j++) {
Element cleanAllEle = document.createElement("delete");
cleanAllEle.setAttribute("dir", project.getProperty("BUILD_DIR") + File.separatorChar + targetList[i] + "_" + toolchainList[j]);
ele.appendChild(cleanAllEle);
}
}
} else {
Set set = outfiles.keySet();
Iterator iter = set.iterator();
while (iter.hasNext()) {
FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
ModuleIdentification moduleId = fpdModuleId.getModule();
Element ifEle = document.createElement("if");
Element availableEle = document.createElement("available");
availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
+ "build.xml");
ifEle.appendChild(availableEle);
Element elseEle = document.createElement("then");
Element moduleEle = document.createElement("ant");
moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
+ "build.xml");
moduleEle.setAttribute("target", "cleanall");
//
// Inherit Properties.
//{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
//
//
// ARCH
//
Element property = document.createElement("property");
property.setAttribute("name", "ARCH");
property.setAttribute("value", fpdModuleId.getArch());
moduleEle.appendChild(property);
//
// PACKAGE
//
property = document.createElement("property");
property.setAttribute("name", "PACKAGE");
property.setAttribute("value", moduleId.getPackage().getName());
moduleEle.appendChild(property);
//
// PACKAGE_GUID
//
property = document.createElement("property");
property.setAttribute("name", "PACKAGE_GUID");
property.setAttribute("value", moduleId.getPackage().getGuid());
moduleEle.appendChild(property);
//
// PACKAGE_VERSION
//
property = document.createElement("property");
property.setAttribute("name", "PACKAGE_VERSION");
property.setAttribute("value", moduleId.getPackage().getVersion());
moduleEle.appendChild(property);
//
// MODULE_DIR
//
property = document.createElement("property");
property.setAttribute("name", "MODULE_DIR");
property.setAttribute("value", moduleId.getMsaFile().getParent());
moduleEle.appendChild(property);
elseEle.appendChild(moduleEle);
ifEle.appendChild(elseEle);
ele.appendChild(ifEle);
}
}
root.appendChild(ele);
}
private void applyUserExtensionsPreBuild(Document document, Node root) {
//
// User Extensions
//
root.appendChild(document.createComment("Pre-Build Processing"));
Element ele = document.createElement("target");
ele.setAttribute("name", "prebuild");
Node node = saq.getFpdUserExtensionPreBuild();
if (node != null) {
//
// For every Target and ToolChain
//
String[] targetList = GlobalData.getToolChainInfo().getTargets();
for (int i = 0; i < targetList.length; i++){
String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
for(int j = 0; j < toolchainList.length; j++){
//
// Prepare FV_DIR
//
String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
+ targetList[i] + "_"
+ toolchainList[j];
File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
Element fvEle = document.createElement("var");
fvEle.setAttribute("name", "FV_DIR");
fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));
ele.appendChild(fvEle);
Element targetDirEle = document.createElement("var");
targetDirEle.setAttribute("name", "TARGET_DIR");
targetDirEle.setAttribute("value", ffsCommonDir.replaceAll("(\\\\)", "/"));
ele.appendChild(targetDirEle);
NodeList childNodes = node.getChildNodes();
for (int k = 0; k < childNodes.getLength(); k++) {
Node childItem = childNodes.item(k);
if (childItem.getNodeType() == Node.ELEMENT_NODE) {
ele.appendChild(recursiveNode(childItem, document));
}
}
}
}
}
root.appendChild(ele);
}
private void applyUserExtensionsPostBuild(Document document, Node root) {
//
// User Extensions
//
root.appendChild(document.createComment("Post-Build Processing"));
Element ele = document.createElement("target");
ele.setAttribute("name", "postbuild");
Node node = saq.getFpdUserExtensionPostBuild();
if (node != null) {
//
// For every Target and ToolChain
//
String[] targetList = GlobalData.getToolChainInfo().getTargets();
for (int i = 0; i < targetList.length; i++){
String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
for(int j = 0; j < toolchainList.length; j++){
//
// Prepare FV_DIR
//
String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
+ targetList[i] + "_"
+ toolchainList[j];
File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
Element fvEle = document.createElement("var");
fvEle.setAttribute("name", "FV_DIR");
fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));
ele.appendChild(fvEle);
Element targetDirEle = document.createElement("var");
targetDirEle.setAttribute("name", "TARGET_DIR");
targetDirEle.setAttribute("value", ffsCommonDir.replaceAll("(\\\\)", "/"));
ele.appendChild(targetDirEle);
NodeList childNodes = node.getChildNodes();
for (int k = 0; k < childNodes.getLength(); k++) {
Node childItem = childNodes.item(k);
if (childItem.getNodeType() == Node.ELEMENT_NODE) {
ele.appendChild(recursiveNode(childItem, document));
}
}
}
}
}
root.appendChild(ele);
}
private Element recursiveNode(Node node, Document document) {
Element root = document.createElement(node.getNodeName());
NamedNodeMap attr = node.getAttributes();
for (int i = 0; i < attr.getLength(); i++) {
Node attrItem = attr.item(i);
root.setAttribute(attrItem.getNodeName(), attrItem.getNodeValue());
}
NodeList childNodes = node.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node childItem = childNodes.item(i);
if (childItem.getNodeType() == Node.ELEMENT_NODE) {
root.appendChild(recursiveNode(childItem, document));
}
else if (childItem.getNodeType() == Node.TEXT_NODE){
if (!childItem.getNodeValue().trim().equalsIgnoreCase("")) {
root.setTextContent(childItem.getNodeValue());
}
}
}
return root;
}
}

View File

@ -0,0 +1,130 @@
/** @file
This file is used to define class which represents dependency file in ANT task
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.global;
import org.apache.tools.ant.types.DataType;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.BuildException;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
DpFile is a ANT DataType which can be used to specify dependency files from
a file list file, from file list string separated by space, comma or semi-comma,
or from file name with absolute path
**/
public class DpFile extends DataType {
///
/// keep the list of files path
///
private List<String> nameList = new ArrayList<String>();
/**
Empty constructor just in case
**/
public DpFile() {
}
/**
Empty execute method of ANT task, just in case
**/
public void execute() {
}
/**
Standard set method of ANT task/datatype, for ListFile attribute. It simply
fetch one file path a line from specified list file, and put them in nameList
@param fileListFile file which contains a file list, one file a line,
with full path
**/
public void setListFile(String fileListFile) {
File file = new File(fileListFile);
if (!file.exists()) {
return;
}
try {
FileReader fileReader = new FileReader(file);
LineNumberReader lineReader = new LineNumberReader(fileReader);
String filePath = null;
while ((filePath = lineReader.readLine()) != null) {
filePath = filePath.trim();
if (filePath.length() == 0) {
continue;
}
this.nameList.add(filePath);
}
lineReader.close();
fileReader.close();
} catch (IOException e) {
throw new BuildException(e.getMessage());
}
}
/**
Standard set method of ANT task/datatype, for List attribute.
@param fileList string with file pathes separated by space, comma,
or semi-comma
**/
public void setList(String fileList) {
//
// space, comma or semi-comma separated files list
//
Pattern pattern = Pattern.compile("([^ ,;\n\r]++)[ ,;\n\r]*+");
Matcher matcher = pattern.matcher(fileList);
while (matcher.find()) {
//
// keep each file name before " ,;\n\r"
//
String filePath = fileList.substring(matcher.start(1), matcher.end(1)).trim();
if (filePath.length() == 0) {
continue;
}
nameList.add(Path.translateFile(filePath));
}
}
/**
Standard set method of ANT task/datatype, for Name attribute.
@param fileName string of a file full path
**/
public void setName(String fileName) {
this.nameList.add(fileName);
}
/**
Fetch the file name list.
@returns A string list which contains file names specified to check dependnecy
**/
public List<String> getList() {
return this.nameList;
}
}

View File

@ -0,0 +1,64 @@
/** @file
This file is used to nest elements corresponding to DpFile
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.global;
import java.util.ArrayList;
import java.util.List;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.DataType;
import org.apache.tools.ant.types.FileSet;
/**
DpFileList is a container of Dpfile at the point of ANT task/datatype
**/
public class DpFileList extends DataType {
///
/// Keep all the file names from all nested DpFile
///
List<String> nameList = new ArrayList<String>();
/**
Empty constructor just in case
**/
public DpFileList() {
}
/**
Empty execute method of ANT task. ANT will call it even we don't need it.
**/
public void execute() {
}
/**
Standard add method of ANT task, for nested DpFile type of elements. It just
simply fetch the files list from DpFile and put them in its own nameList.
@param f a DpFile object which will be instantiated by ANT
**/
public void addConfiguredFile(DpFile f) {
this.nameList.addAll(f.getList());
}
public void addConfiguredFileSet(FileSet fileSet) {
DirectoryScanner ds = fileSet.getDirectoryScanner(getProject());
String dir = fileSet.getDir(getProject()).getAbsolutePath();
String[] files = ds.getIncludedFiles();
for (int i = 0; i < files.length; ++i) {
nameList.add(dir + "/" + files[i]);
}
}
}

View File

@ -0,0 +1,274 @@
/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
GenBuildLogger.java
Abstract:
--*/
package org.tianocore.build.global;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.util.StringUtils;
import org.tianocore.build.id.FpdModuleIdentification;
import org.tianocore.common.logger.EdkLog;
import org.tianocore.common.logger.LogMethod;
public class GenBuildLogger extends DefaultLogger implements LogMethod {
Project project = null;
///
/// flag to present whether cache all msg or not
/// true means to cache.
///
private static boolean flag = false;
private static boolean enableFlag = true;
private static Map<FpdModuleIdentification, List<String>> map = new LinkedHashMap<FpdModuleIdentification, List<String> >(256);
private FpdModuleIdentification id = null;
public GenBuildLogger () {
}
public GenBuildLogger (Project project) {
this.project = project;
}
/**
Rules: flag = false: means no cache Action: Print it to console
flag = true: mean cache all msg exception some special Action: loglevel
is EDK_ALWAYS -- Print but no cache loglevel is EDK_ERROR -- Print and
cache the msg others -- No print and cache the msg
**/
public synchronized void putMessage(Object msgSource, int msgLevel, String msg) {
if (this.project == null) {
return;
}
//
// If msgLevel is always print, then print it
//
switch (msgLevel) {
case EdkLog.EDK_ALWAYS:
//
// Do some special
//
log(msgSource, msg, Project.MSG_ERR);
break;
case EdkLog.EDK_ERROR:
log(msgSource, msg, Project.MSG_ERR);
break;
case EdkLog.EDK_WARNING:
log(msgSource, msg, Project.MSG_WARN);
break;
case EdkLog.EDK_INFO:
log(msgSource, msg, Project.MSG_INFO);
break;
case EdkLog.EDK_VERBOSE:
log(msgSource, msg, Project.MSG_VERBOSE);
break;
case EdkLog.EDK_DEBUG:
log(msgSource, msg, Project.MSG_DEBUG);
break;
}
}
public static void flushErrorModuleLog(FpdModuleIdentification errorModuleId) {
List<String> errorLogs = map.get(errorModuleId);
if (errorLogs != null) {
EdkLog.log("ErrorLog", EdkLog.EDK_ERROR, errorModuleId + " error logs: ");
for(int i = 0; i < errorLogs.size(); i++) {
EdkLog.log(EdkLog.EDK_ERROR, errorLogs.get(i));
}
}
}
public void flushToFile(File file) {
//
// Put all messages in map to file
//
String msg = "Writing log to file [" + file.getPath() + "]";
log("Logging", msg, Project.MSG_INFO);
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
Iterator<FpdModuleIdentification> iter = map.keySet().iterator();
List<String> mainLogs = null;
while (iter.hasNext()) {
FpdModuleIdentification item = iter.next();
if(item == null) {
mainLogs = map.get(item);
continue ;
}
bw.write(">>>>>>>>>>>>>");
bw.write(" " + item + " Build Log ");
bw.write(">>>>>>>>>>>>>");
bw.newLine();
List<String> allMessages = map.get(item);
for(int i = 0; i < allMessages.size(); i++) {
bw.write(allMessages.get(i));
bw.newLine();
}
}
if (mainLogs != null) {
bw.write(">>>>>>>>>>>>>");
bw.write(" Main Logs (already print to command) ");
bw.write(">>>>>>>>>>>>>");
bw.newLine();
for(int i = 0; i < mainLogs.size(); i++) {
bw.write(mainLogs.get(i));
bw.newLine();
}
}
bw.flush();
bw.close();
} catch (IOException e) {
new BuildException("Writing log error. " + e.getMessage());
}
}
private void log(Object msgSource, String msg, int level) {
if (msgSource instanceof Task) {
((Task)msgSource).getProject().log((Task)msgSource, msg, level);
} else if (msgSource instanceof String){
//
// Pad 12 space to keep message in unify format
//
msg = msg.replaceAll("\n", "\n ");
this.project.log(String.format("%12s", "[" + msgSource + "] ") + msg, level);
} else {
this.project.log(msg, level);
}
}
public void targetStarted(BuildEvent event) {
if (!flag) {
super.targetStarted(event);
}
}
public void messageLogged(BuildEvent event) {
if (!enableFlag) {
return ;
}
int currentLevel = event.getPriority();
//
// If current level is upper than Ant Level, skip it
//
if (currentLevel <= this.msgOutputLevel) {
String originalMessage = event.getMessage();
StringBuffer message = new StringBuffer();
if (!emacsMode && event.getTask() != null) {
String label = String.format("%12s", "[" + event.getTask().getTaskName() + "] ");
//
// Append label first
//
message.append(label);
//
// Format all output message's line separator
//
try {
BufferedReader r = new BufferedReader(new StringReader(originalMessage));
boolean ifFirstLine = true;
String line = null;
while ((line = r.readLine()) != null) {
if (!ifFirstLine) {
message.append(StringUtils.LINE_SEP);
}
ifFirstLine = false;
message.append(line);
}
} catch (IOException e) {
message.append(originalMessage);
}
} else {
message.append(originalMessage);
}
String msg = message.toString();
if (currentLevel == Project.MSG_ERR) {
printMessage(msg, err, currentLevel);
} else if(currentLevel == Project.MSG_WARN) {
printMessage(msg, out, currentLevel);
} else if(!flag) {
printMessage(msg, out, currentLevel);
}
log(msg);
}
}
public static void setCacheEnable(boolean enable) {
flag = enable;
}
public static void maskAllLog(boolean enable) {
enableFlag = !enable;
}
protected synchronized void log(String message) {
//
// cache log
//
if (map.containsKey(this.id)) {
map.get(this.id).add(message);
} else {
List<String> list = new Vector<String>(1024);
list.add(message);
map.put(this.id, list);
}
}
public Object clone() {
GenBuildLogger newLogger = new GenBuildLogger();
//
// Transfer emacs mode, out, err, level to new Logger
//
newLogger.setEmacsMode(this.emacsMode);
newLogger.setOutputPrintStream(this.out);
newLogger.setErrorPrintStream(this.err);
newLogger.setMessageOutputLevel(this.msgOutputLevel);
//
// Transfer project
//
newLogger.project = this.project;
return newLogger;
}
public void setId(FpdModuleIdentification id) {
this.id = id;
}
}

View File

@ -0,0 +1,958 @@
/** @file
GlobalData class.
GlobalData provide initializing, instoring, querying and update global data.
It is a bridge to intercommunicate between multiple component, such as AutoGen,
PCD and so on.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.global;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.tianocore.common.exception.EdkException;
import org.tianocore.common.logger.EdkLog;
import org.tianocore.pcd.entity.MemoryDatabaseManager;
import org.tianocore.DbPathAndFilename;
import org.tianocore.FrameworkDatabaseDocument;
import org.tianocore.ModuleSurfaceAreaDocument;
import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea;
import org.tianocore.build.id.FpdModuleIdentification;
import org.tianocore.build.id.ModuleIdentification;
import org.tianocore.build.id.PackageIdentification;
import org.tianocore.build.id.PlatformIdentification;
import org.tianocore.build.toolchain.ToolChainAttribute;
import org.tianocore.build.toolchain.ToolChainConfig;
import org.tianocore.build.toolchain.ToolChainElement;
import org.tianocore.build.toolchain.ToolChainInfo;
import org.tianocore.build.toolchain.ToolChainKey;
import org.tianocore.build.toolchain.ToolChainMap;
/**
GlobalData provide initializing, instoring, querying and update global data.
It is a bridge to intercommunicate between multiple component, such as AutoGen,
PCD and so on.
<p>Note that all global information are initialized incrementally. All data will
parse and record only of necessary during build time. </p>
@since GenBuild 1.0
**/
public class GlobalData {
///
/// Record current WORKSPACE Directory
///
private static String workspaceDir = "";
///
/// Be used to ensure Global data will be initialized only once.
///
private static boolean globalFlag = false;
///
/// Framework Database information: package list and platform list
///
private static Set<PackageIdentification> packageList = new HashSet<PackageIdentification>();
private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();
///
/// Every detail SPD informations: Module list, Library class definition,
/// Package header file, GUID/PPI/Protocol definitions
///
private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();
///
/// Build informations are divided into three parts:
/// 1. From MSA 2. From FPD 3. From FPD' ModuleSA
///
private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();
private static Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
private static Map<String, XmlObject> fpdBuildOptionsMap = new HashMap<String, XmlObject>();
private static XmlObject fpdBuildOptions;
private static XmlObject fpdDynamicPcds;
///
/// Parsed modules list
///
private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
///
/// built modules list with ARCH, TARGET, TOOLCHAIN
///
private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();
///
/// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.
///
private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();
///
/// build target + tool chain family/tag name + arch + command types + command options
///
///
/// Tool Chain Data
/// toolsDef - build tool program information
/// fpdBuildOption - all modules's build options for tool tag or tool chain families
/// moduleSaBuildOption - build options for a specific module
///
private static ToolChainConfig toolsDef;
private static ToolChainInfo toolChainInfo;
private static ToolChainInfo toolChainEnvInfo;
private static ToolChainInfo toolChainPlatformInfo;
private static ToolChainMap platformToolChainOption;
private static ToolChainMap platformToolChainFamilyOption;
private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainOption = new HashMap<FpdModuleIdentification, ToolChainMap>();
private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainFamilyOption = new HashMap<FpdModuleIdentification, ToolChainMap>();
/**
Parse framework database (DB) and all SPD files listed in DB to initialize
the environment for next build. This method will only be executed only once
in the whole build process.
@param workspaceDatabaseFile the file name of framework database
@param workspaceDir current workspace directory path
@throws BuildException
Framework Dababase or SPD or MSA file is not valid
**/
public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir, String toolsDefFilename ) throws EdkException {
//
// ensure this method will be revoked only once
//
if (globalFlag) {
return;
}
globalFlag = true;
//
// Backup workspace directory. It will be used by other method
//
GlobalData.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/");
//
// Parse tools definition file
//
//
// If ToolChain has been set up before, do nothing.
// CONF dir + tools definition file name
//
File toolsDefFile = new File(workspaceDir + File.separatorChar + toolsDefFilename);
EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Using tool definition file [" + toolsDefFile.getPath() + "].");
toolsDef = new ToolChainConfig(toolsDefFile);
//
// Parse Framework Database
//
File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
try {
FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);
//
// validate FrameworkDatabaseFile
//
if (!db.validate()) {
throw new EdkException("Framework Database file [" + dbFile.getPath() + "] format is invalid!");
}
//
// Get package list
//
if (db.getFrameworkDatabase().getPackageList() != null ) {
List<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();
Iterator<DbPathAndFilename> iter = packages.iterator();
while (iter.hasNext()) {
String fileName = iter.next().getStringValue().trim();
Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));
packageList.add(spd.getPackageId());
//
// Report warning if existing two packages with same GUID and Version
//
if (spdTable.containsKey(spd.getPackageId())) {
//
// BUGBUG
//
EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two packages with same GUID and Version. They are ... " + spd.getPackageId().getSpdFile().getPath());
}
spdTable.put(spd.getPackageId(), spd);
}
}
//
// Get platform list
//
if (db.getFrameworkDatabase().getPlatformList() != null) {
List<DbPathAndFilename> platforms = db.getFrameworkDatabase().getPlatformList().getFilenameList();
Iterator<DbPathAndFilename> iter = platforms.iterator();
while (iter.hasNext()) {
String fileName = iter.next().getStringValue().trim();
File fpdFile = new File(workspaceDir + File.separatorChar + fileName);
if ( !fpdFile.exists() ) {
throw new EdkException("Platform file [" + fpdFile.getPath() + "] not exists. ");
}
XmlObject fpdDoc = XmlObject.Factory.parse(fpdFile);
//
// Verify FPD file, if is invalid, throw Exception
//
if (!fpdDoc.validate()) {
throw new EdkException("Framework Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!");
}
//
// We can change Map to XmlObject
//
Map<String, XmlObject> fpdDocMap = new HashMap<String, XmlObject>();
fpdDocMap.put("PlatformSurfaceArea", fpdDoc);
SurfaceAreaQuery saq = new SurfaceAreaQuery(fpdDocMap);
PlatformIdentification platformId = saq.getFpdHeader();
platformId.setFpdFile(fpdFile);
//
// Report warning if existing two platfrom with same GUID and Version
//
if (platformList.contains(platformId)) {
//
// BUGBUG
//
EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two platforms with same GUID and Version. They are ... " + fpdFile.getPath());
}
platformList.add(platformId);
}
}
} catch(IOException ex) {
EdkException edkException = new EdkException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + ex.getMessage());
edkException.setStackTrace(ex.getStackTrace());
throw edkException;
} catch(XmlException ex) {
EdkException edkException = new EdkException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + ex.getMessage());
edkException.setStackTrace(ex.getStackTrace());
throw edkException;
}
}
/**
Get the current WORKSPACE Directory.
@return current workspace directory
**/
public synchronized static String getWorkspacePath() {
return workspaceDir;
}
/**
Get the MSA file name with absolute path
*/
public synchronized static File getMsaFile(ModuleIdentification moduleId) throws EdkException {
File msaFile = null;
//
// TBD. Do only when package is null.
//
Iterator iter = packageList.iterator();
while (iter.hasNext()) {
PackageIdentification packageId = (PackageIdentification)iter.next();
Spd spd = spdTable.get(packageId);
msaFile = spd.getModuleFile(moduleId);
if (msaFile != null ) {
break ;
}
}
if (msaFile == null){
throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");
} else {
return msaFile;
}
}
public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) throws EdkException {
//
// If package already defined in module
//
if (moduleId.getPackage() != null) {
return moduleId.getPackage();
}
PackageIdentification packageId = null;
Iterator iter = packageList.iterator();
while (iter.hasNext()) {
packageId = (PackageIdentification)iter.next();
moduleId.setPackage(packageId);
Spd spd = spdTable.get(packageId);
File tempMsaFile = null;
if ((tempMsaFile = spd.getModuleFile(moduleId)) != null ) {
if (tempMsaFile.getParent().equalsIgnoreCase(moduleId.getMsaFile().getParent())) {
break ;
}
tempMsaFile = null;
}
}
if (packageId == null){
throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");
} else {
return packageId;
}
}
/**
Difference between build and parse: ToolChain and Target
**/
public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {
return builtModules.contains(moduleId);
}
public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {
builtModules.add(fpdModuleId);
}
public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws EdkException{
Map<String, XmlObject> result = new HashMap<String, XmlObject>();
Set keySet = doc.keySet();
Iterator iter = keySet.iterator();
while (iter.hasNext()){
String key = (String)iter.next();
XmlObject item = cloneXmlObject(doc.get(key), true);
result.put(key, item);
}
fpdModuleSA.put(fpdModuleId, result);
}
public synchronized static boolean hasFpdModuleSA(FpdModuleIdentification fpdModuleId) {
return fpdModuleSA.containsKey(fpdModuleId);
}
/**
Query module surface area information.
<p>Note that surface area parsing is incremental. That means the method will
only parse the MSA files if necessary. </p>
@param fpdModuleId Module ID with arch
@return ModuleSA info and MSA info for fpdModuleId
@throws BuildException Can't find MSA
**/
public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws EdkException{
if (parsedModules.containsKey(fpdModuleId)) {
return parsedModules.get(fpdModuleId);
}
Map<String, XmlObject> doc = new HashMap<String, XmlObject>();
ModuleIdentification moduleId = fpdModuleId.getModule();
//
// First part: get the MSA files info
//
doc.putAll(getNativeMsa(moduleId));
//
// Second part: put build options
//
doc.put("BuildOptions", fpdBuildOptions);
//
// Third part: get Module info from FPD, such as Library instances, PCDs
//
if (fpdModuleSA.containsKey(fpdModuleId)){
//
// merge module info in FPD to final Doc
// For Library Module, do nothing here
//
doc.putAll(fpdModuleSA.get(fpdModuleId));
}
parsedModules.put(fpdModuleId, doc);
return doc;
}
public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws EdkException{
FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);
return getDoc(fpdModuleId);
}
/**
Query the native MSA information with module base name.
<p>Note that MSA parsing is incremental. That means the method will
only to parse the MSA files when never parsed before. </p>
@param moduleName the base name of the module
@return the native MSA information
@throws BuildException
MSA file is not valid
**/
public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws EdkException {
if (nativeMsa.containsKey(moduleId)) {
return nativeMsa.get(moduleId);
}
File msaFile = getMsaFile(moduleId);
Map<String, XmlObject> msaMap = getNativeMsa(msaFile);
nativeMsa.put(moduleId, msaMap);
return msaMap;
}
public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws EdkException {
if (!msaFile.exists()) {
throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] can't be found!");
}
try {
ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile);
//
// Validate File if they accord with XML Schema
//
if ( !doc.validate()){
throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] format is invalid!");
}
//
// parse MSA file
//
ModuleSurfaceArea msa= doc.getModuleSurfaceArea();
Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();
msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));
msaMap.put("ModuleDefinitions", cloneXmlObject(msa.getModuleDefinitions(), true));
msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));
msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));
msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));
msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));
msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));
msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));
msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));
msaMap.put("PcdCoded", cloneXmlObject(msa.getPcdCoded(), true));
return msaMap;
} catch(IOException ex) {
EdkException edkException = new EdkException("Parsing MSA file [" + msaFile.getPath() + "] error. \n" + ex.getMessage());
edkException.setStackTrace(ex.getStackTrace());
throw edkException;
} catch(XmlException ex) {
EdkException edkException = new EdkException("Parsing MSA file [" + msaFile.getPath() + "] error. \n" + ex.getMessage());
edkException.setStackTrace(ex.getStackTrace());
throw edkException;
}
}
public static Map<String, XmlObject> getFpdBuildOptionsMap() {
return fpdBuildOptionsMap;
}
public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws EdkException {
GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);
fpdBuildOptionsMap.put("BuildOptions", GlobalData.fpdBuildOptions);
}
public static XmlObject getFpdDynamicPcds() {
return fpdDynamicPcds;
}
public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {
GlobalData.fpdDynamicPcds = fpdDynamicPcds;
}
public static Set<ModuleIdentification> getModules(PackageIdentification packageId){
Spd spd = spdTable.get(packageId);
if (spd == null ) {
Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();
return dummy;
} else {
return spd.getModules();
}
}
/**
* The header file path is relative to workspace dir
*/
public static String[] getLibraryClassHeaderFiles(
PackageIdentification[] packages, String name) throws EdkException{
if (packages == null) {
// throw Exception or not????
return new String[0];
}
String[] result = null;
for (int i = 0; i < packages.length; i++) {
Spd spd = spdTable.get(packages[i]);
//
// If find one package defined the library class
//
if ((result = spd.getLibClassIncluder(name)) != null) {
return result;
}
}
//
// If can't find library class declaration in every package
//
throw new EdkException("Can not find library class [" + name
+ "] declaration in any SPD package!");
}
/**
* The header file path is relative to workspace dir
*/
public static String getPackageHeaderFiles(PackageIdentification packages,
String moduleType) {
if (packages == null) {
return new String("");
}
Spd spd = spdTable.get(packages);
//
// If can't find package header file, skip it
//
String temp = null;
if (spd != null) {
if ((temp = spd.getPackageIncluder(moduleType)) != null) {
return temp;
} else {
temp = "";
return temp;
}
} else {
return null;
}
}
/**
* return two values: {cName, GuidValue}
*/
public static String[] getGuid(List<PackageIdentification> packages, String name) {
if (packages == null) {
// throw Exception or not????
return new String[0];
}
String[] result = null;
Iterator item = packages.iterator();
while (item.hasNext()){
Spd spd = spdTable.get(item.next());
//
// If find one package defined the GUID
//
if ((result = spd.getGuid(name)) != null) {
return result;
}
}
return null;
}
/**
* return two values: {cName, GuidValue}
*/
public static String[] getPpiGuid(List<PackageIdentification> packages,
String name) {
if (packages == null) {
return new String[0];
}
String[] result = null;
Iterator item = packages.iterator();
while (item.hasNext()){
Spd spd = spdTable.get(item.next());
//
// If find one package defined the Ppi GUID
//
if ((result = spd.getPpi(name)) != null) {
return result;
}
}
return null;
}
/**
* return two values: {cName, GuidValue}
*/
public static String[] getProtocolGuid(List<PackageIdentification> packages,
String name) {
if (packages == null) {
return new String[0];
}
String[] result = null;
Iterator item = packages.iterator();
while (item.hasNext()){
Spd spd = spdTable.get(item.next());
//
// If find one package defined the protocol GUID
//
if ((result = spd.getProtocol(name))!= null){
return result;
}
}
return null;
}
public synchronized static PlatformIdentification getPlatformByName(String name) throws EdkException {
Iterator iter = platformList.iterator();
while(iter.hasNext()){
PlatformIdentification platformId = (PlatformIdentification)iter.next();
if (platformId.getName().equalsIgnoreCase(name)) {
return platformId;
}
}
throw new EdkException("Can't find platform [" + name + "] in the current WORKSPACE database!");
}
public synchronized static PlatformIdentification getPlatform(String filename) throws EdkException {
File file = new File(workspaceDir + File.separatorChar + filename);
Iterator iter = platformList.iterator();
while(iter.hasNext()){
PlatformIdentification platformId = (PlatformIdentification)iter.next();
if (platformId.getFpdFile().getPath().equalsIgnoreCase(file.getPath())) {
return platformId;
}
}
throw new EdkException("Can't find platform file [" + filename + "] in the current WORKSPACE database!");
}
public synchronized static PackageIdentification refreshPackageIdentification(PackageIdentification packageId) throws EdkException {
Iterator iter = packageList.iterator();
while(iter.hasNext()){
PackageIdentification packageItem = (PackageIdentification)iter.next();
if (packageItem.equals(packageId)) {
packageId.setName(packageItem.getName());
packageId.setSpdFile(packageItem.getSpdFile());
return packageId;
}
}
throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");
}
public synchronized static ModuleIdentification refreshModuleIdentification(ModuleIdentification moduleId) throws EdkException {
PackageIdentification packageId = getPackageForModule(moduleId);
moduleId.setPackage(packageId);
Spd spd = spdTable.get(packageId);
if (spd == null) {
throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");
}
Set<ModuleIdentification> modules = spd.getModules();
Iterator<ModuleIdentification> iter = modules.iterator();
while (iter.hasNext()) {
ModuleIdentification item = iter.next();
if (item.equals(moduleId)) {
moduleId.setName(item.getName());
moduleId.setModuleType(item.getModuleType());
moduleId.setMsaFile(item.getMsaFile());
return moduleId;
}
}
throw new EdkException("Can't find module GUID value " + moduleId.toGuidString() + " in " + packageId + " under the current workspace!");
}
public synchronized static Set<PackageIdentification> getPackageList(){
return packageList;
}
/**
BUGBUG: It is a walk around method. If do not clone, can't query info with
XPath correctly.
@param object XmlObject
@param deep flag for deep clone
@return XmlObject after clone
@throws BuildException parse original XmlObject error.
**/
private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws EdkException {
if ( object == null) {
return null;
}
XmlObject result = null;
try {
result = XmlObject.Factory.parse(object.getDomNode()
.cloneNode(deep));
} catch (XmlException ex) {
EdkException edkException = new EdkException(ex.getMessage());
edkException.setStackTrace(ex.getStackTrace());
throw edkException;
}
return result;
}
///
/// Tool Chain Related, try to refine and put some logic process to ToolChainFactory
///
public synchronized static ToolChainInfo getToolChainInfo() {
if (toolChainInfo == null) {
toolChainInfo = toolsDef.getConfigInfo().intersection(toolChainEnvInfo);
if (toolChainPlatformInfo != null) {
toolChainInfo = toolChainInfo.intersection(toolChainPlatformInfo);
}
toolChainInfo.addCommands(toolsDef.getConfigInfo().getCommands());
toolChainInfo.normalize();
EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Current build tool chain information summary: ");
EdkLog.log("Init", EdkLog.EDK_ALWAYS, toolChainInfo + "");
}
return toolChainInfo;
}
public static void setPlatformToolChainFamilyOption(ToolChainMap map) {
platformToolChainFamilyOption = map;
}
public static void setPlatformToolChainOption(ToolChainMap map) {
platformToolChainOption = map;
}
public static void addModuleToolChainOption(FpdModuleIdentification fpdModuleId,
ToolChainMap toolChainOption) {
moduleToolChainOption.put(fpdModuleId, toolChainOption);
}
public static void addModuleToolChainFamilyOption(FpdModuleIdentification fpdModuleId,
ToolChainMap toolChainOption) {
moduleToolChainFamilyOption.put(fpdModuleId, toolChainOption);
}
public static boolean isCommandSet(String target, String toolchain, String arch) {
String[] commands = getToolChainInfo().getCommands();
for (int i = 0; i < commands.length; ++i) {
String cmdName = toolsDef.getConfig().get(new String[] {target, toolchain, arch, commands[i], ToolChainAttribute.NAME.toString()});
if (cmdName != null && cmdName.length() != 0) {
return true;
}
}
return false;
}
public synchronized static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) throws EdkException {
ToolChainKey toolChainKey = new ToolChainKey(commandDescription);
ToolChainMap toolChainConfig = toolsDef.getConfig();
String setting = null;
setting = toolChainConfig.get(toolChainKey);
if (setting == null) {
setting = "";
}
if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolChainAttribute.FLAGS.toString())) {
return setting;
}
//
// get module specific options, if any
//
// tool tag first
ToolChainMap option = moduleToolChainOption.get(fpdModuleId);
ToolChainKey toolChainFamilyKey = null;
if (option != null && option.get(toolChainKey) != null)
{
String str = option.get(toolChainKey);
Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
Matcher matcher = myPattern.matcher(str + " ");
while (matcher.find())
{
setting = setting + " " + str.substring(matcher.start(1), matcher.end(1));
}
}
// else
// {
if (toolChainFamilyKey == null)
{
toolChainFamilyKey = new ToolChainKey(commandDescription);
toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value);
String family = toolChainConfig.get(toolChainFamilyKey);
toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value);
}
option = moduleToolChainFamilyOption.get(fpdModuleId);
if (option != null && option.get(toolChainFamilyKey) != null)
{
String str = option.get(toolChainFamilyKey);
Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
Matcher matcher = myPattern.matcher(str + " ");
while (matcher.find())
{
setting = setting + " " + str.substring(matcher.start(1), matcher.end(1));
}
}
// }
//
// get platform options, if any
//
// tool tag first
// if (platformToolChainOption != null && platformToolChainOption.get(toolChainKey) != null)
if (platformToolChainOption.get(toolChainKey) != null)
{
String str = platformToolChainOption.get(toolChainKey);
Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
Matcher matcher = myPattern.matcher(str + " ");
while (matcher.find())
{
setting = setting + " " + str.substring(matcher.start(1), matcher.end(1));
}
}
// else
// {
// then tool chain family
if (toolChainFamilyKey == null)
{
toolChainFamilyKey = new ToolChainKey(commandDescription);
toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value);
String family = toolChainConfig.get(toolChainFamilyKey);
toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value);
}
// if (platformToolChainFamilyOption != null && platformToolChainFamilyOption.get(toolChainFamilyKey) != null)
if (platformToolChainFamilyOption.get(toolChainFamilyKey) != null)
{
String str = platformToolChainFamilyOption.get(toolChainFamilyKey);
setting = setting + " " + str;
// Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
// Matcher matcher = myPattern.matcher(str + " ");
// while (matcher.find())
// {
// setting = setting + " " + str.substring(matcher.start(1), matcher.end(1));
// }
}
// }
return setting;
/*
//
// get module specific options, if any
//
// tool tag first
ToolChainMap option = moduleToolChainOption.get(fpdModuleId);
ToolChainKey toolChainFamilyKey = null;
if ((option == null) || (option != null && (setting = option.get(toolChainKey)) == null))
{
//
// then tool chain family
//
toolChainFamilyKey = new ToolChainKey(commandDescription);
toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value);
String family = toolChainConfig.get(toolChainFamilyKey);
toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value);
option = moduleToolChainFamilyOption.get(fpdModuleId);
if (option != null) {
setting = option.get(toolChainFamilyKey);
}
}
//
// get platform options, if any
//
if (setting == null) {
// tool tag first
if (platformToolChainOption == null || (setting = platformToolChainOption.get(toolChainKey)) == null) {
// then tool chain family
if (toolChainFamilyKey == null) {
toolChainFamilyKey = new ToolChainKey(commandDescription);
toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value);
String family = toolChainConfig.get(toolChainFamilyKey);
toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value);
}
setting = platformToolChainFamilyOption.get(toolChainFamilyKey);
}
}
if (setting == null) {
setting = "";
}
return setting;
*/
}
public static void setToolChainEnvInfo(ToolChainInfo envInfo) {
toolChainEnvInfo = envInfo;
}
public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) {
toolChainPlatformInfo = platformInfo;
}
//
// for PCD
//
public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
return pcdDbManager;
}
//
// For PCD get tokenSpaceGUid
//
public synchronized static String getGuidInfoFromCname(String cName){
String cNameGuid = null;
String guid = null;
Set set = spdTable.keySet();
Iterator iter = set.iterator();
if (iter == null) {
return null;
}
while (iter.hasNext()){
Spd spd = (Spd) spdTable.get(iter.next());
guid = spd.getGuidFromCname(cName);
if (guid != null){
cNameGuid = guid;
break;
}
}
return cNameGuid;
}
//
// For PCD
//
public synchronized static Map<FpdModuleIdentification, XmlObject>
getFpdModuleSaXmlObject(String xmlObjectName) {
Set<FpdModuleIdentification> fpdModuleSASet = fpdModuleSA.keySet();
Iterator item = fpdModuleSASet.iterator();
Map<FpdModuleIdentification, XmlObject> SAPcdBuildDef = new HashMap<FpdModuleIdentification, XmlObject>();
Map<String, XmlObject> SANode = new HashMap<String, XmlObject>();
FpdModuleIdentification moduleId;
while (item.hasNext()) {
moduleId = (FpdModuleIdentification) item.next();
SANode = fpdModuleSA.get(moduleId);
try{
if (SANode.get(xmlObjectName)!= null){
SAPcdBuildDef.put(moduleId,
(XmlObject) SANode.get(xmlObjectName));
}
} catch (Exception e){
EdkLog.log(EdkLog.EDK_INFO, e.getMessage());
}
}
return SAPcdBuildDef;
}
public synchronized static Map<FpdModuleIdentification,XmlObject> getFpdPcdBuildDefinitions() {
Map<FpdModuleIdentification,XmlObject> pcdBuildDef = getFpdModuleSaXmlObject ("PcdBuildDefinition");
return pcdBuildDef;
}
}

View File

@ -0,0 +1,145 @@
/** @file
This file is to define OnDependency class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
--*/
package org.tianocore.build.global;
import java.io.File;
import java.util.Iterator;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Sequential;
import org.tianocore.common.logger.EdkLog;
import org.tianocore.common.cache.FileTimeStamp;
/**
Class OnDepdendency is used to check the timestamp between source files and
target files, which can be used to determine if the target files are needed to
be re-generated from source files.
**/
public class OnDependency extends Task {
//
// source files list
//
private DpFileList sources = null;
//
// target files list
//
private DpFileList targets = null;
//
// tasks to be performed to generate target files
//
private Sequential task = null;
/**
An empty constructor for an ANT task can avoid some potential issues
**/
public OnDependency(){
}
/**
Standard execute method of ANT task
**/
public void execute() throws BuildException {
if (isOutOfDate() && task != null) {
task.perform();
}
//
// Update the time stamp of target files since they are just re-generated
//
for (Iterator dstIt = targets.nameList.iterator(); dstIt.hasNext();) {
FileTimeStamp.update((String)dstIt.next());
}
}
//
// check if the target files are outofdate
//
private boolean isOutOfDate() {
///
/// if no source files specified, take it as a fresh start
///
if (sources.nameList.size() == 0) {
EdkLog.log(this, EdkLog.EDK_VERBOSE, "No source file spcified!");
return true;
}
if (targets.nameList.size() == 0) {
EdkLog.log(this, EdkLog.EDK_VERBOSE, "No target file found!");
return true;
}
Iterator dstIt = targets.nameList.iterator();
while (dstIt.hasNext()) {
String dstFileName = (String)dstIt.next();
File dstFile = new File(dstFileName);
if (!dstFile.exists()) {
EdkLog.log(this, EdkLog.EDK_VERBOSE, "Target file [" + dstFileName + "] doesn't exist!");
return true;
}
long dstTimeStamp = FileTimeStamp.get(dstFileName);
Iterator srcIt = sources.nameList.iterator();
while (srcIt.hasNext()) {
String srcFileName = (String)srcIt.next();
long srcTimeStamp = FileTimeStamp.get(srcFileName);
if (srcTimeStamp == 0) {
//
// time stamp 0 means that the file doesn't exist
//
throw new BuildException("Source File name: " + srcFileName + " doesn't exist!!!");
}
if (dstTimeStamp < srcTimeStamp) {
EdkLog.log(this, EdkLog.EDK_VERBOSE, "Source file [" + srcFileName + "] has been changed since last build!");
return true;
}
}
}
EdkLog.log(this, EdkLog.EDK_VERBOSE, "Target files are up-to-date!");
return false;
}
/**
Add method of ANT task for nested element with Sequential type
@param task Sequential object which contains tasks for generating target files
**/
public void addSequential(Sequential task) {
this.task = task;
}
/**
Add method of ANT task for nested element with DpFileList type
@param sources DpFileList object which contains the list of source files
**/
public void addSourcefiles(DpFileList sources) {
this.sources = sources;
}
/**
Add method of ANT task for nested element with DpFileList type
@param targets DpFileList object which contains the list of target files
**/
public void addTargetfiles(DpFileList targets) {
this.targets = targets;
}
}

View File

@ -0,0 +1,201 @@
/** @file
OutputManager class.
OutputManager class set output directories for every module by BUILD_MODE.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.global;
import org.apache.tools.ant.Project;
import java.io.File;
/**
OutputManager class is used to setup output directories (BIN_DIR, DEST_DIR_OUTPUT,
DEST_DIR_DEBUG).
@since GenBuild 1.0
**/
public class OutputManager {
///
/// means intermediate files will put under Module's dir
///
private String MODULE = "MODULE";
///
/// mean intermediate files will put under a unify dir
///
private String UNIFIED = "UNIFIED";
private String userdir;
private String type;
///
/// Singleton Design Pattern
///
private static OutputManager object;
public synchronized static OutputManager getInstance() {
if ( object == null ) {
object = new OutputManager();
}
return object;
}
public void setup(String userdir, String type) {
this.userdir = userdir;
this.type = type;
}
/**
Setup BIN_DIR, DEST_DIR_OUTPUT and DEST_DIR_OUTPUT, following are the rules:
<p>Divide all output files into two types: one is final files, such as FFS
file for driver module while LIB file for library module; another is
intermediate files, such AutoGen.c, OBJ files, Section files and so on.
<p>In FPD, OutputDirectory element is used to specify where to put the output
files to. There are two mode (MODULE | UNIFIED). MODULE mode means that all
output files will put to the module directory while UNIFIED mode means that
all output files will put together. Default is UNIFIED mode.
<p>BUILD_DIR is the base directory for current module build. By default,
BUILD_DIR is PLATFORM_DIR/Build in UNIFIED mode while is MODULE_DIR/Build
in MODULE mode. Of course, user can customize BUILD_DIR. If user-defined
BUILD_DIR is relative path, then look as related to WORKSPACE_DIR.
<p>Then, BIN_DIR is BUILD_DIR/TARGET/TOOLCHAIN/ARCH;
<p>FV_DIR is BUILD_DIR/TARGET/TOOLCHAIN/FV;
<p>DEST_DIR_DEBUG | DEST_DIR_OUTPUT is:
BIN_DIR/PACKAGE_RELATIVE_DIR/MODULE_RELATIVE_DIR/DEBUG | OUTPUT
@param project current ANT build Project
@param userdir user-defined directory
@param type the module build type (MODULE or UNIFIED)
**/
public void update(Project project) {
//
// Default mode is UNIFIED.
//
if (type != null && type.equalsIgnoreCase(MODULE)) {
type = MODULE;
}
else {
type = UNIFIED;
}
//
// default BUILD_DIR value
//
String buildDir;
if(type.equals(MODULE)){
buildDir = project.getProperty("MODULE_DIR") + File.separatorChar + "Build";
}
else {
buildDir = project.getProperty("PLATFORM_DIR") + File.separatorChar + "Build";
}
//
// If user define BUILD_DIR
//
if (userdir != null && ! userdir.equals("")) {
File buildFile = new File(userdir);
if (buildFile.isAbsolute()){
buildDir = userdir;
}
//
// If path is not absolute, then look as related to WORKSPACE_DIR
//
else {
buildDir = GlobalData.getWorkspacePath() + File.separatorChar + userdir;
}
}
//
// Define TARGET_DIR
//
String targetDir = buildDir + File.separatorChar + project.getProperty("TARGET")
+ "_" + project.getProperty("TOOLCHAIN");
//
// Define BIN_DIR and FV_DIR
//
String binDir = targetDir + File.separatorChar + project.getProperty("ARCH") ;
String fvDir = targetDir + File.separatorChar + "FV";
//
// Define DEST_DIR_OUTPUT and DEST_DIR_DEBUG
//
String destDir = binDir + File.separatorChar + project.getProperty("PACKAGE_RELATIVE_DIR")
+ File.separatorChar + project.getProperty("MODULE_RELATIVE_DIR");
//
// Set properties
//
project.setProperty("BUILD_DIR", buildDir.replaceAll("(\\\\)", "/"));
project.setProperty("TARGET_DIR", targetDir.replaceAll("(\\\\)", "/"));
project.setProperty("FV_DIR", fvDir.replaceAll("(\\\\)", "/"));
project.setProperty("BIN_DIR", binDir.replaceAll("(\\\\)", "/"));
project.setProperty("DEST_DIR_DEBUG", (destDir + File.separatorChar + "DEBUG").replaceAll("(\\\\)", "/"));
project.setProperty("DEST_DIR_OUTPUT", (destDir + File.separatorChar + "OUTPUT").replaceAll("(\\\\)", "/"));
//
// Create all directory if necessary
//
(new File(buildDir)).mkdirs();
(new File(fvDir)).mkdirs();
(new File(binDir)).mkdirs();
(new File(destDir + File.separatorChar + "DEBUG")).mkdirs();
(new File(destDir + File.separatorChar + "OUTPUT")).mkdirs();
}
public boolean prepareBuildDir(Project project){
boolean isUnified = true;
if (type.equalsIgnoreCase("MODULE")) {
isUnified = false;
}
String buildDir = project.getProperty("PLATFORM_DIR") + File.separatorChar + "Build";
//
// If user define BUILD_DIR
//
if (userdir != null && ! userdir.equals("")) {
File buildFile = new File(userdir);
if (buildFile.isAbsolute()){
buildDir = userdir;
}
//
// If path is not absolute, then look as related to WORKSPACE_DIR
//
else {
buildDir = GlobalData.getWorkspacePath() + File.separatorChar + userdir;
}
}
//
// Set to property
//
project.setProperty("BUILD_DIR", buildDir.replaceAll("(\\\\)", "/"));
//
// Create all directory if necessary
//
(new File(buildDir)).mkdirs();
return isUnified;
}
}

View File

@ -0,0 +1,196 @@
/** @file
PropertyManager class.
PropertyManager class wraps Project.setProperty and tracks overrided properties.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.global;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.Stack;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.PropertyHelper;
/**
PropertyManager uses a incremental way to to track overrided properties when
setProperty. This is useful for property recovery in nestly calling build files.
Another functionality of this class is to prevent warning message printed when
building with "verbose" mode.
**/
public class PropertyManager {
//
// Property table stack, keeps track the history of properties changes
//
private static Stack<HashMap<String, String>> propertyTableStack = new Stack<HashMap<String, String>>();
//
// The very original properties
//
private static HashMap<String, String> orgPropertyTable = null;
//
// The last changes of properties
//
private static HashMap<String, String> oldPropertyTable = null;
//
// The current changes of properties
//
private static HashMap<String, String> bakPropertyTable = null;
//
// The Project of tracking properties
//
private static Project prj = null;
//
// PropertyHelper of this project for setting property quietly
//
private static PropertyHelper ph = null;
/**
Backup properties that have been overrided onto the stack for later recovery.
**/
public static void save() {
//
// If this is the first time to save properties changes, keep all properties
// of this project as the original property table.
//
if (orgPropertyTable == null) {
Hashtable prjProperties = prj.getProperties();
orgPropertyTable = new HashMap<String, String>();
Set keys = prjProperties.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String item = (String)iter.next();
orgPropertyTable.put(item, (String)prjProperties.get(item));
}
}
//
// If there're already overrided properties, push it onto stack; otherwise
// prepare taking new overrided property by allocating space for it.
//
if (bakPropertyTable != null) {
propertyTableStack.push(bakPropertyTable);
oldPropertyTable = bakPropertyTable;
} else {
oldPropertyTable = orgPropertyTable;
}
bakPropertyTable = new HashMap<String, String>();
}
/**
Restore the properties backup
**/
public static void restore() {
if (bakPropertyTable == null) {
//
// No properties backup, do nothing
//
return;
}
Set keys = bakPropertyTable.keySet();
//
// Re-set properties in backup
//
Iterator iter = keys.iterator();
while (iter.hasNext()) {
String name = (String)iter.next();
String value = (String)bakPropertyTable.get(name);
ph.setProperty(null, name, value, false);
}
//
// If there's backup history, get top one for next recovery
//
if (propertyTableStack.size() > 0) {
bakPropertyTable = (HashMap<String, String>)propertyTableStack.pop();
} else {
bakPropertyTable = null; // no recovery any more
}
//
// Determine last overrided properties for incremental judgement
//
if (propertyTableStack.size() == 0) {
oldPropertyTable = orgPropertyTable;
} else {
oldPropertyTable = (HashMap<String, String>)propertyTableStack.peek();
}
}
/**
Set current Project for save() and restore() use.
@param prj
**/
public static void setProject(Project prj) {
PropertyManager.prj = prj;
PropertyManager.ph = PropertyHelper.getPropertyHelper(prj);
}
/**
Set a property for current project. It will also be put into property
history record if the record table has been setup.
@param name Property name
@param value Property value
**/
public static void setProperty(String name, String value) {
if (prj == null) {
return;
}
setProperty(prj, name, value);
}
/**
Set a property for current project. It will also be put into property
history record if the record table has been setup.
@param project The Project for which the property will be set
@param name Property name
@param value Property value
**/
public static void setProperty(Project project, String name, String value) {
if (project == null) {
if (prj == null) {
return; // a Project must be given; otherwise nothing can be set
}
project = prj;
}
//
// Using PropertyHelper to set a property can be quiet (no override
// warning preset).
//
PropertyHelper.getPropertyHelper(project).setProperty(null, name, value, false);
//
// If no property override history record is found, do nothing further
//
if (oldPropertyTable == null || bakPropertyTable == null) {
return;
}
//
// Put a copy of given property in history record.
//
String oldValue = oldPropertyTable.get(name);
if (oldValue == null) {
oldValue = value;
}
bakPropertyTable.put(name, oldValue);
}
}

View File

@ -0,0 +1,279 @@
/** @file
Spd class.
This class is to generate a global table for the content of spd file.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.global;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.tianocore.build.id.ModuleIdentification;
import org.tianocore.build.id.PackageIdentification;
import org.tianocore.common.exception.EdkException;
/**
This class is to generate a global table for the content of spd file.
**/
public class Spd {
///
///
///
Map<ModuleIdentification, File> msaInfo = new HashMap<ModuleIdentification, File>();
///
/// Map of module info.
/// Key : moduletype
/// Value: moduletype related include file
///
Map<String, String> packageHeaderInfo = new HashMap<String, String>();
///
/// Map of PPI info.
/// Key : PPI name
/// value: String[] a. PPI C_NAME; b. PPI GUID;
///
Map<String, String[]> ppiInfo = new HashMap<String, String[]>();
///
/// Map of Protocol info.
/// Key : Protocol name
/// value: String[] a. Protocol C_NAME; b. Protocol GUID;
///
Map<String, String[]> protocolInfo = new HashMap<String, String[]>();
///
/// Map of Guid info.
/// Key : Guid name
/// value: String[] a. Guid C_NAME; b. Guid's GUID;
///
Map<String, String[]> guidInfo = new HashMap<String, String[]>();
///
/// Map of Guid info
/// Key: GuidCName
/// value: String Guid's GUID
///
Map<String, String> guidCnameInfo = new HashMap<String, String>();
/// Map of library class and its exposed header file.
/// Key : library class name
/// value : library class corresponding header file
///
Map<String, String[]> libClassHeaderList = new HashMap<String, String[]>();
///
/// Package path.
///
PackageIdentification packageId;
/**
Constructor function
This function mainly initialize some member variables.
**/
Spd(File packageFile) throws EdkException {
//
// If specified package file not exists
//
if ( ! packageFile.exists()) {
throw new EdkException("Package file [" + packageFile.getPath() + "] does not exist!");
}
try {
XmlObject spdDoc = XmlObject.Factory.parse(packageFile);
//
// Verify SPD file, if is invalid, throw Exception
//
if (! spdDoc.validate()) {
throw new EdkException("Package Surface Area file [" + packageFile.getPath() + "] format is invalid!");
}
//
// We can change Map to XmlObject
//
Map<String, XmlObject> spdDocMap = new HashMap<String, XmlObject>();
spdDocMap.put("PackageSurfaceArea", spdDoc);
SurfaceAreaQuery saq = new SurfaceAreaQuery(spdDocMap);
packageId = saq.getSpdHeader();
packageId.setSpdFile(packageFile);
//
// initialize Msa Files
// MSA file is absolute file path
//
String[] msaFilenames = saq.getSpdMsaFile();
for (int i = 0; i < msaFilenames.length; i++){
File msaFile = new File(packageId.getPackageDir() + File.separatorChar + msaFilenames[i]);
Map<String, XmlObject> msaDoc = GlobalData.getNativeMsa( msaFile );
saq.push(msaDoc);
ModuleIdentification moduleId = saq.getMsaHeader();
saq.pop();
moduleId.setPackage(packageId);
moduleId.setMsaFile(msaFile);
if (msaInfo.containsKey(moduleId)) {
throw new EdkException("Found two modules with the same GUID and Version in package " + packageId + ".\nThey are module [" + msaInfo.get(moduleId) + "] and MSA file [" + msaFile + "]!");
}
msaInfo.put(moduleId, msaFile);
}
//
// initialize Package header files
//
Map<String, String> packageHeaders = saq.getSpdPackageHeaderFiles();
Set keys = packageHeaders.keySet();
Iterator iter = keys.iterator();
while (iter.hasNext()){
String moduleType = (String)iter.next();
String header = packageId.getPackageRelativeDir() + File.separatorChar + packageHeaders.get(moduleType);
//
// Change path seperator to system-dependent path separator
//
File file = new File (header);
header = file.getPath();
packageHeaderInfo.put(moduleType, header);
}
//
// initialize Guid Info
//
guidInfo.putAll(saq.getSpdGuid());
//
// For Pcd get TokenSpaceGuid
//
Set<String> key = guidInfo.keySet();
Iterator item = key.iterator();
String [] nameValue = new String[2];
while(item.hasNext()){
nameValue = guidInfo.get(item.next());
guidCnameInfo.put(nameValue[0], nameValue[1]);
}
//
// initialize PPI info
//
ppiInfo.putAll(saq.getSpdPpi());
//
// initialize Protocol info
//
protocolInfo.putAll(saq.getSpdProtocol());
//
// initialize library class declaration
//
Map<String, String[]> libraryClassHeaders = saq.getSpdLibraryClasses();
keys = libraryClassHeaders.keySet();
iter = keys.iterator();
while (iter.hasNext()){
String libraryClassName = (String)iter.next();
String[] headerFiles = libraryClassHeaders.get(libraryClassName);
for (int i = 0; i < headerFiles.length; i++){
headerFiles[i] = packageId.getPackageRelativeDir() + File.separatorChar + headerFiles[i];
//
// Change path separator to system system-dependent path separator.
//
File file = new File (headerFiles[i]);
headerFiles[i] = file.getPath();
}
libClassHeaderList.put(libraryClassName, headerFiles);
}
} catch (IOException ex) {
EdkException edkException = new EdkException("Parse of the package description file [" + packageFile.getPath() + "] failed!\n" + ex.getMessage());
edkException.setStackTrace(ex.getStackTrace());
throw edkException;
} catch (XmlException ex) {
EdkException edkException = new EdkException("Parse of the package description file [" + packageFile.getPath() + "] failed!\n" + ex.getMessage());
edkException.setStackTrace(ex.getStackTrace());
throw edkException;
}
}
public PackageIdentification getPackageId() {
return packageId;
}
public File getModuleFile(ModuleIdentification moduleId) {
return msaInfo.get(moduleId);
}
public Set<ModuleIdentification> getModules(){
return msaInfo.keySet();
}
/**
return two value {CName, Guid}. If not found, return null.
**/
public String[] getPpi(String ppiName) {
return ppiInfo.get(ppiName);
}
/**
return two value {CName, Guid}. If not found, return null.
**/
public String[] getProtocol(String protocolName) {
return protocolInfo.get(protocolName);
}
/**
return two value {CName, Guid}. If not found, return null.
**/
public String[] getGuid(String guidName) {
return guidInfo.get(guidName);
}
/**
* return Guid Value.
*/
public String getGuidFromCname(String cName){
return guidCnameInfo.get(cName);
}
/**
getLibClassInclude
This function is to get the library exposed header file name according
library class name.
@param libName Name of library class
@return Name of header file
**/
String[] getLibClassIncluder(String libName) {
return libClassHeaderList.get(libName);
}
/**
getModuleTypeIncluder
This function is to get the header file name from module info map
according to module type.
@param moduleType Module type.
@return Name of header file.
**/
String getPackageIncluder(String moduleType) {
return packageHeaderInfo.get(moduleType);
}
}

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 cannot be null.");
}
getProject().setProperty(name, value);
}
}

View File

@ -0,0 +1,130 @@
/** @file
Java class FpdModuleIdentification is used to present a module identification
from BaseName, GUID, Version, PackageName, and ARCH.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.id;
/**
This class is used to identify a module with Module Guid, Module Version,
Package Guid, Package Version and Arch.
@since GenBuild 1.0
**/
public class FpdModuleIdentification {
private String arch;
private String fvBinding = "NULL"; // Optional
private ModuleIdentification module;
/**
Constructor Method.
@param arch Build Arch
@param fvBinding Belong to what FVs
@param module ModuleIdentification
**/
public FpdModuleIdentification(String arch, String fvBinding, ModuleIdentification module){
this.arch = arch;
this.fvBinding = fvBinding;
this.module = module;
}
/**
Constructor Method.
@param arch Build Arch
@param module ModuleIdentification
**/
public FpdModuleIdentification(ModuleIdentification module, String arch){
this.arch = arch;
this.module = module;
}
/**
Override java.lang.Object#equals.
<p>Currently, use BaseName and ARCH to identify a module. It will enhance
in the next version. </p>
@see java.lang.Object#equals(java.lang.Object)
**/
public boolean equals(Object obj) {
if (obj instanceof FpdModuleIdentification) {
FpdModuleIdentification moduleIdObj = (FpdModuleIdentification)obj;
if ( module.equals(moduleIdObj.module) && arch.equalsIgnoreCase(moduleIdObj.arch)) {
return true;
}
return false;
}
else {
return false;
}
}
/**
@param fvBinding
**/
public void setFvBinding(String fvBinding) {
this.fvBinding = fvBinding;
}
/* (non-Javadoc)
@see java.lang.Object#toString()
**/
public String toString(){
return arch + ":" + module;
}
/**
@return String fvBinding
**/
public String getFvBinding() {
return fvBinding;
}
/**
@return ModuleIdentification module ID
**/
public ModuleIdentification getModule() {
return module;
}
/**
@param module Module Identification
**/
public void setModule(ModuleIdentification module) {
this.module = module;
}
/**
@return String arch
**/
public String getArch() {
return arch;
}
/**
@param arch build ARCH
**/
public void setArch(String arch) {
this.arch = arch;
}
/* (non-Javadoc)
@see java.lang.Object#hashCode()
**/
public int hashCode(){
return module.hashCode();
}
}

View File

@ -0,0 +1,128 @@
/** @file
This file is to define Identification class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.id;
/**
This class is used to identify with its GUID and Version.
@since GenBuild 1.0
**/
public class Identification {
String name;
String guid;
String version;
/**
@param name Name
@param guid Guid
@param version Version
**/
Identification(String name, String guid, String version){
this.name = name;
this.guid = guid;
this.version = version;
}
/**
@param guid Guid
@param version Version
**/
Identification(String guid, String version){
this.guid = guid;
this.version = version;
}
/* (non-Javadoc)
@see java.lang.Object#equals(java.lang.Object)
**/
public boolean equals(Object obj) {
if (obj instanceof Identification) {
Identification id = (Identification)obj;
if ( guid.equalsIgnoreCase(id.guid)) {
if (version == null || id.version == null) {
return true;
}
else if (version.trim().equalsIgnoreCase("") || id.version.trim().equalsIgnoreCase("")){
return true;
}
else if (version.equalsIgnoreCase(id.version)) {
return true;
}
}
return false;
}
else {
return super.equals(obj);
}
}
/**
@param name Name
**/
public void setName(String name) {
this.name = name;
}
/**
@param guid Guid
**/
public void setGuid(String guid) {
this.guid = guid;
}
/**
@param version Version
**/
public void setVersion(String version) {
this.version = version;
}
public String getGuid() {
return guid;
}
/**
@return String Name
**/
public String getName() {
return name;
}
/**
@return String Version
**/
public String getVersion() {
return version;
}
public String toGuidString() {
if (version == null || version.trim().equalsIgnoreCase("")) {
return "[" + guid + "]";
}
else {
return "[" + guid + "] and version [" + version + "]";
}
}
/* (non-Javadoc)
@see java.lang.Object#hashCode()
**/
public int hashCode(){
return guid.toLowerCase().hashCode();
}
}

View File

@ -0,0 +1,171 @@
/** @file
This file is to define ModuleIdentification class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.id;
import java.io.File;
/**
This class is used to identify a module with Module Guid, Module Version,
Package Guid, Package Version.
@since GenBuild 1.0
**/
public class ModuleIdentification extends Identification {
private PackageIdentification packageId;
private File msaFile;
private String moduleType;
private boolean isLibrary = false;
/**
@param guid Guid
@param version Version
**/
public ModuleIdentification(String guid, String version){
super(guid, version);
}
/**
@param guid Guid
@param version Version
@param packageId Package Identification
**/
public ModuleIdentification(String guid, String version, PackageIdentification packageId){
super(guid, version);
this.packageId = packageId;
}
/**
@param name Name
@param guid Guid
@param version Version
**/
public ModuleIdentification(String name, String guid, String version){
super(name, guid, version);
}
/**
@param name Name
@param guid Guid
@param version Version
@param packageId PackageIdentification
**/
public ModuleIdentification(String name, String guid, String version, PackageIdentification packageId){
super(name, guid, version);
this.packageId = packageId;
}
/**
@return boolean is this module is library
**/
public boolean isLibrary() {
return isLibrary;
}
/**
@param isLibrary
**/
public void setLibrary(boolean isLibrary) {
this.isLibrary = isLibrary;
}
/**
@return MSA File
**/
public File getMsaFile() {
return msaFile;
}
/**
@return Module relative path to package
**/
public String getModuleRelativePath() {
if (msaFile.getParent().length() == packageId.getPackageDir().length()) {
return ".";
}
return msaFile.getParent().substring(packageId.getPackageDir().length() + 1);
}
/**
@param msaFile Set Msa File
**/
public void setMsaFile(File msaFile) {
this.msaFile = msaFile;
}
public boolean equals(Object obj) {
if (obj instanceof ModuleIdentification) {
ModuleIdentification id = (ModuleIdentification)obj;
if (guid.equalsIgnoreCase(id.getGuid()) && packageId.equals(id.getPackage())) {
if (version == null || id.version == null) {
return true;
}
else if (version.trim().equalsIgnoreCase("") || id.version.trim().equalsIgnoreCase("")){
return true;
}
else if (version.equalsIgnoreCase(id.version)) {
return true;
}
}
return false;
}
else {
return super.equals(obj);
}
}
public String toString() {
if (version == null || version.trim().equalsIgnoreCase("")) {
return "Module [" + name + "] in " + packageId;
}
else {
return "Module [" + name + " " + version + "] in " + packageId;
}
}
/**
@param packageId set package identification
**/
public void setPackage(PackageIdentification packageId) {
this.packageId = packageId;
}
/**
@return get package identification
**/
public PackageIdentification getPackage() {
return packageId;
}
/**
@return get module type
**/
public String getModuleType() {
return moduleType;
}
/**
@param moduleType set module type
**/
public void setModuleType(String moduleType) {
this.moduleType = moduleType;
}
public String getName() {
return name;
}
}

View File

@ -0,0 +1,118 @@
/** @file
This file is to define PackageIdentification class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.id;
import java.io.File;
import org.tianocore.build.global.GlobalData;
/**
This class is used to identify a package.
@since GenBuild 1.0
**/
public class PackageIdentification extends Identification{
//
// SPD file
//
private File spdFile;
/**
@param guid Guid
@param version Version
**/
public PackageIdentification(String guid, String version){
super(guid, version);
}
/**
@param name Name
@param guid Guid
@param version Version
**/
public PackageIdentification(String name, String guid, String version){
super(name, guid, version);
}
/**
@param name Name
@param guid Guid
@param version Version
@param spdFilename SPD file name
**/
public PackageIdentification(String name, String guid, String version, String spdFilename){
super(name, guid, version);
this.spdFile = new File(spdFilename);
}
/**
@param name Name
@param guid Guid
@param version Version
@param spdFile SPD file
**/
public PackageIdentification(String name, String guid, String version, File spdFile){
super(name, guid, version);
this.spdFile = spdFile;
}
/**
set SPD file.
@param spdFile SPD file
**/
public void setSpdFile(File spdFile) {
this.spdFile = spdFile;
}
/**
get SPD file
@return SPD file
**/
public File getSpdFile() {
return spdFile;
}
public String toString(){
if (version == null || version.trim().equalsIgnoreCase("")) {
return "package [" + name + "]";
}
else {
return "package [" + name + " " + version + "]";
}
}
/**
get package directory
@return Package Directory
**/
public String getPackageDir(){
return spdFile.getParent();
}
/**
get package relative directory.
@return package relative directory
**/
public String getPackageRelativeDir(){
String relativeDir =spdFile.getParent().substring(GlobalData.getWorkspacePath().length());
if(relativeDir.startsWith("\\") || relativeDir.startsWith("/")) {
relativeDir = relativeDir.substring(1);
}
return relativeDir;
}
public String getName() {
return name;
}
}

View File

@ -0,0 +1,113 @@
/** @file
This file is to define PlatformIdentification class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.id;
import java.io.File;
import org.tianocore.build.global.GlobalData;
/**
This class is used to identify a platform.
@since GenBuild 1.0
**/
public class PlatformIdentification extends Identification{
///
/// FPD file
///
private File fpdFile;
/**
@param guid Guid
@param version Version
**/
public PlatformIdentification(String guid, String version){
super(guid, version);
}
/**
@param name Name
@param guid Guid
@param version Version
**/
public PlatformIdentification(String name, String guid, String version){
super(name, guid, version);
}
/**
@param name Name
@param guid Guid
@param version Version
@param fpdFilename Fpd File Name
**/
public PlatformIdentification(String name, String guid, String version, String fpdFilename){
super(name, guid, version);
this.fpdFile = new File(fpdFilename);
}
/**
@param name Name
@param guid Guid
@param version Version
@param fpdFile Fpd File
**/
public PlatformIdentification(String name, String guid, String version, File fpdFile){
super(name, guid, version);
this.fpdFile = fpdFile;
}
public String toString(){
return "Platform " + name + "["+guid+"]";
}
/**
Set FPD file.
@param fpdFile FPD File
**/
public void setFpdFile(File fpdFile) {
this.fpdFile = fpdFile;
}
/**
Get FPD file.
@return Fpd File
**/
public File getFpdFile() {
return fpdFile;
}
/**
Get FPD relative file to workspace.
@return Fpd Relative file.
**/
public String getRelativeFpdFile (){
String relativeDir = fpdFile.getPath().substring(GlobalData.getWorkspacePath().length());
if(relativeDir.startsWith("\\") || relativeDir.startsWith("/")) {
relativeDir = relativeDir.substring(1);
}
return relativeDir;
}
/**
Get Platform relative directory to workspace.
@return Platform relative directory
**/
public String getPlatformRelativeDir(){
String relativeDir = fpdFile.getParent().substring(GlobalData.getWorkspacePath().length());
if(relativeDir.startsWith("\\") || relativeDir.startsWith("/")) {
relativeDir = relativeDir.substring(1);
}
return relativeDir;
}
}

View File

@ -0,0 +1,384 @@
/** @file
PCDAutoGenAction class.
This class is to manage how to generate the PCD information into Autogen.c and
Autogen.h.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.pcd.action;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.tianocore.build.FrameworkBuildTask;
import org.tianocore.build.autogen.CommonDefinition;
import org.tianocore.build.global.GlobalData;
import org.tianocore.build.id.ModuleIdentification;
import org.tianocore.common.logger.EdkLog;
import org.tianocore.pcd.action.BuildAction;
import org.tianocore.pcd.entity.MemoryDatabaseManager;
import org.tianocore.pcd.entity.Token;
import org.tianocore.pcd.entity.UsageIdentification;
import org.tianocore.pcd.entity.UsageInstance;
import org.tianocore.pcd.exception.BuildActionException;
/**
This class is to manage how to generate the PCD information into Autogen.c
and Autogen.h.
**/
public class PCDAutoGenAction extends BuildAction {
///
/// The reference of DBManager in GlobalData class.
///
private MemoryDatabaseManager dbManager;
///
/// The identification for a UsageInstance.
///
private UsageIdentification usageId;
///
/// Whether current autogen is for building library used by current module.
///
private boolean isBuildUsedLibrary;
///
/// One of PEI_PCD_DRIVER, DXE_PCD_DRIVER, NOT_PCD_DRIVER
///
private CommonDefinition.PCD_DRIVER_TYPE pcdDriverType;
///
/// The generated string for header file.
///
private String hAutoGenString;
///
/// The generated string for C code file.
///
private String cAutoGenString;
///
/// The name array of <PcdCoded> in a module.
///
private String[] pcdNameArrayInMsa;
private UsageIdentification parentId = null;
/**
Set parameter moduleId
@param moduleName the module name parameter.
**/
public void setUsageId(UsageIdentification usageId) {
this.usageId = usageId;
}
/**
Set paramter pcdDriverType
@param pcdDriverType the driver type for PCD
**/
public void setPcdDriverType(CommonDefinition.PCD_DRIVER_TYPE pcdDriverType) {
this.pcdDriverType = pcdDriverType;
}
/**
set isBuildUsedLibrary parameter.
@param isBuildUsedLibrary
**/
public void setIsBuildUsedLibrary(boolean isBuildUsedLibrary) {
this.isBuildUsedLibrary = isBuildUsedLibrary;
}
/**
set pcdNameArrayInMsa parameter.
@param pcdNameArrayInMsa
*/
public void setPcdNameArrayInMsa(String[] pcdNameArrayInMsa) {
this.pcdNameArrayInMsa = pcdNameArrayInMsa;
}
/**
Get the output of generated string for header file.
@return the string of header file for PCD
**/
public String getHAutoGenString() {
return hAutoGenString;
}
/**
Get the output of generated string for C Code file.
@return the string of C code file for PCD
**/
public String getCAutoGenString() {
return cAutoGenString;
}
/**
Construct function
This function mainly initialize some member variable.
@param moduleId the identification for module
@param arch the architecture for module
@param isBuildUsedLibary Is the current module library.
@param pcdNameArrayInMsa the pcd name array got from MSA file.
@param pcdDriverType one of PEI_PCD_DRIVER, DXE_PCD_DRIVER,
NOT_PCD_DRIVER
**/
public PCDAutoGenAction(ModuleIdentification moduleId,
String arch,
boolean isBuildUsedLibrary,
String[] pcdNameArrayInMsa,
CommonDefinition.PCD_DRIVER_TYPE pcdDriverType,
ModuleIdentification parentId) {
dbManager = null;
hAutoGenString = "";
cAutoGenString = "";
setUsageId(new UsageIdentification(moduleId.getName(),
moduleId.getGuid(),
moduleId.getPackage().getName(),
moduleId.getPackage().getGuid(),
arch,
moduleId.getVersion(),
moduleId.getModuleType()));
if (parentId != null) {
this.parentId = new UsageIdentification(parentId.getName(),
parentId.getGuid(),
parentId.getPackage().getName(),
parentId.getPackage().getGuid(),
arch,
parentId.getVersion(),
parentId.getModuleType());
}
setIsBuildUsedLibrary(isBuildUsedLibrary);
setPcdNameArrayInMsa(pcdNameArrayInMsa);
setPcdDriverType(pcdDriverType);
}
/**
Override function: check the parameter for action class.
@throws BuildActionException Bad parameter.
**/
public void checkParameter() {
}
/**
Core execution function for this action class.
All PCD information of this module comes from memory dabase. The collection
work should be done before this action execution.
Currently, we should generated all PCD information(maybe all dynamic) as array
in Pei emulated driver for simulating PCD runtime database.
@throws BuildActionException Failed to execute this aciton class.
**/
public void performAction() {
EdkLog.log(EdkLog.EDK_DEBUG, "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");
dbManager = GlobalData.getPCDMemoryDBManager();
if(dbManager.getDBSize() == 0) {
return;
}
EdkLog.log(EdkLog.EDK_DEBUG, "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens.");
generateAutogenForModule();
}
/**
Generate the autogen string for a common module.
All PCD information of this module comes from memory dabase. The collection
work should be done before this action execution.
**/
private void generateAutogenForModule()
{
int index, index2;
List<UsageInstance> usageInstanceArray, usageContext;
String[] guidStringArray = null;
String guidStringCName = null;
String guidString = null;
String moduleName = usageId.moduleName;
UsageInstance usageInstance = null;
boolean found = false;
usageInstanceArray = null;
if (FrameworkBuildTask.multithread) {
if (parentId == null) {
usageInstanceArray = dbManager.getUsageInstanceArrayById(usageId);
} else if ((pcdNameArrayInMsa != null) && (pcdNameArrayInMsa.length > 0)) {
usageContext = dbManager.getUsageInstanceArrayById(parentId);
//
// For building library package, although all module are library, but PCD entries of
// these library should be used to autogen.
//
if (usageContext == null) {
usageInstanceArray = dbManager.getUsageInstanceArrayById(usageId);
} else {
usageInstanceArray = new ArrayList<UsageInstance>();
//
// Try to find all PCD defined in library's PCD in all <PcdEntry> in module's
// <ModuleSA> in FPD file.
//
for (index = 0; index < pcdNameArrayInMsa.length; index++) {
found = false;
for (index2 = 0; index2 < usageContext.size(); index2 ++) {
if (pcdNameArrayInMsa[index].equalsIgnoreCase(usageContext.get(index2).parentToken.cName)) {
usageInstanceArray.add(usageContext.get(index2));
found = true;
break;
}
}
if (!found) {
//
// All library's PCD should instanted in module's <ModuleSA> who
// use this library instance. If not, give errors.
//
throw new BuildActionException (String.format("Module %s using library instance %s; the PCD %s " +
"is required by this library instance, but can not be found " +
"in the %s's <ModuleSA> in the FPD file!",
MemoryDatabaseManager.CurrentModuleName,
moduleName,
pcdNameArrayInMsa[index],
MemoryDatabaseManager.CurrentModuleName
));
}
}
}
}
} else {
if (!isBuildUsedLibrary) {
usageInstanceArray = dbManager.getUsageInstanceArrayById(usageId);
MemoryDatabaseManager.UsageInstanceContext = usageInstanceArray;
MemoryDatabaseManager.CurrentModuleName = moduleName;
} else if ((pcdNameArrayInMsa != null) && (pcdNameArrayInMsa.length > 0)) {
usageContext = MemoryDatabaseManager.UsageInstanceContext;
//
// For building library package, although all module are library, but PCD entries of
// these library should be used to autogen.
//
if (usageContext == null) {
usageInstanceArray = dbManager.getUsageInstanceArrayById(usageId);
} else {
usageInstanceArray = new ArrayList<UsageInstance>();
//
// Try to find all PCD defined in library's PCD in all <PcdEntry> in module's
// <ModuleSA> in FPD file.
//
for (index = 0; index < pcdNameArrayInMsa.length; index++) {
found = false;
for (index2 = 0; index2 < usageContext.size(); index2 ++) {
if (pcdNameArrayInMsa[index].equalsIgnoreCase(usageContext.get(index2).parentToken.cName)) {
usageInstanceArray.add(usageContext.get(index2));
found = true;
break;
}
}
if (!found) {
//
// All library's PCD should instanted in module's <ModuleSA> who
// use this library instance. If not, give errors.
//
throw new BuildActionException (String.format("Module %s using library instance %s; the PCD %s " +
"is required by this library instance, but can not be found " +
"in the %s's <ModuleSA> in the FPD file!",
MemoryDatabaseManager.CurrentModuleName,
moduleName,
pcdNameArrayInMsa[index],
MemoryDatabaseManager.CurrentModuleName
));
}
}
}
}
}
if (usageInstanceArray == null) {
return;
}
//
// Generate all PCD entry for a module.
//
for(index = 0; index < usageInstanceArray.size(); index ++) {
usageInstance = usageInstanceArray.get(index);
//
// Before generate any PCD information into autogen.h/autogen.c for a module,
// generate TokenSpaceGuid array variable firstly. For every dynamicEx type
// PCD in this module the token, they are all reference to TokenSpaceGuid
// array.
//
if (usageInstanceArray.get(index).modulePcdType == Token.PCD_TYPE.DYNAMIC_EX) {
guidStringArray = usageInstance.parentToken.tokenSpaceName.split("-");
guidStringCName = "_gPcd_TokenSpaceGuid_" +
usageInstance.parentToken.tokenSpaceName.replaceAll("-", "_");
guidString = String.format("{ 0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}",
guidStringArray[0],
guidStringArray[1],
guidStringArray[2],
(guidStringArray[3].substring(0, 2)),
(guidStringArray[3].substring(2, 4)),
(guidStringArray[4].substring(0, 2)),
(guidStringArray[4].substring(2, 4)),
(guidStringArray[4].substring(4, 6)),
(guidStringArray[4].substring(6, 8)),
(guidStringArray[4].substring(8, 10)),
(guidStringArray[4].substring(10, 12)));
Pattern pattern = Pattern.compile("(" + guidStringCName + ")+?");
Matcher matcher = pattern.matcher(cAutoGenString + " ");
//
// Find whether this guid array variable has been generated into autogen.c
// For different DyanmicEx pcd token who use same token space guid, the token space
// guid array should be only generated once.
//
if (!matcher.find()) {
hAutoGenString += String.format("extern EFI_GUID %s;\r\n", guidStringCName);
if (!isBuildUsedLibrary) {
cAutoGenString += String.format("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID %s = %s;\r\n",
guidStringCName,
guidString);
}
}
}
usageInstance.generateAutoGen(isBuildUsedLibrary);
//
// For every PCD entry for this module(usage instance), autogen string would
// be appand.
//
hAutoGenString += usageInstance.getHAutogenStr() + "\r\n";
cAutoGenString += usageInstance.getCAutogenStr();
}
if (pcdDriverType == CommonDefinition.PCD_DRIVER_TYPE.PEI_PCD_DRIVER) {
hAutoGenString += MemoryDatabaseManager.PcdPeimHString;
cAutoGenString += MemoryDatabaseManager.PcdPeimCString;
} else if (pcdDriverType == CommonDefinition.PCD_DRIVER_TYPE.DXE_PCD_DRIVER) {
hAutoGenString += MemoryDatabaseManager.PcdDxeHString;
cAutoGenString += MemoryDatabaseManager.PcdDxeCString;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,372 @@
/** @file
PlatformPcdPreprocessActionForBuilding class.
This action class is to collect PCD information from MSA, SPD, FPD xml file.
This class will be used for wizard and build tools, So it can *not* inherit
from buildAction or wizardAction.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.pcd.action;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;
import org.tianocore.PcdBuildDefinitionDocument;
import org.tianocore.PlatformSurfaceAreaDocument;
import org.tianocore.build.exception.PlatformPcdPreprocessBuildException;
import org.tianocore.build.global.GlobalData;
import org.tianocore.build.id.FpdModuleIdentification;
import org.tianocore.pcd.action.PlatformPcdPreprocessAction;
import org.tianocore.pcd.entity.MemoryDatabaseManager;
import org.tianocore.pcd.entity.ModulePcdInfoFromFpd;
import org.tianocore.pcd.entity.Token;
import org.tianocore.pcd.entity.UsageIdentification;
import org.tianocore.pcd.exception.EntityException;
import org.tianocore.pcd.exception.PlatformPcdPreprocessException;
/**
This action class is to collect PCD information from MSA, SPD, FPD xml file.
This class will be used for wizard and build tools, So it can *not* inherit
from buildAction or UIAction.
**/
public class PlatformPcdPreprocessActionForBuilding extends PlatformPcdPreprocessAction {
///
/// FPD file path.
///
private String fpdFilePath;
///
/// Message level for CollectPCDAction.
///
private int originalMessageLevel;
///
/// Cache the fpd docment instance for private usage.
///
private PlatformSurfaceAreaDocument fpdDocInstance;
/**
Set FPDFileName parameter for this action class.
@param fpdFilePath fpd file path
**/
public void setFPDFilePath(String fpdFilePath) {
this.fpdFilePath = fpdFilePath;
}
/**
Common function interface for outer.
@param fpdFilePath The fpd file path of current build or processing.
@throws PlatformPreprocessBuildException
The exception of this function. Because it can *not* be predict
where the action class will be used. So only Exception can be throw.
**/
public void perform(String fpdFilePath)
throws PlatformPcdPreprocessBuildException {
this.fpdFilePath = fpdFilePath;
checkParameter();
execute();
}
/**
Core execution function for this action class.
This function work flows will be:
1) Collect and prepocess PCD information from FPD file, all PCD
information will be stored into memory database.
2) Generate 3 strings for
a) All modules using Dynamic(Ex) PCD entry.(Token Number)
b) PEI PCDDatabase (C Structure) for PCD Service PEIM.
c) DXE PCD Database (C structure) for PCD Service DXE.
@throws EntityException Exception indicate failed to execute this action.
**/
public void execute() throws PlatformPcdPreprocessBuildException {
String errorMessageHeader = "Failed to initialize the Pcd memory database because: ";
String errorsForPreprocess = null;
//
// Get memoryDatabaseManager instance from GlobalData.
// The memoryDatabaseManager should be initialized as static variable
// in some Pre-process class.
//
setPcdDbManager(GlobalData.getPCDMemoryDBManager());
//
// Collect all PCD information defined in FPD file.
// Evenry token defind in FPD will be created as an token into
// memory database.
//
try {
initPcdMemoryDbWithPlatformInfo();
} catch (PlatformPcdPreprocessException exp) {
throw new PlatformPcdPreprocessBuildException(errorMessageHeader + exp.getMessage());
}
errorsForPreprocess = this.getErrorString();
if (errorsForPreprocess != null) {
throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + errorsForPreprocess);
}
//
// Generate for PEI, DXE PCD DATABASE's definition and initialization.
//
try {
genPcdDatabaseSourceCode ();
} catch (EntityException exp) {
throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + exp.getMessage());
}
}
/**
Override function: implementate the method of get Guid string information from SPD file.
@param guidCName Guid CName string.
@return String Guid information from SPD file.
@throws PlatformPcdPreprocessException
Fail to get Guid information from SPD file.
**/
public String getGuidInfoFromSpd(String guidCName) throws PlatformPcdPreprocessException {
String tokenSpaceStrRet = null;
try {
tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(guidCName);
} catch ( Exception e ) {
throw new PlatformPcdPreprocessException ("Failed to get Guid CName " + guidCName + " from the SPD file!");
}
return tokenSpaceStrRet;
}
/**
This function generates source code for PCD Database.
@throws EntityException If the token does *not* exist in memory database.
**/
private void genPcdDatabaseSourceCode()
throws EntityException {
String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions();
ArrayList<Token> alPei = new ArrayList<Token> ();
ArrayList<Token> alDxe = new ArrayList<Token> ();
getPcdDbManager().getTwoPhaseDynamicRecordArray(alPei, alDxe);
PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);
pcdPeiDatabase.genCode();
MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString() +
PcdDatabase.getPcdPeiDatabaseDefinitions();
MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();
PcdDatabase pcdDxeDatabase = new PcdDatabase(alDxe, "DXE", alPei.size());
pcdDxeDatabase.genCode();
MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString() +
PcdDatabase.getPcdDxeDatabaseDefinitions();
MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();
}
/**
Override function: Get component array from FPD.
This function maybe provided by some Global class.
@return List<ModuleInfo> the component array.
@throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.
**/
public List<ModulePcdInfoFromFpd> getComponentsFromFpd()
throws PlatformPcdPreprocessException {
List<ModulePcdInfoFromFpd> allModules = new ArrayList<ModulePcdInfoFromFpd>();
Map<FpdModuleIdentification, XmlObject> pcdBuildDefinitions = null;
UsageIdentification usageId = null;
pcdBuildDefinitions = GlobalData.getFpdPcdBuildDefinitions();
if (pcdBuildDefinitions == null) {
return null;
}
//
// Loop map to retrieve all PCD build definition and Module id
//
Iterator item = pcdBuildDefinitions.keySet().iterator();
while (item.hasNext()){
FpdModuleIdentification id = (FpdModuleIdentification) item.next();
usageId = new UsageIdentification(id.getModule().getName(),
id.getModule().getGuid(),
id.getModule().getPackage().getName(),
id.getModule().getPackage().getGuid(),
id.getArch(),
id.getModule().getVersion(),
id.getModule().getModuleType());
allModules.add(
new ModulePcdInfoFromFpd(
usageId,
((PcdBuildDefinitionDocument)pcdBuildDefinitions.get(id)).getPcdBuildDefinition()));
}
return allModules;
}
/**
Override function: Verify the datum value according its datum size and datum type, this
function maybe moved to FPD verification tools in future.
@param cName The token name
@param moduleName The module who use this PCD token
@param datum The PCD's datum
@param datumType The PCD's datum type
@param maxDatumSize The max size for PCD's Datum.
@return String exception strings.
*/
public String verifyDatum(String cName,
String moduleName,
String datum,
Token.DATUM_TYPE datumType,
int maxDatumSize) {
//
// In building system, datum should not be checked, the checking work
// should be done by wizard tools or PCD verification tools.
//
return null;
}
/**
Override function: Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.
This function should be implemented in GlobalData in future.
@param token The token instance which has hold module's PCD information
@param moduleName The name of module who will use this Dynamic PCD.
@return DynamicPcdBuildDefinitions.PcdBuildData
**/
public DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFpd(Token token,
String moduleName)
throws PlatformPcdPreprocessException {
int index = 0;
String exceptionString = null;
String dynamicPrimaryKey = null;
DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;
List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;
String tokenSpaceStrRet = null;
//
// If FPD document is not be opened, open and initialize it.
// BUGBUG: The code should be moved into GlobalData in future.
//
if (fpdDocInstance == null) {
try {
fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));
} catch(IOException ioE) {
throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
} catch(XmlException xmlE) {
throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
}
}
dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();
if (dynamicPcdBuildDefinitions == null) {
exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> elements in FPD file but there are Dynamic type "+
"PCD entries %s in module %s!",
token.cName,
moduleName);
putError(exceptionString);
return null;
}
dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();
for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {
tokenSpaceStrRet = getGuidInfoFromSpd(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());
if (tokenSpaceStrRet == null) {
exceptionString = "Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName();
putError(exceptionString);
continue;
}
dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),
tokenSpaceStrRet);
if (dynamicPrimaryKey.equals(token.getPrimaryKeyString())) {
return dynamicPcdBuildDataArray.get(index);
}
}
return null;
}
/**
Override function: get all <DynamicPcdBuildDefinition> from FPD file.
@return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.
@throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.
**/
public List<DynamicPcdBuildDefinitions.PcdBuildData>
getAllDynamicPcdInfoFromFpd()
throws PlatformPcdPreprocessException {
DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;
//
// Open fpd document to get <DynamicPcdBuildDefinition> Section.
// BUGBUG: the function should be move GlobalData in furture.
//
if (fpdDocInstance == null) {
try {
fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));
} catch(IOException ioE) {
throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
} catch(XmlException xmlE) {
throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
}
}
dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();
if (dynamicPcdBuildDefinitions == null) {
return null;
}
return dynamicPcdBuildDefinitions.getPcdBuildDataList();
}
/**
check parameter for this action.
@throws PlatformPcdPreprocessBuildException Bad parameter.
**/
private void checkParameter() throws PlatformPcdPreprocessBuildException {
File file = null;
if (fpdFilePath == null) {
throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");
}
if (fpdFilePath.length() == 0) {
throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");
}
file = new File(fpdFilePath);
if(!file.exists()) {
throw new PlatformPcdPreprocessBuildException("FPD File " + fpdFilePath + " does not exist!");
}
}
}

View File

@ -0,0 +1,108 @@
/** @file
ConfigReader class.
ConfigReader is used to read tool chain config file with flat format.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.toolchain;
import org.tianocore.build.exception.GenBuildException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
/**
ConfigReader is used to read tool chain config file with flat format. Comments
is line starting with character '#'.
@since GenBuild 1.0
**/
public class ConfigReader {
/**
Parse specified tool chain definition file.
@param filename The config file name with full path
@return String[][] The definition array
**/
public static synchronized String[][] parse(String filename) throws GenBuildException {
return parse(new File(filename));
}
/**
Get all definitions in config file. the config file format is flat
with "A=B". If line started with '#' looks as comments.
@param configFile The config file
@return String[][] The variables defined in the config file
@throws GenBuildException
Config file's format is not valid
**/
public static synchronized String[][] parse(File configFile) throws GenBuildException {
List<String> keyList = new ArrayList<String>(256);
List<String> valueList = new ArrayList<String>(256);
int lines = 0;
try {
FileReader reader = new FileReader(configFile);
BufferedReader in = new BufferedReader(reader);
String str;
while ((str = in.readLine()) != null) {
++lines;
str = str.trim();
//
// skip empty line, comment (start with '#')
//
if (str.length() == 0 || str.startsWith("#")) {
continue;
}
//
// stop if the definition line is not in "name=value" form
//
int index;
if ((index = str.indexOf('=')) <= 0) {
throw new GenBuildException("ERROR Processing file ["
+ configFile.getAbsolutePath()
+ "] (line " + lines + ").\n");
}
//
// look as line "A = B"
//
keyList.add(str.substring(0, index).trim());
valueList.add(str.substring(index + 1).trim());
}
} catch (Exception ex) {
GenBuildException e = new GenBuildException("ERROR Processing file ["
+ configFile.getAbsolutePath()
+ "] (line " + lines + ").\n" + ex.getMessage());
e.setStackTrace(ex.getStackTrace());
throw e;
}
String[][] definitions = new String[2][keyList.size()];
definitions[0] = (String[])keyList.toArray(definitions[0]);
definitions[1] = (String[])valueList.toArray(definitions[1]);
return definitions;
}
}

View File

@ -0,0 +1,52 @@
/** @file
ToolChainAttribute class
This file is to define enumeration value for tool chain attribute names.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.toolchain;
/**
ToolChainAttribute is used to define the enumeration value for the attributes
used in tool chain definition file.
**/
public class ToolChainAttribute {
private static int nextValue = 0;
///
/// "NAME", "PATH", "DPATH", "SPATH", "EXT", "FAMILY", "FLAGS"
///
public final static ToolChainAttribute NAME = new ToolChainAttribute("NAME");
public final static ToolChainAttribute PATH = new ToolChainAttribute("PATH");
public final static ToolChainAttribute DPATH = new ToolChainAttribute("DPATH");
public final static ToolChainAttribute SPATH = new ToolChainAttribute("SPATH");
public final static ToolChainAttribute EXT = new ToolChainAttribute("EXT");
public final static ToolChainAttribute FAMILY = new ToolChainAttribute("FAMILY");
public final static ToolChainAttribute FLAGS = new ToolChainAttribute("FLAGS");
private final String name;
public final int value = nextValue++;
/**
* Default constructor
*/
private ToolChainAttribute(String name) {
this.name = name;
}
public String toString() {
return name;
}
}

View File

@ -0,0 +1,125 @@
/** @file
ToolChainConfig class.
ToolChainConfig class parse all config files and get tool chain information.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.toolchain;
import org.tianocore.build.exception.GenBuildException;
import org.tianocore.build.toolchain.ToolChainKey;
import org.tianocore.build.toolchain.ToolChainMap;
import java.io.File;
import java.util.Iterator;
import java.util.Set;
/**
ToolChainConfig class parse all config files and get tool chain information.
**/
public class ToolChainConfig {
//
// tool chain definitions
//
private ToolChainMap config = null;
//
// tool chain information (how many targets, archs, etc.)
//
private ToolChainInfo info = new ToolChainInfo();
/**
Public construct method.
@param toolChainFile File object representing the tool chain configuration file
**/
public ToolChainConfig (File toolChainFile) throws GenBuildException {
config = getToolChainConfig(toolChainFile);
parseToolChainDefKey(config.keySet());
}
/**
Read tool chain definitions from specified file and put them in
ToolChainMap class.
@param ConfigFile The file containing tool chain definitions
@return ToolChainMap
**/
private ToolChainMap getToolChainConfig(File ConfigFile) throws GenBuildException {
ToolChainMap map = new ToolChainMap();
String[][] toolChainDef = ConfigReader.parse(ConfigFile);
for (int i = 0; i < toolChainDef[0].length; ++i) {
map.put(toolChainDef[0][i], toolChainDef[1][i]);
}
return map;
}
/**
Collect target, tool chain tag, arch and command information from key part
of configuration
@param toolChainDefKey The set of keys in tool chain configuration
**/
private void parseToolChainDefKey (Set<ToolChainKey> toolChainDefKey) {
Iterator it = toolChainDefKey.iterator();
while (it.hasNext()) {
ToolChainKey key = (ToolChainKey)it.next();
String[] keySet = key.getKeySet();
info.addTargets(keySet[ToolChainElement.TARGET.value]);
info.addTagnames(keySet[ToolChainElement.TOOLCHAIN.value]);
info.addArchs(keySet[ToolChainElement.ARCH.value]);
info.addCommands(keySet[ToolChainElement.TOOLCODE.value]);
}
}
/**
Return the tool chain configuration information in a Map form
@return ToolChainMap Tool chain configurations in a ToolChainMap
**/
public ToolChainMap getConfig() {
return config;
}
/**
Return the tool chain's target, arch, tag and commands information
@return ToolChainInfo Tool chain information summary
**/
public ToolChainInfo getConfigInfo() {
return info;
}
/**
override toString()
@return String The converted configuration string in name=value form
**/
public String toString() {
StringBuffer ts = new StringBuffer(10240);
Iterator it = config.keySet().iterator();
while (it.hasNext()) {
ToolChainKey key = (ToolChainKey)it.next();
ts.append(key.toString() + " = ");
ts.append(config.get(key) + "\n");
}
return ts.toString();
}
}

View File

@ -0,0 +1,54 @@
/** @file
ToolChainElement class
ToolChainElement class is defining enumeration value of key part names.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.toolchain;
/**
This class is an enumeration definition for key elements in tool chain definition
file.
**/
public class ToolChainElement {
private static int nextValue = 0;
//
// "TARGET", "TOOLCHAIN", "ARCH", "TOOLCODE", "ATTRIBUTE"
//
public final static ToolChainElement TARGET = new ToolChainElement("TARGET");
public final static ToolChainElement TOOLCHAIN = new ToolChainElement("TOOLCHAIN");
public final static ToolChainElement ARCH = new ToolChainElement("ARCH");
public final static ToolChainElement TOOLCODE = new ToolChainElement("TOOLCODE");
public final static ToolChainElement ATTRIBUTE = new ToolChainElement("ATTRIBUTE");
private final String name;
public final int value = nextValue++;
/**
* Default constructor
*/
private ToolChainElement(String name) {
this.name = name;
}
public String toString() {
return name;
}
}

View File

@ -0,0 +1,347 @@
/** @file
ToolChainInfo class
This file is to define ToolChainInfo class.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.toolchain;
import java.util.LinkedHashSet;
import java.util.Set;
/**
ToolChainInfo collects valid build targets, tool chain tag, ARCHs and commands
information for real build use.
**/
public class ToolChainInfo {
//
// build target set
//
private Set<String> targets = new LinkedHashSet<String>();
//
// tool chain tag name set
//
private Set<String> tagnames = new LinkedHashSet<String>();
//
// build archs set
//
private Set<String> archs = new LinkedHashSet<String>();
//
// build commands set
//
private Set<String> commands = new LinkedHashSet<String>();
/**
Add a list of targets in the form of string separated by space
@param targetList target list string
**/
public void addTargets(String targetList) {
//
// targetList some targets separated by space " "
//
if (targetList == null || targetList.length() == 0) {
targets.add("*");
} else {
addTargets(targetList.split(" "));
}
}
/**
Add a list of targets in the form of string array
@param targetArray target string array
**/
public void addTargets(String[] targetArray) {
if (targetArray != null ) {
for (int i = 0; i < targetArray.length; i++) {
targets.add(targetArray[i]);
}
}
}
/**
Add a list of target in the form of set
@param targetSet target string set
**/
public void addTargets(Set<String> targetSet) {
if (targetSet != null) {
targets.addAll(targetSet);
}
}
/**
Add a list of tool chain tag name in the form of string separated by space
@param tagnameList Tool chain tag name list string
**/
public void addTagnames(String tagnameList) {
//
// tagnameList some tagnames separated by space " "
//
if (tagnameList == null || tagnameList.length() == 0) {
tagnames.add("*");
} else {
addTagnames(tagnameList.split(" "));
}
}
/**
Add a list of tool chain tag name in the form of string array
@param tagnameArray Tool chain tag names array
**/
public void addTagnames(String[] tagnameArray) {
if (tagnameArray != null ) {
for (int i = 0; i < tagnameArray.length; i++) {
tagnames.add(tagnameArray[i]);
}
}
}
/**
Add a list of tool chain tag name in the form of Set
@param tagnameSet Tool chain tag names set
**/
public void addTagnames(Set<String> tagnameSet) {
if (tagnameSet != null) {
tagnames.addAll(tagnameSet);
}
}
/**
Add a list of ARCH in the form of string
@param archList ARCH string
**/
public void addArchs(String archList) {
//
// archList some archs separated by space " "
//
if (archList == null || archList.length() == 0) {
archs.add("*");
} else {
addArchs(archList.split(" "));
}
}
/**
Add a list of ARCH in the form of string array
@param archArray ARCH array
**/
public void addArchs(String[] archArray) {
if (archArray != null ) {
for (int i = 0; i < archArray.length; i++) {
archs.add(archArray[i]);
}
}
}
/**
Add a list of ARCH in the form of set
@param archSet ARCH set
**/
public void addArchs(Set<String> archSet) {
if (archSet != null) {
archs.addAll(archSet);
}
}
/**
Add a list of command in the form of string
@param commandList Command list string
**/
public void addCommands(String commandList) {
//
// archList some archs separated by space " "
//
if (commandList == null || commandList.length() == 0) {
commands.add("*");
} else {
addCommands(commandList.split(" "));
}
}
/**
Add a list of ARCH in the form of array
@param commandArray Commands array
**/
public void addCommands(String[] commandArray) {
if (commandArray != null ) {
for (int i = 0; i < commandArray.length; i++) {
commands.add(commandArray[i]);
}
}
}
/**
Add a list of ARCH in the form of set
@param commandSet Commands set
**/
public void addCommands(Set<String> commandSet) {
if (commandSet != null) {
commands.addAll(commandSet);
}
}
/**
Make a union operation on this ToolChainInfo and the given one.
@param info Another ToolChainInfo object to merge with
@return ToolChainInfo Merged ToolChainInfo object
**/
public ToolChainInfo union(ToolChainInfo info) {
ToolChainInfo result = new ToolChainInfo();
result.addTargets(union(this.targets, info.targets));
result.addTagnames(union(this.tagnames, info.tagnames));
result.addArchs(union(this.archs, info.archs));
return result;
}
/**
Make a intersection operation on this ToolChainInfo and the given one
@param info Another ToolChainInfo object to intersect with
@return ToolChainInfo Intersected ToolChainInfo object
**/
public ToolChainInfo intersection(ToolChainInfo info) {
ToolChainInfo result = new ToolChainInfo();
result.addTargets(intersection(this.targets, info.targets));
result.addTagnames(intersection(this.tagnames, info.tagnames));
result.addArchs(intersection(this.archs, info.archs));
return result;
}
/**
Make a union operation on two Sets
@param set1 One Set
@param set2 Another Set
@return Set<String> Merged Set object
**/
private Set<String> union(Set<String> set1, Set<String> set2) {
Set<String> result = new LinkedHashSet<String>();
result.addAll(set1);
result.addAll(set2);
result.remove("*");
return result;
}
/**
Make a intersection operation on two Sets with the consideration of wildcard.
@param set1 One Set
@param set2 Another Set
@return Set<String> The intersected Set object
**/
private Set<String> intersection(Set<String> set1, Set<String> set2) {
Set<String> result = new LinkedHashSet<String>();
boolean set1HasWildcard = set1.contains("*");
boolean set2HasWildcard = set2.contains("*");
if (set1HasWildcard && set2HasWildcard) {
//
// Both Sets have wildcard, the result will have all elements in them
//
result.addAll(set1);
result.addAll(set2);
} else if (set1HasWildcard) {
//
// Only set1 has wildcard, then result will have only set2 elements.
//
result.addAll(set2);
} else if (set2HasWildcard) {
//
// Only set2 has wildcard, then result will have only set1 elements.
//
result.addAll(set1);
} else {
//
// No wildcard in both Sets, the result will have the elements in both Sets.
//
result.addAll(set1);
result.retainAll(set2);
}
return result;
}
/**
Get target array.
@return String[]
**/
public String[] getTargets() {
return (String[])targets.toArray(new String[targets.size()]);
}
/**
Get tool chain tag name array.
@return String[]
**/
public String[] getTagnames() {
return (String[])tagnames.toArray(new String[tagnames.size()]);
}
/**
Get ARCH array.
@return String[]
**/
public String[] getArchs() {
return (String[])archs.toArray(new String[archs.size()]);
}
/**
Get command name array.
@return String[]
**/
public String[] getCommands() {
return (String[])commands.toArray(new String[commands.size()]);
}
/**
Override the Object's toString().
@return String
**/
public String toString() {
return " TARGET :" + targets + "\n" +
" TAGNAME:" + tagnames + "\n" +
" ARCH :" + archs + "\n" +
" COMMAND:" + commands;
}
/**
Remove the wildcard element in the tool chain information because they
are useless when retrieved.
**/
public void normalize() {
targets.remove("*");
tagnames.remove("*");
archs.remove("*");
commands.remove("*");
}
}

View File

@ -0,0 +1,278 @@
/** @file
ToolChainKey class
ToolChainKey class is representing the "name" part of tool chain definition.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.toolchain;
import org.tianocore.build.exception.GenBuildException;
/**
ToolChainKey class is the java class form of the "name" of tool chain definition.
It's primarily for the key of a Map data structure.
**/
public class ToolChainKey implements java.io.Serializable, Comparable<ToolChainKey> {
static final long serialVersionUID = -8034897190740066933L;
///
/// The part number of key. Currently we only support fixed five parts.
///
public final static int keyLength = 5;
//
// Default delimiter which is used for concatenating the parts of key
//
private String delimiter = "_";
//
// Key value in string array form
//
private String[] keySet = null;
//
// Key value in one string form
//
private String keyString = null;
//
// Key hash value used for hash table
//
private int hashValue = 0;
/**
Public constructor which can override default delimiter.
@param keyString The key string value
@param delimiter Delimiter charater concatenating the key parts
**/
public ToolChainKey(String keyString, String delimiter) throws GenBuildException {
setKey(keyString, delimiter);
}
/**
Public constructor which uses default delimiter.
@param keyString The key string value
**/
public ToolChainKey(String keyString) throws GenBuildException {
setKey(keyString);
}
/**
Public constructor which doesn't use any delimiter.
@param keySet
**/
public ToolChainKey(String[] keySet) throws GenBuildException {
setKey(keySet);
}
/**
Calculate hash value of the key string (without the delimiter). It's used
for Hash Table kind of Map.
@return int The hash value
**/
public int hashCode() {
if (hashValue != 0) {
return hashValue;
}
for (int i = 0; i < keySet.length; ++i) {
char[] keyStringValue = new char[keySet[i].length()];
this.keySet[i].getChars(0, keyStringValue.length, keyStringValue, 0);
for (int j = 0; j < keyStringValue.length; ++j) {
hashValue = keyStringValue[j] + hashValue * 31;
}
}
return hashValue;
}
/**
Compare the string value of two keys . It's used for Tree kind of Map.
@param dstKey Another key to compare to.
@retval 0 Two keys are equal
@retval >0 This key is after the given key
@retval <0 This key is before the given key
**/
public int compareTo(ToolChainKey dstKey) {
String[] dstKeySet = dstKey.getKeySet();
int result = 0;
for (int i = 0; i < ToolChainKey.keyLength; ++i) {
result = this.keySet[i].compareToIgnoreCase(dstKeySet[i]);
if (result != 0) {
break;
}
}
return result;
}
/**
Check if this key is the same as the given key.
@param o Another key to compare to
@return boolean
**/
public boolean equals(Object o) {
ToolChainKey dstKey = (ToolChainKey)o;
String[] dstKeySet = dstKey.getKeySet();
if (this == dstKey) {
return true;
}
if (dstKeySet.length != ToolChainKey.keyLength) {
return false;
}
for (int i = 0; i < ToolChainKey.keyLength; ++i) {
if (!this.keySet[i].equalsIgnoreCase(dstKeySet[i])) {
return false;
}
}
return true;
}
/**
Set the key value in form of string array.
@param keySet The string array of key value
**/
public void setKey(String[] keySet) throws GenBuildException {
if (keySet.length != ToolChainKey.keyLength) {
throw new GenBuildException("Invalid ToolChain key");
}
//
// Clone the string array because we don't want to change original one
//
this.keySet = new String[ToolChainKey.keyLength];
System.arraycopy(keySet, 0, this.keySet, 0, ToolChainKey.keyLength);
for (int i = 0; i < ToolChainKey.keyLength; ++i) {
if (this.keySet[i] == null || this.keySet[i].length() == 0) {
this.keySet[i] = "*";
}
}
//
// We need to re-generate the single key string and hash value.
//
this.keyString = null;
this.hashValue = 0;
}
/**
Set key value at the specified key part .
@param keySetString The new value of "index" part of key
@param index The key part index
**/
public void setKey(String keySetString, int index) throws GenBuildException {
if (index >= ToolChainKey.keyLength) {
throw new GenBuildException("Invalid ToolChain key index");
}
//
// Allow wildcard in key string
//
if (keySetString == null || keySetString.length() == 0) {
keySetString = "*";
}
this.keySet[index] = keySetString;
//
// We need to re-generate the single key string and hash value.
//
this.keyString = null;
this.hashValue = 0;
}
/**
Set key value in the form of single string.
@param keyString The key value string
**/
public void setKey(String keyString) throws GenBuildException {
this.keySet = keyString.split(this.delimiter);
if (this.keySet.length != ToolChainKey.keyLength) {
throw new GenBuildException("Invalid ToolChain key");
}
this.keyString = keyString;
//
// We need to re-generate hash value.
//
this.hashValue = 0;
}
/**
Set key value in the form of single string with specified delimiter.
@param keyString The key value string
@param delimiter The delimiter concatenating the key string
**/
public void setKey(String keyString, String delimiter) throws GenBuildException {
this.keySet = keyString.split(delimiter);
if (this.keySet.length != ToolChainKey.keyLength) {
throw new GenBuildException("Invalid ToolChain key");
}
this.keyString = keyString;
this.delimiter = delimiter;
//
// We need to re-generate hash value.
//
this.hashValue = 0;
}
/**
Return the string array form of key
@return String[]
**/
public String[] getKeySet() {
return keySet;
}
/**
Return the single string form of key.
@return String
**/
public String toString() {
if (this.keyString == null) {
StringBuffer keyStringBuf = new StringBuffer(64);
keyStringBuf.append(this.keySet[0]);
for (int i = 1; i < ToolChainKey.keyLength; ++i) {
keyStringBuf.append(this.delimiter);
keyStringBuf.append(this.keySet[i]);
}
this.keyString = keyStringBuf.toString();
}
return this.keyString;
}
}

View File

@ -0,0 +1,326 @@
/** @file
ToolChainMap class
ToolChainMap class is used for storing tool chain configurations.
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.toolchain;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
ToolChainMap is a wrapper class for a generic Map class which uses ToolChainKey
class as its key. It's used to store and retrieve tool chain configuration
information.
**/
public class ToolChainMap {
//
// From which part of key can be used to match "*"
//
private int matchLevel = ToolChainKey.keyLength - 2;
//
// A Map object in which tool chain configuration information will be stored
//
private Map<ToolChainKey, String> map = null;
/**
Public constructor. It just initializes the private Map object.
**/
public ToolChainMap() {
this.map = new HashMap<ToolChainKey, String>();
}
/**
Wrapper function for Map.put(). It's used when default delimiter of
ToolChainKey is not wanted and will be overrided by "delimiter" parameter.
@param key Key string which is concatenated with "delimiter"
@param delimiter The delimiter string in the key string
@param value Value string associated with the "key"
@retval String The "value" string if the "key" is valid.
@retval null if the "key" is invalid
**/
public String put(String key, String delimiter, String value) {
ToolChainKey toolChainKey;
try {
toolChainKey = new ToolChainKey(key, delimiter);
} catch (Exception e) {
return null;
}
return (String)map.put(toolChainKey, value);
}
/**
Wrapper function for Map.put().
@param key Key string which is concatenated with default "delimiter"
@param value Value string associated with the "key"
@retval String The "value" string if the "key" is valid.
@retval null if the "key" is invalid
**/
public String put(String key, String value) {
ToolChainKey toolChainKey;
try {
toolChainKey = new ToolChainKey(key);
} catch (Exception e) {
return null;
}
return (String)map.put(toolChainKey, value);
}
/**
Wrapper function for Map.put(). The key is given in the form of string
array.
@param key Key string array
@param value Value string associated with the "key"
@retval String The "value" string if the "key" is valid.
@retval null if the "key" is invalid
**/
public String put(String[] key, String value) {
ToolChainKey toolChainKey;
try {
toolChainKey = new ToolChainKey(key);
} catch (Exception e) {
return null;
}
return (String)map.put(toolChainKey, value);
}
/**
Wrapper function for Map.put(). The key is given in ToolChainKey class.
@param key ToolChainKey class
@param value Value string associated with the "key"
@retval String The "value" string if the "key" is valid.
@retval null if the "key" is invalid
**/
public String put(ToolChainKey key, String value) {
return (String)map.put(key, value);
}
/**
Wrapper function for Map.get().
@param key Key string which is concatenated with default "delimiter"
@return String
**/
public String get(String key) {
ToolChainKey toolChainKey;
try {
toolChainKey = new ToolChainKey(key);
} catch (Exception e) {
return null;
}
return get(toolChainKey);
}
/**
Wrapper function for Map.get(). It's used when default delimiter of
ToolChainKey is not wanted and will be overrided by "delimiter" parameter.
@param key Key string which is concatenated with "delimiter"
@param delimiter The delimiter string in the key string
@return String
**/
public String get(String key, String delimiter) {
ToolChainKey toolChainKey;
try {
toolChainKey = new ToolChainKey(key, delimiter);
} catch (Exception e) {
return null;
}
return get(toolChainKey);
}
/**
Wrapper function for Map.get(). The key is given in the form of string
array.
@param key Key string array
@return String
**/
public String get(String[] key) {
ToolChainKey toolChainKey;
try {
toolChainKey = new ToolChainKey(key);
} catch (Exception e) {
return null;
}
return get(toolChainKey);
}
/**
Wrapper function for Map.get(). The key is given in ToolChainKey class.
All other form of get() method will eventually call this form of get. It
will do real job of finding the value associated with the given key. Most
of the job is to try to match the key with "wildcard".
@param key ToolChainKey class
@return String The value associated with the key
**/
public String get(ToolChainKey key) {
///
/// First, we'll try to get the value through the exact given key
///
String result = map.get(key);
if (result != null || map.containsKey(key)) {
return result;
}
///
/// If nothing is found, then, we'll try all possible keys combined with
/// wildcard "*". In order not to change the original key value, we have
/// to clone one for later use.
///
String[] keySet = key.getKeySet();
ToolChainKey tmpKey;
try {
tmpKey = new ToolChainKey(keySet);
} catch (Exception e) {
return null;
}
///
/// In the current tool chain definition format (in name/value pair),
/// there're five parts in the "name". The last part of the "name" must
/// not be "wildcard". So we should start combining "*" from the fourth part.
/// We'll try all the possible combinations until the value can be fetched.
///
/// The following code implements the logic which will try to use, for example,
/// following key parts combinations sequentially to get the value.
///
/// TARGET_TOOLCHAIN_ARCH_TOOLCODE_ATTRIBUTE
/// TARGET_TOOLCHAIN_ARCH_*_ATTRIBUTE
/// TARGET_TOOLCHAIN_*_TOOLCODE_ATTRIBUTE
/// TARGET_TOOLCHAIN_*_*_ATTRIBUTE
/// TARGET_*_ARCH_TOOLCODE_ATTRIBUTE
/// TARGET_*_ARCH_*_ATTRIBUTE
/// TARGET_*_*_TOOLCODE_ATTRIBUTE
/// TARGET_*_*_*_ATTRIBUTE
/// *_TOOLCHAIN_ARCH_TOOLCODE_ATTRIBUTE
/// *_TOOLCHAIN_ARCH_*_ATTRIBUTE
/// *_TOOLCHAIN_*_TOOLCODE_ATTRIBUTE
/// *_TOOLCHAIN_*_*_ATTRIBUTE
/// *_*_ARCH_TOOLCODE_ATTRIBUTE
/// *_*_ARCH_*_ATTRIBUTE
/// *_*_*_TOOLCODE_ATTRIBUTE
/// *_*_*_*_ATTRIBUTE
///
//
// level is used to control if all parts of "name" have been "wildcarded"
//
int level = matchLevel;
while (level >= 0) {
//
// tmplevel is used to control if all parts of "name" between first
// "*" and fourth name part have been "wildcarded".
//
int tmpLevel = level;
while (tmpLevel >= level) {
String[] tmpKeySet = tmpKey.getKeySet();
try {
if (!tmpKeySet[tmpLevel].equals("*")) {
//
// If "tmplevel" part is not "*", set it to "*".
// For example, at first loop, the key will become
// TARGET_TOOLCHAIN_ARCH_*_ATTRIBUTE, and at next loop,
// become TARGET_TOOLCHAIN_*_ARCH_ATTRIBUTE
//
tmpKey.setKey("*", tmpLevel);
//
// We'll try all possible combinations between current
// part and the fourth part.
//
tmpLevel = matchLevel;
} else {
//
// Restore original value of key if "*" at "tmplevel"
// part of "name" has been checked
//
tmpKey.setKey(keySet[tmpLevel], tmpLevel);
//
// Try "*" at part left to "tmplevel" part of "name"
//
--tmpLevel;
continue;
}
} catch (Exception e) {
return null;
}
//
// Try get the value from the map
//
result = map.get(tmpKey);
if (result != null) {
//
// The map actually has no exact key as the given "key",
// putting it back into map can speed up the get() next time
//
map.put(key, result);
return result;
}
}
///
/// If all possible combinations of "wildcard" between "level" and
/// the fourth part of "name" have been tried, try the left part
///
--level;
}
//
// The map actually has no exact key as the given "key", putting it back
// into map can speed up the get() next time even we got nothing.
//
map.put(key, result);
return result;
}
/**
Wrapper function for Map.size().
@return int The size of map
**/
public int size() {
return map.size();
}
/**
Wrapper function for Map.keySet().
@return Set<ToolChainKey> A set of ToolChainKey objects
*/
public Set<ToolChainKey> keySet() {
return (Set<ToolChainKey>)map.keySet();
}
}

View File

@ -0,0 +1,140 @@
/** @file
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.tools;
import org.apache.tools.ant.BuildException;
/**
Ant element for module.
@since GenBuild 1.0
**/
public class ModuleItem {
private String moduleName = null;
private String moduleGuid = null;
private String moduleVersion = null;
private String packageName = null;
private String packageGuid = null;
private String packageVersion = null;
public ModuleItem(){
}
public void execute() throws BuildException {
}
/**
Get module Guid.
@return Module Guid
**/
public String getModuleGuid() {
return moduleGuid;
}
/**
Set module Guid
@param moduleGuid Module Guid
**/
public void setModuleGuid(String moduleGuid) {
this.moduleGuid = moduleGuid;
}
/**
Get Module Name.
@return Module Name
**/
public String getModuleName() {
return moduleName;
}
/**
Set Module Name.
@param moduleName Module Name
**/
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
/**
Get Module Version.
@return Module Version
**/
public String getModuleVersion() {
return moduleVersion;
}
/**
Set Module Version.
@param moduleVersion Module version
**/
public void setModuleVersion(String moduleVersion) {
this.moduleVersion = moduleVersion;
}
/**
Get Package Guid.
@return Package Guid
**/
public String getPackageGuid() {
return packageGuid;
}
/**
Set Package Guid.
@param packageGuid Package Guid
**/
public void setPackageGuid(String packageGuid) {
this.packageGuid = packageGuid;
}
/**
Get Package Name.
@return Package Name
**/
public String getPackageName() {
return packageName;
}
/**
Set Package Name.
@param packageName Package Name
**/
public void setPackageName(String packageName) {
this.packageName = packageName;
}
/**
Get Package Version.
@return Package Version
**/
public String getPackageVersion() {
return packageVersion;
}
/**
Set Package Version.
@param packageVersion Package Version
**/
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
}

View File

@ -0,0 +1,88 @@
/** @file
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
package org.tianocore.build.tools;
import org.apache.tools.ant.BuildException;
/**
Ant element for Package.
@since GenBuild 1.0
**/
public class PackageItem {
private String packageName = null;
private String packageGuid = null;
private String packageVersion = null;
public PackageItem(){
}
public void execute() throws BuildException {
}
public String toString(){
return "[" + packageName + packageGuid + "]";
}
/**
Get Package Guid.
@return Package Guid
**/
public String getPackageGuid() {
return packageGuid;
}
/**
Set Package Guid.
@param packageGuid Package Guid
**/
public void setPackageGuid(String packageGuid) {
this.packageGuid = packageGuid;
}
/**
Get Package Name.
@return Package Name
**/
public String getPackageName() {
return packageName;
}
/**
Set Package Name.
@param packageName Package Name
**/
public void setPackageName(String packageName) {
this.packageName = packageName;
}
/**
Get Package Version.
@return Package Version
**/
public String getPackageVersion() {
return packageVersion;
}
/**
Set Package Version.
@param packageVersion Package Version
**/
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
}