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:
84
Tools/Java/Source/GenBuild/GenBuild.msa
Normal file
84
Tools/Java/Source/GenBuild/GenBuild.msa
Normal 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>
|
8
Tools/Java/Source/GenBuild/GenBuild.tasks
Normal file
8
Tools/Java/Source/GenBuild/GenBuild.tasks
Normal 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
|
54
Tools/Java/Source/GenBuild/build.xml
Normal file
54
Tools/Java/Source/GenBuild/build.xml
Normal 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>
|
422
Tools/Java/Source/GenBuild/org/tianocore/build/FfsProcess.java
Normal file
422
Tools/Java/Source/GenBuild/org/tianocore/build/FfsProcess.java
Normal 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>
|
||||
<Ffs type="APPLICATION">
|
||||
<Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_APPLICATION" />
|
||||
<Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />
|
||||
<Sections EncapsulationType="Compress">
|
||||
<Sections EncapsulationType="Guid-Defined">
|
||||
<Section SectionType="EFI_SECTION_PE32" />
|
||||
<Section SectionType="EFI_SECTION_USER_INTERFACE" />
|
||||
<Section SectionType="EFI_SECTION_VERSION" />
|
||||
</Sections>
|
||||
</Sections>
|
||||
</Ffs>
|
||||
</pre>
|
||||
|
||||
@since GenBuild 1.0
|
||||
**/
|
||||
public class FfsProcess {
|
||||
|
||||
private BuildOptionsDocument.BuildOptions.Ffs ffsXmlObject;
|
||||
|
||||
///
|
||||
/// ANT script to call GenFfs
|
||||
///
|
||||
private Element ffsNode = null;
|
||||
|
||||
///
|
||||
/// Module base name
|
||||
///
|
||||
private String basename;
|
||||
|
||||
///
|
||||
/// Sections type: normal
|
||||
///
|
||||
private static int MODE_NONE = 0;
|
||||
|
||||
///
|
||||
/// Sections type: compress
|
||||
///
|
||||
private static int MODE_COMPRESS = 1;
|
||||
|
||||
///
|
||||
/// Sections type: guid-define
|
||||
///
|
||||
private static int MODE_GUID_DEFINED = 2;
|
||||
|
||||
///
|
||||
/// mapping from section type to section output file extension
|
||||
///
|
||||
public static final String[][] sectionExt = EdkDefinitions.SectionTypeExtensions;
|
||||
|
||||
/**
|
||||
search in the type, if componentType is listed in type, return true;
|
||||
otherwise return false.
|
||||
|
||||
@param type a list supported component type separated by comma
|
||||
@param componentType current module component type
|
||||
@return whether componentType is one of type
|
||||
**/
|
||||
private boolean isMatch(String type, String componentType) {
|
||||
String[] items = type.split("[ \t]*,[ \t]*");
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
if (items[i].equalsIgnoreCase(componentType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
Find the corresponding FFS layout in <code>FPD</code>.
|
||||
|
||||
@param buildType Current module's component type
|
||||
@param project Ant project
|
||||
@return whether find the corresponding FFS layout
|
||||
@throws BuildException
|
||||
If can't find FFS Layout in FPD.
|
||||
**/
|
||||
public boolean initSections(String buildType, Project project, FpdModuleIdentification fpdModuleId) throws BuildException {
|
||||
//
|
||||
// Try to find Ffs layout from FPD file
|
||||
//
|
||||
SurfaceAreaQuery saq = new SurfaceAreaQuery(GlobalData.getFpdBuildOptionsMap());
|
||||
BuildOptionsDocument.BuildOptions.Ffs[] ffsArray = saq.getFpdFfs();
|
||||
for (int i = 0; i < ffsArray.length; i++) {
|
||||
if (isMatch(ffsArray[i].getFfsKey(), buildType)) {
|
||||
ffsXmlObject = ffsArray[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If FfsFormatKey is not null, report exception and fail build
|
||||
// Otherwise report warning message
|
||||
//
|
||||
if (buildType == null) {
|
||||
EdkLog.log(EdkLog.EDK_WARNING, "Warning: this module doesn't specify a FfsFormatKey. ");
|
||||
} else {
|
||||
throw new BuildException("Can't find the FfsFormatKey [" + buildType + "] attribute in the FPD file!");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
Recursive parse the FFS layout. Find out all section type here used.
|
||||
|
||||
@param document BaseName_build.xml Xml document
|
||||
@param basename Module's base name
|
||||
@param guid Module's GUID
|
||||
@param targetFilename Module's final file name (GUID-BaseName.APP)
|
||||
@return List of section type
|
||||
**/
|
||||
public String[] getGenSectionElements(Document document, String basename, String guid, String targetFilename) {
|
||||
this.basename = basename;
|
||||
if (ffsXmlObject == null) {
|
||||
return new String[0];
|
||||
}
|
||||
Vector<String> sectionList = new Vector<String>();
|
||||
XmlCursor cursor = null;
|
||||
|
||||
cursor = ffsXmlObject.newCursor();
|
||||
|
||||
int mode = MODE_NONE;
|
||||
Element genffsfileEle = document.createElement("genffsfile");
|
||||
genffsfileEle.setAttribute("outputDir", "${BIN_DIR}");
|
||||
genffsfileEle.setAttribute("moduleType", "${MODULE_TYPE}");
|
||||
genffsfileEle.setAttribute("BaseName", basename);
|
||||
genffsfileEle.setAttribute("fileGuid", guid);
|
||||
|
||||
if (cursor.toFirstChild()) {
|
||||
do {
|
||||
if (cursor.getName().getLocalPart().equalsIgnoreCase("Attribute")) {
|
||||
String name = cursor.getAttributeText(new QName("Name"));
|
||||
String value = cursor.getAttributeText(new QName("Value"));
|
||||
genffsfileEle.setAttribute(changeAttributeName(name), value);
|
||||
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {
|
||||
cursor.push();
|
||||
dealSection(mode, document, genffsfileEle, cursor, sectionList);
|
||||
cursor.pop();
|
||||
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {
|
||||
cursor.push();
|
||||
dealSections(mode, document, genffsfileEle, cursor, sectionList);
|
||||
cursor.pop();
|
||||
}
|
||||
} while (cursor.toNextSibling());
|
||||
}
|
||||
//
|
||||
// Check dependency
|
||||
//
|
||||
Element outofdateEle = document.createElement("OnDependency");
|
||||
Element sourceEle = document.createElement("sourcefiles");
|
||||
String[] result = new String[sectionList.size()];
|
||||
for (int i = 0; i < sectionList.size(); i++) {
|
||||
result[i] = (String) sectionList.get(i);
|
||||
Element pathEle = document.createElement("file");
|
||||
pathEle.setAttribute("name", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename
|
||||
+ getSectionExt(result[i]));
|
||||
sourceEle.appendChild(pathEle);
|
||||
}
|
||||
outofdateEle.appendChild(sourceEle);
|
||||
Element targetEle = document.createElement("targetfiles");
|
||||
Element fileEle = document.createElement("file");
|
||||
fileEle.setAttribute("name", "${BIN_DIR}" + File.separatorChar + targetFilename);
|
||||
targetEle.appendChild(fileEle);
|
||||
outofdateEle.appendChild(targetEle);
|
||||
Element sequentialEle = document.createElement("sequential");
|
||||
sequentialEle.appendChild(genffsfileEle);
|
||||
outofdateEle.appendChild(sequentialEle);
|
||||
ffsNode = outofdateEle;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
Change the attribute name. For example:
|
||||
|
||||
<pre>
|
||||
Before change: FFS_ATTRIB_CHECKSUM
|
||||
After change: ffsATTRIBCHECKSUM
|
||||
</pre>
|
||||
|
||||
@param name Original attribute name
|
||||
@return Changed attribute name
|
||||
**/
|
||||
private String changeAttributeName(String name) {
|
||||
String[] strs = name.split("_");
|
||||
String str = strs[0].toLowerCase();
|
||||
for (int j = 1; j < strs.length; j++) {
|
||||
str += strs[j];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
Recursively deal with Sections. If sections does not specify a type, then omit it.
|
||||
|
||||
@param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
|
||||
@param doc Xml Document
|
||||
@param root Root Node
|
||||
@param cursor Current FFS layout cursor
|
||||
@param list List of section type here used
|
||||
**/
|
||||
private void dealSections(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {
|
||||
String type = cursor.getAttributeText(new QName("EncapsulationType"));
|
||||
String toolName = cursor.getAttributeText(new QName("ToolName"));
|
||||
String sectType = cursor.getAttributeText(new QName("SectionType"));
|
||||
if (type == null && sectType == null) {
|
||||
if (cursor.toFirstChild()) {
|
||||
do {
|
||||
if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {
|
||||
cursor.push();
|
||||
dealSection(mode, doc, root, cursor, list);
|
||||
cursor.pop();
|
||||
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {
|
||||
cursor.push();
|
||||
dealSections(mode, doc, root, cursor, list);
|
||||
cursor.pop();
|
||||
}
|
||||
} while (cursor.toNextSibling());
|
||||
}
|
||||
return;
|
||||
}
|
||||
Element ele;
|
||||
Element toolEle = null;
|
||||
if (type.equalsIgnoreCase("COMPRESS") && (toolName == null || toolName.equalsIgnoreCase(""))) {
|
||||
mode = MODE_COMPRESS;
|
||||
//
|
||||
// <gensection sectiontype="EFI_SECTION_COMPRESSION">
|
||||
//
|
||||
ele = doc.createElement("gensection");
|
||||
ele.setAttribute("sectionType", "EFI_SECTION_COMPRESSION");
|
||||
|
||||
} else {
|
||||
mode = MODE_GUID_DEFINED;
|
||||
//
|
||||
// <gensection sectiontype="EFI_SECTION_GUID_DEFINED">
|
||||
//
|
||||
ele = doc.createElement("gensection");
|
||||
if (type != null) {
|
||||
if (type.equalsIgnoreCase("COMPRESS")) {
|
||||
ele.setAttribute("sectionType", "EFI_SECTION_COMPRESSION");
|
||||
}else {
|
||||
ele.setAttribute("sectiontype", "EFI_SECTION_GUID_DEFINED");
|
||||
}
|
||||
|
||||
} else {
|
||||
ele.setAttribute("sectiontype", sectType);
|
||||
}
|
||||
//
|
||||
// <tool toolName="${OEMTOOLPATH}\toolname"
|
||||
// outputPath = "${DEST_DIR_OUTPUT}">
|
||||
//
|
||||
toolEle = doc.createElement("tool");
|
||||
if (toolName == null || toolName.equalsIgnoreCase("")) {
|
||||
toolEle.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin"
|
||||
+ File.separatorChar + "GenCRC32Section");
|
||||
}else{
|
||||
File toolExe = new File(toolName);
|
||||
//
|
||||
// If <Tool> element exist, add sub element under <tool> .
|
||||
//
|
||||
if (toolExe.isAbsolute()) {
|
||||
toolEle.setAttribute("toolName", toolName);
|
||||
} else {
|
||||
toolEle.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin"
|
||||
+ File.separatorChar + toolName);
|
||||
}
|
||||
}
|
||||
|
||||
toolEle.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");
|
||||
ele.appendChild(toolEle);
|
||||
}
|
||||
if (cursor.toFirstChild()) {
|
||||
do {
|
||||
if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {
|
||||
cursor.push();
|
||||
if (toolEle == null) {
|
||||
dealSection(mode, doc, ele, cursor, list);
|
||||
} else {
|
||||
dealSection(mode, doc, toolEle, cursor, list);
|
||||
}
|
||||
|
||||
cursor.pop();
|
||||
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {
|
||||
cursor.push();
|
||||
if (toolEle == null) {
|
||||
dealSections(mode, doc, ele, cursor, list);
|
||||
} else {
|
||||
dealSections(mode, doc, toolEle, cursor, list);
|
||||
}
|
||||
|
||||
cursor.pop();
|
||||
}
|
||||
} while (cursor.toNextSibling());
|
||||
}
|
||||
root.appendChild(ele);
|
||||
}
|
||||
|
||||
/**
|
||||
Recursively deal with section.
|
||||
|
||||
@param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
|
||||
@param doc Xml Document
|
||||
@param root Root Node
|
||||
@param cursor Current FFS layout cursor
|
||||
@param list List of section type here used
|
||||
**/
|
||||
private void dealSection(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {
|
||||
String type = cursor.getAttributeText(new QName("SectionType"));
|
||||
|
||||
//
|
||||
// Judge if file is specified? Yes, just use the file, else call Build Macro
|
||||
// If fileName is null, means without FileNames specify in FPD file
|
||||
//
|
||||
String fileName = null;
|
||||
cursor.push();
|
||||
if (cursor.toFirstChild()) {
|
||||
do {
|
||||
if (cursor.getName().getLocalPart().equalsIgnoreCase("Filenames")) {
|
||||
cursor.push();
|
||||
if (cursor.toFirstChild()) {
|
||||
do {
|
||||
if (cursor.getName().getLocalPart().equalsIgnoreCase("Filename")) {
|
||||
fileName = cursor.getTextValue();
|
||||
}
|
||||
} while (cursor.toNextSibling());
|
||||
}
|
||||
cursor.pop();
|
||||
}
|
||||
} while (cursor.toNextSibling());
|
||||
}
|
||||
|
||||
cursor.pop();
|
||||
|
||||
if (fileName == null) {
|
||||
list.addElement(type);
|
||||
}
|
||||
if (mode == MODE_GUID_DEFINED) {
|
||||
//
|
||||
// <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>
|
||||
//
|
||||
Element ele = doc.createElement("input");
|
||||
if (fileName == null) {
|
||||
ele.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));
|
||||
} else {
|
||||
ele.setAttribute("file", "${PLATFORM_DIR}" + File.separatorChar + fileName);
|
||||
}
|
||||
root.appendChild(ele);
|
||||
} else {
|
||||
//
|
||||
// <sectFile fileName= "..."/>
|
||||
//
|
||||
Element ele = doc.createElement("sectFile");
|
||||
if (fileName == null) {
|
||||
ele.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));
|
||||
} else {
|
||||
ele.setAttribute("fileName", "${PLATFORM_DIR}" + File.separatorChar + fileName);
|
||||
}
|
||||
root.appendChild(ele);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Get the corresponding section file suffix.
|
||||
|
||||
@param type Section type
|
||||
@return Corresponding section file extension
|
||||
**/
|
||||
private String getSectionExt(String type) {
|
||||
for (int i = 0; i < sectionExt.length; i++) {
|
||||
if (sectionExt[i][0].equalsIgnoreCase(type)) {
|
||||
return sectionExt[i][1];
|
||||
}
|
||||
}
|
||||
return ".sec";
|
||||
}
|
||||
|
||||
/**
|
||||
Return the ANT script to call GenFfs Tool.
|
||||
|
||||
@return ANT script to call GenFfs Tool
|
||||
**/
|
||||
public Element getFfsNode() {
|
||||
return ffsNode;
|
||||
}
|
||||
}
|
263
Tools/Java/Source/GenBuild/org/tianocore/build/FileProcess.java
Normal file
263
Tools/Java/Source/GenBuild/org/tianocore/build/FileProcess.java
Normal 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);
|
||||
}
|
||||
}
|
@ -0,0 +1,448 @@
|
||||
/** @file FrameworkBuildTask.java
|
||||
|
||||
The file is ANT task to find MSA or FPD file and build them.
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
package org.tianocore.build;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.Task;
|
||||
import org.tianocore.build.exception.AutoGenException;
|
||||
import org.tianocore.build.exception.GenBuildException;
|
||||
import org.tianocore.build.exception.PcdAutogenException;
|
||||
import org.tianocore.build.exception.PlatformPcdPreprocessBuildException;
|
||||
import org.tianocore.build.fpd.FpdParserForThread;
|
||||
import org.tianocore.build.fpd.FpdParserTask;
|
||||
import org.tianocore.build.global.GenBuildLogger;
|
||||
import org.tianocore.build.global.GlobalData;
|
||||
import org.tianocore.build.toolchain.ConfigReader;
|
||||
import org.tianocore.build.toolchain.ToolChainInfo;
|
||||
import org.tianocore.common.definitions.ToolDefinitions;
|
||||
import org.tianocore.common.exception.EdkException;
|
||||
import org.tianocore.common.logger.EdkLog;
|
||||
|
||||
/**
|
||||
<p>
|
||||
<code>FrameworkBuildTask</code> is an Ant task. The main function is finding
|
||||
and processing a FPD or MSA file, then building a platform or stand-alone
|
||||
module.
|
||||
|
||||
<p>
|
||||
The task search current directory and find out all MSA and FPD files by file
|
||||
extension. Base on ACTIVE_PLATFORM policy, decide to build a platform or a
|
||||
stand-alone module. The ACTIVE_PLATFORM policy is:
|
||||
|
||||
<pre>
|
||||
1. More than one MSA files, report error;
|
||||
2. Only one MSA file, but ACTIVE_PLATFORM is not specified, report error;
|
||||
3. Only one MSA file, and ACTIVE_PLATFORM is also specified, build this module;
|
||||
4. No MSA file, and ACTIVE_PLATFORM is specified, build the active platform;
|
||||
5. No MSA file, no ACTIVE_PLATFORM, and no FPD file, report error;
|
||||
6. No MSA file, no ACTIVE_PLATFORM, and only one FPD file, build the platform;
|
||||
7. No MSA file, no ACTIVE_PLATFORM, and more than one FPD files, list all platform
|
||||
and let user choose one.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Framework build task also parse target file [${WORKSPACE_DIR}/Tools/Conf/target.txt].
|
||||
And load all system environment variables to Ant properties.
|
||||
|
||||
<p>
|
||||
The usage for this task is :
|
||||
|
||||
<pre>
|
||||
<FrameworkBuild type="cleanall" />
|
||||
</pre>
|
||||
|
||||
@since GenBuild 1.0
|
||||
**/
|
||||
public class FrameworkBuildTask extends Task{
|
||||
|
||||
private Set<File> buildFiles = new LinkedHashSet<File>();
|
||||
|
||||
private Set<File> fpdFiles = new LinkedHashSet<File>();
|
||||
|
||||
private Set<File> msaFiles = new LinkedHashSet<File>();
|
||||
|
||||
//
|
||||
// This is only for none-multi-thread build to reduce overriding message
|
||||
//
|
||||
public static Hashtable<String, String> originalProperties = new Hashtable<String, String>();
|
||||
|
||||
String toolsDefFilename = ToolDefinitions.DEFAULT_TOOLS_DEF_FILE_PATH;
|
||||
|
||||
String targetFilename = ToolDefinitions.TARGET_FILE_PATH;
|
||||
|
||||
String dbFilename = ToolDefinitions.FRAMEWORK_DATABASE_FILE_PATH;
|
||||
|
||||
String activePlatform = null;
|
||||
|
||||
///
|
||||
/// The flag to present current is multi-thread enabled
|
||||
///
|
||||
public static boolean multithread = false;
|
||||
|
||||
///
|
||||
/// The concurrent thread number
|
||||
///
|
||||
public static int MAX_CONCURRENT_THREAD_NUMBER = 2;
|
||||
|
||||
///
|
||||
/// there are three type: all (build), clean and cleanall
|
||||
///
|
||||
private String type = "all";
|
||||
|
||||
public void execute() throws BuildException {
|
||||
//
|
||||
// set Logger
|
||||
//
|
||||
GenBuildLogger logger = new GenBuildLogger(getProject());
|
||||
EdkLog.setLogLevel(getProject().getProperty("env.LOGLEVEL"));
|
||||
EdkLog.setLogger(logger);
|
||||
|
||||
try {
|
||||
processFrameworkBuild();
|
||||
} catch (PcdAutogenException e) {
|
||||
//
|
||||
// Add more logic process here
|
||||
//
|
||||
throw new BuildException(e.getMessage());
|
||||
} catch (AutoGenException e) {
|
||||
//
|
||||
// Add more logic process here
|
||||
//
|
||||
throw new BuildException(e.getMessage());
|
||||
} catch (PlatformPcdPreprocessBuildException e) {
|
||||
//
|
||||
// Add more logic process here
|
||||
//
|
||||
throw new BuildException(e.getMessage());
|
||||
} catch (GenBuildException e) {
|
||||
//
|
||||
// Add more logic process here
|
||||
//
|
||||
throw new BuildException(e.getMessage());
|
||||
} catch (EdkException e) {
|
||||
//
|
||||
// Add more logic process here
|
||||
//
|
||||
throw new BuildException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void processFrameworkBuild() throws EdkException, GenBuildException, AutoGenException, PcdAutogenException, PlatformPcdPreprocessBuildException {
|
||||
//
|
||||
// Seach build.xml -> .FPD -> .MSA file
|
||||
//
|
||||
try {
|
||||
//
|
||||
// Gen Current Working Directory
|
||||
//
|
||||
File dummyFile = new File(".");
|
||||
File cwd = dummyFile.getCanonicalFile();
|
||||
File[] files = cwd.listFiles();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
if (files[i].isFile()) {
|
||||
if (files[i].getName().equalsIgnoreCase("build.xml")) {
|
||||
//
|
||||
// First, search build.xml, if found, ANT call it
|
||||
//
|
||||
buildFiles.add(files[i]);
|
||||
|
||||
} else if (files[i].getName().endsWith(ToolDefinitions.FPD_EXTENSION)) {
|
||||
//
|
||||
// Second, search FPD file, if found, build it
|
||||
//
|
||||
fpdFiles.add(files[i]);
|
||||
} else if (files[i].getName().endsWith(ToolDefinitions.MSA_EXTENSION)) {
|
||||
//
|
||||
// Third, search MSA file, if found, build it
|
||||
//
|
||||
msaFiles.add(files[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
BuildException buildException = new BuildException("Scanning current directory error. \n" + ex.getMessage());
|
||||
buildException.setStackTrace(ex.getStackTrace());
|
||||
throw buildException;
|
||||
}
|
||||
|
||||
//
|
||||
// Deal with all environment variable (Add them to properties)
|
||||
//
|
||||
backupSystemProperties();
|
||||
|
||||
//
|
||||
// Read target.txt file
|
||||
//
|
||||
readTargetFile();
|
||||
|
||||
//
|
||||
// Global Data initialization
|
||||
//
|
||||
File workspacePath = new File(getProject().getProperty("WORKSPACE"));
|
||||
getProject().setProperty("WORKSPACE_DIR", workspacePath.getPath().replaceAll("(\\\\)", "/"));
|
||||
GlobalData.initInfo(dbFilename, workspacePath.getPath(), toolsDefFilename);
|
||||
|
||||
//
|
||||
// If find MSA file and ACTIVE_PLATFORM is set, build the module;
|
||||
// else fail build.
|
||||
// If without MSA file, and ACTIVE_PLATFORM is set, build the ACTIVE_PLATFORM.
|
||||
// If ACTIVE_PLATFORM is not set, and only find one FPD file, build the platform;
|
||||
// If find more than one FPD files, let user select one.
|
||||
//
|
||||
File buildFile = null;
|
||||
if (msaFiles.size() > 1) {
|
||||
throw new BuildException("Having more than one MSA file in a directory is not allowed!");
|
||||
} else if (msaFiles.size() == 1 && activePlatform == null) {
|
||||
throw new BuildException("If trying to build a single module, please set ACTIVE_PLATFORM in file [" + targetFilename + "]. ");
|
||||
} else if (msaFiles.size() == 1 && activePlatform != null) {
|
||||
//
|
||||
// Build the single module
|
||||
//
|
||||
buildFile = msaFiles.toArray(new File[1])[0];
|
||||
} else if (activePlatform != null) {
|
||||
buildFile = new File(GlobalData.getWorkspacePath() + File.separatorChar + activePlatform);
|
||||
} else if (fpdFiles.size() == 1) {
|
||||
buildFile = fpdFiles.toArray(new File[1])[0];
|
||||
} else if (fpdFiles.size() > 1) {
|
||||
buildFile = intercommuniteWithUser();
|
||||
}
|
||||
//
|
||||
// If there is no build files or FPD files or MSA files, stop build
|
||||
//
|
||||
else {
|
||||
throw new BuildException("Can't find any FPD or MSA files in the current directory. ");
|
||||
}
|
||||
|
||||
//
|
||||
// Build every FPD files (PLATFORM build)
|
||||
//
|
||||
if (buildFile.getName().endsWith(ToolDefinitions.FPD_EXTENSION)) {
|
||||
EdkLog.log(this, "Processing the FPD file [" + buildFile.getPath() + "] ..>> ");
|
||||
//
|
||||
// Iff for platform build will enable the multi-thread if set in target.txt
|
||||
//
|
||||
if (multithread && type.equalsIgnoreCase("all")) {
|
||||
EdkLog.log(this, "Multi-thread build is enabled. ");
|
||||
FpdParserForThread fpdParserForThread = new FpdParserForThread();
|
||||
fpdParserForThread.setType(type);
|
||||
fpdParserForThread.setProject(getProject());
|
||||
fpdParserForThread.setFpdFile(buildFile);
|
||||
fpdParserForThread.perform();
|
||||
return ;
|
||||
}
|
||||
|
||||
FpdParserTask fpdParserTask = new FpdParserTask();
|
||||
fpdParserTask.setType(type);
|
||||
fpdParserTask.setProject(getProject());
|
||||
fpdParserTask.setFpdFile(buildFile);
|
||||
fpdParserTask.perform();
|
||||
|
||||
//
|
||||
// If cleanall delete the Platform_build.xml
|
||||
//
|
||||
if (type.compareTo("cleanall") == 0) {
|
||||
File platformBuildFile =
|
||||
new File(getProject().getProperty("BUILD_DIR")
|
||||
+ File.separatorChar
|
||||
+ getProject().getProperty("PLATFORM")
|
||||
+ "_build.xml");
|
||||
platformBuildFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Build every MSA files (SINGLE MODULE BUILD)
|
||||
//
|
||||
else if (buildFile.getName().endsWith(ToolDefinitions.MSA_EXTENSION)) {
|
||||
if (multithread) {
|
||||
EdkLog.log(this, EdkLog.EDK_WARNING, "Multi-Thead do not take effect on Stand-Alone (Single) module build. ");
|
||||
multithread = false;
|
||||
}
|
||||
File tmpFile = new File(GlobalData.getWorkspacePath() + File.separatorChar + activePlatform);
|
||||
EdkLog.log(this, "Using the FPD file [" + tmpFile.getPath() + "] for the active platform. ");
|
||||
EdkLog.log(this, "Processing the MSA file [" + buildFile.getPath() + "] ..>> ");
|
||||
GenBuildTask genBuildTask = new GenBuildTask();
|
||||
genBuildTask.setSingleModuleBuild(true);
|
||||
genBuildTask.setType(type);
|
||||
getProject().setProperty("PLATFORM_FILE", activePlatform);
|
||||
if( !multithread) {
|
||||
originalProperties.put("PLATFORM_FILE", activePlatform);
|
||||
}
|
||||
genBuildTask.setProject(getProject());
|
||||
genBuildTask.setMsaFile(buildFile);
|
||||
genBuildTask.perform();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Transfer system environment variables to ANT properties. If system variable
|
||||
already exiests in ANT properties, skip it.
|
||||
|
||||
**/
|
||||
private void backupSystemProperties() {
|
||||
Map<String, String> sysProperties = System.getenv();
|
||||
Iterator<String> iter = sysProperties.keySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
String name = iter.next();
|
||||
|
||||
//
|
||||
// If system environment variable is not in ANT properties, add it
|
||||
//
|
||||
if (getProject().getProperty(name) == null) {
|
||||
getProject().setProperty(name, sysProperties.get(name));
|
||||
}
|
||||
}
|
||||
|
||||
Hashtable allProperties = getProject().getProperties();
|
||||
Iterator piter = allProperties.keySet().iterator();
|
||||
while (piter.hasNext()) {
|
||||
String name = (String)piter.next();
|
||||
originalProperties.put(new String(name), new String((String)allProperties.get(name)));
|
||||
}
|
||||
}
|
||||
|
||||
private File intercommuniteWithUser(){
|
||||
File file = null;
|
||||
if (fpdFiles.size() > 1) {
|
||||
File[] allFiles = new File[fpdFiles.size()];
|
||||
int index = 0;
|
||||
Iterator<File> iter = fpdFiles.iterator();
|
||||
while (iter.hasNext()) {
|
||||
allFiles[index] = iter.next();
|
||||
index++;
|
||||
}
|
||||
|
||||
EdkLog.log(this, "Finding " + allFiles.length + " FPD files: ");
|
||||
for (int i = 0; i < allFiles.length; i++) {
|
||||
System.out.println("[" + (i + 1) + "]: " + allFiles[i].getName());
|
||||
}
|
||||
|
||||
boolean flag = true;
|
||||
EdkLog.log(this, "Please select one of the following FPD files to build:[1] ");
|
||||
do{
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
|
||||
try {
|
||||
String str = br.readLine();
|
||||
if (str.trim().length() == 0) {
|
||||
file = allFiles[0];
|
||||
flag = false;
|
||||
continue ;
|
||||
}
|
||||
int indexSelect = Integer.parseInt(str);
|
||||
if (indexSelect <=0 || indexSelect > allFiles.length) {
|
||||
EdkLog.log(this, "Please enter a number between [1.." + allFiles.length + "]:[1] ");
|
||||
continue ;
|
||||
} else {
|
||||
file = allFiles[indexSelect - 1];
|
||||
flag = false;
|
||||
continue ;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
EdkLog.log(this, "Please enter a valid number:[1] ");
|
||||
flag = true;
|
||||
}
|
||||
} while (flag);
|
||||
} else if (fpdFiles.size() == 1) {
|
||||
file = fpdFiles.toArray(new File[1])[0];
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
public void setType(String type) {
|
||||
if (type.equalsIgnoreCase("clean") || type.equalsIgnoreCase("cleanall")) {
|
||||
this.type = type.toLowerCase();
|
||||
} else {
|
||||
this.type = "all";
|
||||
}
|
||||
}
|
||||
|
||||
private void readTargetFile() throws EdkException{
|
||||
String targetFile = getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + targetFilename;
|
||||
|
||||
String[][] targetFileInfo = ConfigReader.parse(targetFile);
|
||||
|
||||
//
|
||||
// Get ToolChain Info from target.txt
|
||||
//
|
||||
ToolChainInfo envToolChainInfo = new ToolChainInfo();
|
||||
String str = getValue(ToolDefinitions.TARGET_KEY_TARGET, targetFileInfo);
|
||||
if (str == null || str.trim().equals("")) {
|
||||
envToolChainInfo.addTargets("*");
|
||||
} else {
|
||||
envToolChainInfo.addTargets(str);
|
||||
}
|
||||
str = getValue(ToolDefinitions.TARGET_KEY_TOOLCHAIN, targetFileInfo);
|
||||
if (str == null || str.trim().equals("")) {
|
||||
envToolChainInfo.addTagnames("*");
|
||||
} else {
|
||||
envToolChainInfo.addTagnames(str);
|
||||
}
|
||||
str = getValue(ToolDefinitions.TARGET_KEY_ARCH, targetFileInfo);
|
||||
if (str == null || str.trim().equals("")) {
|
||||
envToolChainInfo.addArchs("*");
|
||||
} else {
|
||||
envToolChainInfo.addArchs(str);
|
||||
}
|
||||
GlobalData.setToolChainEnvInfo(envToolChainInfo);
|
||||
|
||||
str = getValue(ToolDefinitions.TARGET_KEY_TOOLS_DEF, targetFileInfo);
|
||||
if (str != null && str.trim().length() > 0) {
|
||||
toolsDefFilename = str;
|
||||
}
|
||||
|
||||
str = getValue(ToolDefinitions.TARGET_KEY_ACTIVE_PLATFORM, targetFileInfo);
|
||||
if (str != null && ! str.trim().equals("")) {
|
||||
if ( ! str.endsWith(".fpd")) {
|
||||
throw new BuildException("FPD file's extension must be \"" + ToolDefinitions.FPD_EXTENSION + "\"!");
|
||||
}
|
||||
activePlatform = str;
|
||||
}
|
||||
|
||||
str = getValue(ToolDefinitions.TARGET_KEY_MULTIPLE_THREAD, targetFileInfo);
|
||||
if (str != null && str.trim().equalsIgnoreCase("Enable")) {
|
||||
multithread = true;
|
||||
}
|
||||
|
||||
str = getValue(ToolDefinitions.TARGET_KEY_MAX_CONCURRENT_THREAD_NUMBER, targetFileInfo);
|
||||
if (str != null ) {
|
||||
try {
|
||||
int threadNum = Integer.parseInt(str);
|
||||
if (threadNum > 0) {
|
||||
MAX_CONCURRENT_THREAD_NUMBER = threadNum;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getValue(String key, String[][] map) {
|
||||
for (int i = 0; i < map[0].length; i++){
|
||||
if (key.equalsIgnoreCase(map[0][i])) {
|
||||
return map[1][i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
840
Tools/Java/Source/GenBuild/org/tianocore/build/GenBuildTask.java
Normal file
840
Tools/Java/Source/GenBuild/org/tianocore/build/GenBuildTask.java
Normal 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>
|
||||
<GenBuild
|
||||
msaFile="${PACKAGE_DIR}/Application/HelloWorld/HelloWorld.msa"
|
||||
type="cleanall" />
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and
|
||||
<em>AutoGen.h</em>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This task will also set properties for current module, such as PACKAGE,
|
||||
PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
|
||||
(relative to Workspace), MODULE or BASE_NAME, GUID, VERSION, MODULE_DIR,
|
||||
MODULE_RELATIVE_DIR (relative to Package), CONFIG_DIR, BIN_DIR,
|
||||
DEST_DIR_DEBUG, DEST_DIR_OUTPUT, TARGET, ARCH, TOOLCHAIN, TOOLCHAIN_FAMILY,
|
||||
SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH, all compiler command related
|
||||
properties (CC, CC_FLAGS, CC_DPATH, CC_SPATH, CC_FAMILY, CC_EXT).
|
||||
</p>
|
||||
|
||||
@since GenBuild 1.0
|
||||
**/
|
||||
public class GenBuildTask extends Ant {
|
||||
|
||||
///
|
||||
/// Module surface area file.
|
||||
///
|
||||
File msaFile;
|
||||
|
||||
public ModuleIdentification parentId;
|
||||
|
||||
private String type = "all";
|
||||
|
||||
///
|
||||
/// Module's Identification.
|
||||
///
|
||||
private ModuleIdentification moduleId;
|
||||
|
||||
private Vector<Property> properties = new Vector<Property>();
|
||||
|
||||
private boolean isSingleModuleBuild = false;
|
||||
|
||||
private SurfaceAreaQuery saq = null;
|
||||
|
||||
/**
|
||||
Public construct method. It is necessary for ANT task.
|
||||
**/
|
||||
public GenBuildTask() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@throws BuildException
|
||||
From module build, exception from module surface area invalid.
|
||||
**/
|
||||
public void execute() throws BuildException {
|
||||
this.setTaskName("GenBuild");
|
||||
try {
|
||||
processGenBuild();
|
||||
} catch (PcdAutogenException e) {
|
||||
//
|
||||
// Add more logic process here
|
||||
//
|
||||
throw new BuildException(e.getMessage());
|
||||
} catch (AutoGenException e) {
|
||||
//
|
||||
// Add more logic process here
|
||||
//
|
||||
throw new BuildException(e.getMessage());
|
||||
} catch (PlatformPcdPreprocessBuildException e) {
|
||||
//
|
||||
// Add more logic process here
|
||||
//
|
||||
throw new BuildException(e.getMessage());
|
||||
} catch (GenBuildException e) {
|
||||
//
|
||||
// Add more logic process here
|
||||
//
|
||||
throw new BuildException(e.getMessage());
|
||||
} catch (EdkException e) {
|
||||
//
|
||||
// Add more logic process here
|
||||
//
|
||||
throw new BuildException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void processGenBuild() throws EdkException, BuildException, GenBuildException, AutoGenException, PcdAutogenException, PlatformPcdPreprocessBuildException {
|
||||
if (!FrameworkBuildTask.multithread) {
|
||||
cleanupProperties();
|
||||
}
|
||||
|
||||
//
|
||||
// Enable all specified properties
|
||||
//
|
||||
Iterator<Property> iter = properties.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Property item = iter.next();
|
||||
getProject().setProperty(item.getName(), item.getValue());
|
||||
}
|
||||
|
||||
//
|
||||
// GenBuild should specify either msaFile or moduleGuid & packageGuid
|
||||
//
|
||||
if (msaFile == null ) {
|
||||
String moduleGuid = getProject().getProperty("MODULE_GUID");
|
||||
String moduleVersion = getProject().getProperty("MODULE_VERSION");
|
||||
String packageGuid = getProject().getProperty("PACKAGE_GUID");
|
||||
String packageVersion = getProject().getProperty("PACKAGE_VERSION");
|
||||
//
|
||||
// If one of module Guid or package Guid is not specified, report error
|
||||
//
|
||||
if (moduleGuid == null || packageGuid == null) {
|
||||
throw new BuildException("GenBuild parameter error.");
|
||||
}
|
||||
|
||||
PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);
|
||||
GlobalData.refreshPackageIdentification(packageId);
|
||||
moduleId = new ModuleIdentification(moduleGuid, moduleVersion);
|
||||
moduleId.setPackage(packageId);
|
||||
GlobalData.refreshModuleIdentification(moduleId);
|
||||
Map<String, XmlObject> doc = GlobalData.getNativeMsa(moduleId);
|
||||
saq = new SurfaceAreaQuery(doc);
|
||||
} else {
|
||||
Map<String, XmlObject> doc = GlobalData.getNativeMsa(msaFile);
|
||||
saq = new SurfaceAreaQuery(doc);
|
||||
moduleId = saq.getMsaHeader();
|
||||
moduleId.setMsaFile(msaFile);
|
||||
}
|
||||
|
||||
String[] producedLibraryClasses = saq.getLibraryClasses("ALWAYS_PRODUCED",null);
|
||||
if (producedLibraryClasses.length == 0) {
|
||||
moduleId.setLibrary(false);
|
||||
} else {
|
||||
moduleId.setLibrary(true);
|
||||
}
|
||||
|
||||
//
|
||||
// Judge whether it is single module build or not
|
||||
//
|
||||
if (isSingleModuleBuild) {
|
||||
//
|
||||
// Single Module build
|
||||
//
|
||||
prepareSingleModuleBuild();
|
||||
}
|
||||
|
||||
//
|
||||
// If single module : get arch from pass down, otherwise intersection MSA
|
||||
// supported ARCHs and tools def
|
||||
//
|
||||
Set<String> archListSupByToolChain = new LinkedHashSet<String>();
|
||||
String[] archs = GlobalData.getToolChainInfo().getArchs();
|
||||
|
||||
for (int i = 0; i < archs.length; i ++) {
|
||||
archListSupByToolChain.add(archs[i]);
|
||||
}
|
||||
|
||||
Set<String> archSet = new LinkedHashSet<String>();
|
||||
|
||||
if ( getProject().getProperty("ARCH") != null) {
|
||||
String[] fpdArchList = getProject().getProperty("ARCH").split(" ");
|
||||
|
||||
for (int i = 0; i < fpdArchList.length; i++) {
|
||||
if (archListSupByToolChain.contains(fpdArchList[i])) {
|
||||
archSet.add(fpdArchList[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
archSet = archListSupByToolChain;
|
||||
}
|
||||
|
||||
String[] archList = archSet.toArray(new String[archSet.size()]);
|
||||
|
||||
//
|
||||
// Judge if arch is all supported by current module. If not, throw Exception.
|
||||
//
|
||||
List moduleSupportedArchs = saq.getModuleSupportedArchs();
|
||||
if (moduleSupportedArchs != null) {
|
||||
for (int k = 0; k < archList.length; k++) {
|
||||
if ( ! moduleSupportedArchs.contains(archList[k])) {
|
||||
throw new BuildException("Specified architecture [" + archList[k] + "] is not supported by " + moduleId + ". The module " + moduleId + " only supports [" + moduleSupportedArchs + "] architectures.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k < archList.length; k++) {
|
||||
|
||||
getProject().setProperty("ARCH", archList[k]);
|
||||
|
||||
FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]);
|
||||
|
||||
//
|
||||
// Whether the module is built before
|
||||
//
|
||||
if (moduleId.isLibrary() == false && GlobalData.hasFpdModuleSA(fpdModuleId) == false) {
|
||||
EdkLog.log(this, EdkLog.EDK_WARNING, "Warning: " + moduleId + " for " + archList[k] + " was not found in current platform FPD file!\n");
|
||||
continue;
|
||||
} else if (GlobalData.isModuleBuilt(fpdModuleId)) {
|
||||
break;
|
||||
} else {
|
||||
GlobalData.registerBuiltModule(fpdModuleId);
|
||||
}
|
||||
|
||||
//
|
||||
// For Every TOOLCHAIN, TARGET
|
||||
//
|
||||
String[] targetList = GlobalData.getToolChainInfo().getTargets();
|
||||
for (int i = 0; i < targetList.length; i ++){
|
||||
//
|
||||
// Prepare for target related common properties
|
||||
// TARGET
|
||||
//
|
||||
getProject().setProperty("TARGET", targetList[i]);
|
||||
String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
|
||||
for(int j = 0; j < toolchainList.length; j ++){
|
||||
//
|
||||
// check if any tool is defined for current target + toolchain + arch
|
||||
// don't do anything if no tools found
|
||||
//
|
||||
if (GlobalData.isCommandSet(targetList[i], toolchainList[j], archList[k]) == false) {
|
||||
EdkLog.log(this, EdkLog.EDK_WARNING, "Warning: No build issued. No tools were found for [target=" + targetList[i] + " toolchain=" + toolchainList[j] + " arch=" + archList[k] + "]\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare for toolchain related common properties
|
||||
// TOOLCHAIN
|
||||
//
|
||||
getProject().setProperty("TOOLCHAIN", toolchainList[j]);
|
||||
|
||||
EdkLog.log(this, "Build " + moduleId + " start >>>");
|
||||
EdkLog.log(this, "Target: " + targetList[i] + " Tagname: " + toolchainList[j] + " Arch: " + archList[k]);
|
||||
saq.push(GlobalData.getDoc(fpdModuleId));
|
||||
|
||||
//
|
||||
// Prepare for all other common properties
|
||||
// PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
|
||||
// MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE
|
||||
// MODULE_DIR, MODULE_RELATIVE_DIR
|
||||
// SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH
|
||||
//
|
||||
setModuleCommonProperties(archList[k]);
|
||||
|
||||
//
|
||||
// OutputManage prepare for
|
||||
// BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR
|
||||
//
|
||||
OutputManager.getInstance().update(getProject());
|
||||
|
||||
if (type.equalsIgnoreCase("all") || type.equalsIgnoreCase("build")) {
|
||||
applyBuild(targetList[i], toolchainList[j], fpdModuleId);
|
||||
} else if (type.equalsIgnoreCase("clean")) {
|
||||
applyClean(fpdModuleId);
|
||||
} else if (type.equalsIgnoreCase("cleanall")) {
|
||||
applyCleanall(fpdModuleId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This method is used to prepare Platform-related information.
|
||||
|
||||
<p>In Single Module Build mode, platform-related information is not ready.
|
||||
The method read the system environment variable <code>ACTIVE_PLATFORM</code>
|
||||
and search in the Framework Database. Note that platform name in the Framework
|
||||
Database must be unique. </p>
|
||||
|
||||
**/
|
||||
private void prepareSingleModuleBuild() throws EdkException {
|
||||
//
|
||||
// Find out the package which the module belongs to
|
||||
//
|
||||
PackageIdentification packageId = GlobalData.getPackageForModule(moduleId);
|
||||
GlobalData.refreshPackageIdentification(packageId);
|
||||
moduleId.setPackage(packageId);
|
||||
GlobalData.refreshModuleIdentification(moduleId);
|
||||
|
||||
//
|
||||
// Read ACTIVE_PLATFORM's FPD file
|
||||
//
|
||||
String filename = getProject().getProperty("PLATFORM_FILE");
|
||||
|
||||
if (filename == null){
|
||||
throw new BuildException("Please set ACTIVE_PLATFORM in the file: Tools/Conf/target.txt if you want to build a single module!");
|
||||
}
|
||||
|
||||
PlatformIdentification platformId = GlobalData.getPlatform(filename);
|
||||
|
||||
//
|
||||
// Read FPD file (Call FpdParserTask's method)
|
||||
//
|
||||
FpdParserTask fpdParser = new FpdParserTask();
|
||||
fpdParser.setProject(getProject());
|
||||
fpdParser.parseFpdFile(platformId.getFpdFile());
|
||||
getProject().setProperty("ARCH", fpdParser.getAllArchForModule(moduleId));
|
||||
}
|
||||
|
||||
private void cleanupProperties() {
|
||||
Project newProject = new Project();
|
||||
|
||||
Hashtable<String, String> passdownProperties = FrameworkBuildTask.originalProperties;
|
||||
Iterator<String> iter = passdownProperties.keySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
String item = iter.next();
|
||||
newProject.setProperty(item, passdownProperties.get(item));
|
||||
}
|
||||
|
||||
newProject.setInputHandler(getProject().getInputHandler());
|
||||
|
||||
Iterator listenerIter = getProject().getBuildListeners().iterator();
|
||||
while (listenerIter.hasNext()) {
|
||||
newProject.addBuildListener((BuildListener) listenerIter.next());
|
||||
}
|
||||
|
||||
getProject().initSubProject(newProject);
|
||||
|
||||
setProject(newProject);
|
||||
}
|
||||
|
||||
/**
|
||||
Set Module-Related information to properties.
|
||||
|
||||
@param arch current build ARCH
|
||||
**/
|
||||
private void setModuleCommonProperties(String arch) {
|
||||
//
|
||||
// Prepare for all other common properties
|
||||
// PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
|
||||
//
|
||||
PackageIdentification packageId = moduleId.getPackage();
|
||||
getProject().setProperty("PACKAGE", packageId.getName());
|
||||
getProject().setProperty("PACKAGE_GUID", packageId.getGuid());
|
||||
getProject().setProperty("PACKAGE_VERSION", packageId.getVersion());
|
||||
getProject().setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/"));
|
||||
getProject().setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/"));
|
||||
|
||||
//
|
||||
// MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE
|
||||
// MODULE_DIR, MODULE_RELATIVE_DIR
|
||||
//
|
||||
getProject().setProperty("MODULE", moduleId.getName());
|
||||
String baseName = saq.getModuleOutputFileBasename();
|
||||
if (baseName == null) {
|
||||
getProject().setProperty("BASE_NAME", moduleId.getName());
|
||||
} else {
|
||||
getProject().setProperty("BASE_NAME", baseName);
|
||||
}
|
||||
getProject().setProperty("GUID", moduleId.getGuid());
|
||||
getProject().setProperty("FILE_GUID", moduleId.getGuid());
|
||||
getProject().setProperty("VERSION", moduleId.getVersion());
|
||||
getProject().setProperty("MODULE_TYPE", moduleId.getModuleType());
|
||||
getProject().setProperty("MODULE_DIR", moduleId.getMsaFile().getParent().replaceAll("(\\\\)", "/"));
|
||||
getProject().setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/"));
|
||||
|
||||
//
|
||||
// SUBSYSTEM
|
||||
//
|
||||
String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},
|
||||
{ "SEC", "EFI_BOOT_SERVICE_DRIVER" },
|
||||
{ "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" },
|
||||
{ "PEIM", "EFI_BOOT_SERVICE_DRIVER" },
|
||||
{ "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },
|
||||
{ "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
|
||||
{ "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" },
|
||||
{ "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
|
||||
{ "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
|
||||
{ "TOOL", "EFI_BOOT_SERVICE_DRIVER" },
|
||||
{ "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
|
||||
{ "UEFI_APPLICATION", "EFI_APPLICATION" },
|
||||
{ "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} };
|
||||
|
||||
String subsystem = "EFI_BOOT_SERVICE_DRIVER";
|
||||
for (int i = 0; i < subsystemMap.length; i++) {
|
||||
if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) {
|
||||
subsystem = subsystemMap[i][1];
|
||||
break ;
|
||||
}
|
||||
}
|
||||
getProject().setProperty("SUBSYSTEM", subsystem);
|
||||
|
||||
//
|
||||
// ENTRYPOINT
|
||||
//
|
||||
if (arch.equalsIgnoreCase("EBC")) {
|
||||
getProject().setProperty("ENTRYPOINT", "EfiStart");
|
||||
} else {
|
||||
getProject().setProperty("ENTRYPOINT", "_ModuleEntryPoint");
|
||||
}
|
||||
|
||||
getProject().setProperty("OBJECTS", "");
|
||||
}
|
||||
|
||||
private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException {
|
||||
String[] cmd = GlobalData.getToolChainInfo().getCommands();
|
||||
for ( int m = 0; m < cmd.length; m++) {
|
||||
//
|
||||
// Set cmd, like CC, DLINK
|
||||
//
|
||||
String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};
|
||||
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_PATH;
|
||||
String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);
|
||||
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME;
|
||||
String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);
|
||||
File cmdFile = new File(cmdPath + File.separatorChar + cmdName);
|
||||
getProject().setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));
|
||||
|
||||
//
|
||||
// set CC_FLAGS
|
||||
//
|
||||
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS;
|
||||
String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);
|
||||
if (cmdFlags != null)
|
||||
{
|
||||
// Set<String> addset = new LinkedHashSet<String>();
|
||||
// Set<String> subset = new LinkedHashSet<String>();
|
||||
// putFlagsToSet(addset, cmdFlags);
|
||||
// getProject().setProperty(cmd[m] + "_FLAGS", getProject().replaceProperties(getFlags(addset, subset)));
|
||||
getProject().setProperty(cmd[m] + "_FLAGS", cmdFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
getProject().setProperty(cmd[m] + "_FLAGS", "");
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Set CC_EXT
|
||||
//
|
||||
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_EXT;
|
||||
String extName = GlobalData.getCommandSetting(key, fpdModuleId);
|
||||
if ( extName != null && ! extName.equalsIgnoreCase("")) {
|
||||
getProject().setProperty(cmd[m] + "_EXT", extName);
|
||||
} else {
|
||||
getProject().setProperty(cmd[m] + "_EXT", "");
|
||||
}
|
||||
|
||||
//
|
||||
// set CC_FAMILY
|
||||
//
|
||||
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY;
|
||||
String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);
|
||||
if (toolChainFamily != null) {
|
||||
getProject().setProperty(cmd[m] + "_FAMILY", toolChainFamily);
|
||||
}
|
||||
|
||||
//
|
||||
// set CC_SPATH
|
||||
//
|
||||
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_SPATH;
|
||||
String spath = GlobalData.getCommandSetting(key, fpdModuleId);
|
||||
if (spath != null) {
|
||||
getProject().setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));
|
||||
} else {
|
||||
getProject().setProperty(cmd[m] + "_SPATH", "");
|
||||
}
|
||||
|
||||
//
|
||||
// set CC_DPATH
|
||||
//
|
||||
key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_DPATH;
|
||||
String dpath = GlobalData.getCommandSetting(key, fpdModuleId);
|
||||
if (dpath != null) {
|
||||
getProject().setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));
|
||||
} else {
|
||||
getProject().setProperty(cmd[m] + "_DPATH", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setMsaFile(File msaFile) {
|
||||
this.msaFile = msaFile;
|
||||
}
|
||||
|
||||
/**
|
||||
Method is for ANT to initialize MSA file.
|
||||
|
||||
@param msaFilename MSA file name
|
||||
**/
|
||||
public void setMsaFile(String msaFilename) {
|
||||
String moduleDir = getProject().getProperty("MODULE_DIR");
|
||||
|
||||
//
|
||||
// If is Single Module Build, then use the Base Dir defined in build.xml
|
||||
//
|
||||
if (moduleDir == null) {
|
||||
moduleDir = getProject().getBaseDir().getPath();
|
||||
}
|
||||
msaFile = new File(moduleDir + File.separatorChar + msaFilename);
|
||||
}
|
||||
|
||||
public void addConfiguredModuleItem(ModuleItem moduleItem) {
|
||||
PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion());
|
||||
ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion());
|
||||
moduleId.setPackage(packageId);
|
||||
this.moduleId = moduleId;
|
||||
}
|
||||
|
||||
/**
|
||||
Add a property.
|
||||
|
||||
@param p property
|
||||
**/
|
||||
public void addProperty(Property p) {
|
||||
properties.addElement(p);
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws EdkException {
|
||||
//
|
||||
// Call AutoGen to generate AutoGen.c and AutoGen.h
|
||||
//
|
||||
AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch(), saq, parentId);
|
||||
autogen.genAutogen();
|
||||
|
||||
//
|
||||
// Get compiler flags
|
||||
//
|
||||
try {
|
||||
getCompilerFlags(buildTarget, buildTagname, fpdModuleId);
|
||||
}
|
||||
catch (EdkException ee) {
|
||||
throw new BuildException(ee.getMessage());
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare LIBS
|
||||
//
|
||||
ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());
|
||||
String propertyLibs = "";
|
||||
for (int i = 0; i < libinstances.length; i++) {
|
||||
propertyLibs += getProject().getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib" + " ";
|
||||
}
|
||||
getProject().setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));
|
||||
|
||||
//
|
||||
// Get all includepath and set to INCLUDE_PATHS
|
||||
//
|
||||
String[] includes = prepareIncludePaths(fpdModuleId);
|
||||
|
||||
//
|
||||
// if it is CUSTOM_BUILD
|
||||
// then call the exist BaseName_build.xml directly.
|
||||
//
|
||||
if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
|
||||
EdkLog.log(this, "Call user-defined " + moduleId.getName() + "_build.xml");
|
||||
|
||||
String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";
|
||||
antCall(antFilename, null);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate ${BASE_NAME}_build.xml
|
||||
// TBD
|
||||
//
|
||||
String ffsKeyword = saq.getModuleFfsKeyword();
|
||||
ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId, includes, saq);
|
||||
String buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
|
||||
fileGenerator.genBuildFile(buildFilename);
|
||||
|
||||
//
|
||||
// Ant call ${BASE_NAME}_build.xml
|
||||
//
|
||||
String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
|
||||
antCall(antFilename, null);
|
||||
}
|
||||
|
||||
private void applyClean(FpdModuleIdentification fpdModuleId){
|
||||
//
|
||||
// if it is CUSTOM_BUILD
|
||||
// then call the exist BaseName_build.xml directly.
|
||||
//
|
||||
if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
|
||||
EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");
|
||||
|
||||
String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";
|
||||
antCall(antFilename, "clean");
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
|
||||
antCall(antFilename, "clean");
|
||||
}
|
||||
|
||||
private void applyCleanall(FpdModuleIdentification fpdModuleId){
|
||||
//
|
||||
// if it is CUSTOM_BUILD
|
||||
// then call the exist BaseName_build.xml directly.
|
||||
//
|
||||
if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
|
||||
EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");
|
||||
|
||||
String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";
|
||||
antCall(antFilename, "cleanall");
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
|
||||
antCall(antFilename, "cleanall");
|
||||
}
|
||||
|
||||
private void antCall(String antFilename, String target) {
|
||||
Ant ant = new Ant();
|
||||
ant.setProject(getProject());
|
||||
ant.setAntfile(antFilename);
|
||||
if (target != null) {
|
||||
ant.setTarget(target);
|
||||
}
|
||||
ant.setInheritAll(true);
|
||||
ant.init();
|
||||
ant.execute();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Separate the string and instore in set.
|
||||
|
||||
<p> String is separated by Java Regulation Expression
|
||||
"[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
|
||||
|
||||
<p>For example: </p>
|
||||
|
||||
<pre>
|
||||
"/nologo", "/W3", "/WX"
|
||||
"/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
|
||||
</pre>
|
||||
|
||||
@param set store the separated string
|
||||
@param str string to separate
|
||||
**/
|
||||
private void putFlagsToSet(Set<String> set, String str) {
|
||||
if (str == null || str.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
|
||||
Matcher matcher = myPattern.matcher(str + " ");
|
||||
while (matcher.find()) {
|
||||
String item = str.substring(matcher.start(1), matcher.end(1));
|
||||
set.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Generate the final flags string will be used by compile command.
|
||||
|
||||
@param add the add flags set
|
||||
@param sub the sub flags set
|
||||
@return final flags after add set substract sub set
|
||||
**/
|
||||
private String getFlags(Set<String> add, Set<String> sub) {
|
||||
String result = "";
|
||||
add.removeAll(sub);
|
||||
Iterator iter = add.iterator();
|
||||
while (iter.hasNext()) {
|
||||
String str = (String) iter.next();
|
||||
result += str.substring(1, str.length() - 1) + " ";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setSingleModuleBuild(boolean isSingleModuleBuild) {
|
||||
this.isSingleModuleBuild = isSingleModuleBuild;
|
||||
}
|
||||
|
||||
private String[] prepareIncludePaths(FpdModuleIdentification fpdModuleId) throws EdkException{
|
||||
//
|
||||
// Prepare the includes: PackageDependencies and Output debug direactory
|
||||
//
|
||||
Set<String> includes = new LinkedHashSet<String>();
|
||||
String arch = fpdModuleId.getArch();
|
||||
|
||||
//
|
||||
// WORKSPACE
|
||||
//
|
||||
includes.add("${WORKSPACE_DIR}" + File.separatorChar);
|
||||
|
||||
//
|
||||
// Module iteself
|
||||
//
|
||||
includes.add("${MODULE_DIR}");
|
||||
includes.add("${MODULE_DIR}" + File.separatorChar + archDir(arch));
|
||||
|
||||
//
|
||||
// Packages in PackageDenpendencies
|
||||
//
|
||||
PackageIdentification[] packageDependencies = saq.getDependencePkg(fpdModuleId.getArch());
|
||||
for (int i = 0; i < packageDependencies.length; i++) {
|
||||
GlobalData.refreshPackageIdentification(packageDependencies[i]);
|
||||
File packageFile = packageDependencies[i].getSpdFile();
|
||||
includes.add(packageFile.getParent() + File.separatorChar + "Include");
|
||||
includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));
|
||||
}
|
||||
|
||||
//
|
||||
// All Dependency Library Instance's PackageDependencies
|
||||
//
|
||||
ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());
|
||||
for (int i = 0; i < libinstances.length; i++) {
|
||||
saq.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch()));
|
||||
PackageIdentification[] libraryPackageDependencies = saq.getDependencePkg(fpdModuleId.getArch());
|
||||
for (int j = 0; j < libraryPackageDependencies.length; j++) {
|
||||
GlobalData.refreshPackageIdentification(libraryPackageDependencies[j]);
|
||||
File packageFile = libraryPackageDependencies[j].getSpdFile();
|
||||
includes.add(packageFile.getParent() + File.separatorChar + "Include");
|
||||
includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));
|
||||
}
|
||||
saq.pop();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// The package which the module belongs to
|
||||
// TBD
|
||||
includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include");
|
||||
includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));
|
||||
|
||||
//
|
||||
// Debug files output directory
|
||||
//
|
||||
includes.add("${DEST_DIR_DEBUG}");
|
||||
|
||||
//
|
||||
// set to INCLUDE_PATHS property
|
||||
//
|
||||
Iterator<String> iter = includes.iterator();
|
||||
StringBuffer includePaths = new StringBuffer();
|
||||
while (iter.hasNext()) {
|
||||
includePaths.append(iter.next());
|
||||
includePaths.append("; ");
|
||||
}
|
||||
getProject().setProperty("INCLUDE_PATHS", getProject().replaceProperties(includePaths.toString()).replaceAll("(\\\\)", "/"));
|
||||
|
||||
return includes.toArray(new String[includes.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
Return the name of the directory that corresponds to the architecture.
|
||||
This is a translation from the XML Schema tag to a directory that
|
||||
corresponds to our directory name coding convention.
|
||||
|
||||
**/
|
||||
private String archDir(String arch) {
|
||||
return arch.replaceFirst("X64", "x64")
|
||||
.replaceFirst("IPF", "Ipf")
|
||||
.replaceFirst("IA32", "Ia32")
|
||||
.replaceFirst("ARM", "Arm")
|
||||
.replaceFirst("EBC", "Ebc");
|
||||
}
|
||||
|
||||
|
||||
public void setExternalProperties(Vector<Property> v) {
|
||||
this.properties = v;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
2188
Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
Normal file
2188
Tools/Java/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
279
Tools/Java/Source/GenBuild/org/tianocore/build/global/Spd.java
Normal file
279
Tools/Java/Source/GenBuild/org/tianocore/build/global/Spd.java
Normal 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
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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("*");
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user