WorkspaceDatabase.py revision 4fd606d1f5abe38e1f42c38de1d2e895166bd0f4
## @file
# This file is used to create a database used by build tool
#
# Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
# 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
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
# Import Modules
#
import sqlite3
import os
import pickle
import uuid
from types import *
from MetaDataTable import *
from MetaFileTable import *
from MetaFileParser import *
from BuildClassObject import *
## Platform build information from DSC file
#
# This class is used to retrieve information stored in database and convert them
# into PlatformBuildClassObject form for easier use for AutoGen.
#
class DscBuildData(PlatformBuildClassObject):
# dict used to convert PCD type in database to string used by build tool
MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
MODEL_PCD_DYNAMIC : "Dynamic",
MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
MODEL_PCD_DYNAMIC_HII : "DynamicHii",
MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
MODEL_PCD_DYNAMIC_EX : "DynamicEx",
MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
}
# dict used to convert part of [Defines] to members of DscBuildData directly
_PROPERTY_ = {
#
# Required Fields
#
TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",
TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",
TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",
TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",
#TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
#TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
#TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
#TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
#TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",
TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",
TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",
TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",
#TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
#TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
}
# used to compose dummy library class name for those forced library instances
## Constructor of DscBuildData
#
# Initialize object of DscBuildData
#
# @param FilePath The path of platform description file
# @param RawData The raw data of DSC file
# @param Arch The target architecture
# @param Platform (not used for DscBuildData)
# @param Macros Macros used for replacement in DSC file
#
## XXX[key] = value
## value = XXX[key]
## "in" test support
## Set all internal used members of DscBuildData to None
self._PlatformName = None
self._DscSpecification = None
self._OutputDirectory = None
self._SupArchList = None
self._BuildTargets = None
self._FlashDefinition = None
self._BuildNumber = None
self._MakefileName = None
self._BsBaseAddress = None
self._RtBaseAddress = None
self._LibraryInstances = None
self._LibraryClasses = None
self._BuildOptions = None
self._LoadFixAddress = None
self._RFCLanguages = None
self._ISOLanguages = None
self._VpdToolGuid = None
## Get current effective macros
def _GetMacros(self):
## Get architecture
## Set architecture
#
# Changing the default ARCH to another may affect all other information
# because all information in a platform may be ARCH-related. That's
# why we need to clear all internal used members, in order to cause all
# information to be re-retrieved.
#
# @param Value The value of ARCH
#
return
## Retrieve all information in [Defines] section
#
# (Retriving all [Defines] information in one-shot is just to save time.)
#
def _GetHeaderInfo(self):
for Record in RecordList:
# items defined _PROPERTY_ don't need additional processing
# some special items in [Defines] section need special treatment
elif Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:
if ErrorCode != 0:
elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
try:
except:
EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))
elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:
EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
if not LanguageCodes:
EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
# check whether there is empty entries in the list
if None in LanguageList:
EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',
elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:
EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
if not LanguageCodes:
EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
LanguageList = []
elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:
#
# try to convert GUID to a real UUID value to see whether the GUID is format
# for VPD_TOOL_GUID is correct.
#
try:
except:
EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
# set _Header to non-None in order to avoid database re-querying
## Retrieve platform name
def _GetPlatformName(self):
if self._PlatformName == None:
if self._PlatformName == None:
return self._PlatformName
## Retrieve file guid
def _GetFileGuid(self):
## Retrieve platform version
def _GetVersion(self):
## Retrieve platform description file version
def _GetDscSpec(self):
if self._DscSpecification == None:
if self._DscSpecification == None:
return self._DscSpecification
## Retrieve OUTPUT_DIRECTORY
def _GetOutpuDir(self):
if self._OutputDirectory == None:
if self._OutputDirectory == None:
return self._OutputDirectory
## Retrieve SUPPORTED_ARCHITECTURES
def _GetSupArch(self):
if self._SupArchList == None:
if self._SupArchList == None:
return self._SupArchList
## Retrieve BUILD_TARGETS
def _GetBuildTarget(self):
if self._BuildTargets == None:
if self._BuildTargets == None:
return self._BuildTargets
## Retrieve SKUID_IDENTIFIER
def _GetSkuName(self):
## Override SKUID_IDENTIFIER
# Needs to re-retrieve the PCD information
def _GetFdfFile(self):
if self._FlashDefinition == None:
if self._FlashDefinition == None:
return self._FlashDefinition
## Retrieve FLASH_DEFINITION
def _GetBuildNumber(self):
if self._BuildNumber == None:
if self._BuildNumber == None:
return self._BuildNumber
## Retrieve MAKEFILE_NAME
def _GetMakefileName(self):
if self._MakefileName == None:
if self._MakefileName == None:
return self._MakefileName
## Retrieve BsBaseAddress
def _GetBsBaseAddress(self):
if self._BsBaseAddress == None:
if self._BsBaseAddress == None:
return self._BsBaseAddress
## Retrieve RtBaseAddress
def _GetRtBaseAddress(self):
if self._RtBaseAddress == None:
if self._RtBaseAddress == None:
return self._RtBaseAddress
## Retrieve the top address for the load fix address
def _GetLoadFixAddress(self):
if self._LoadFixAddress == None:
if self._LoadFixAddress == None:
try:
except:
EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))
#
# If command line defined, should override the value in DSC file.
#
try:
except:
EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))
EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))
EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))
return self._LoadFixAddress
## Retrieve RFCLanguage filter
def _GetRFCLanguages(self):
if self._RFCLanguages == None:
if self._RFCLanguages == None:
self._RFCLanguages = []
return self._RFCLanguages
## Retrieve ISOLanguage filter
def _GetISOLanguages(self):
if self._ISOLanguages == None:
if self._ISOLanguages == None:
self._ISOLanguages = []
return self._ISOLanguages
## Retrieve the GUID string for VPD tool
def _GetVpdToolGuid(self):
if self._VpdToolGuid == None:
if self._VpdToolGuid == None:
return self._VpdToolGuid
## Retrieve [SkuIds] section information
def _GetSkuIds(self):
for Record in RecordList:
## Retrieve [Components] section information
def _GetModules(self):
for Record in RecordList:
# check the file validation
if ErrorCode != 0:
# Check duplication
# If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
# get module override path
RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]
if RecordList != []:
# Check if the source override path exists
EdkLogger.error('build', FILE_NOT_FOUND, Message = 'Source override path does not exist:', File=self.MetaFile, ExtraData=Module.SourceOverridePath, Line=LineNo)
#Add to GlobalData Variables
# get module private library instance
for Record in RecordList:
# check the file validation
if ErrorCode != 0:
EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
# get module private PCD setting
else:
MaxDatumSize = ''
'',
'',
{},
None
)
# get module private build options
else:
## Retrieve all possible library instances used in this platform
def _GetLibraryInstances(self):
if self._LibraryInstances == None:
return self._LibraryInstances
## Retrieve [LibraryClasses] information
def _GetLibraryClasses(self):
if self._LibraryClasses == None:
self._LibraryInstances = []
#
# tdict is a special dict kind of type, used for selecting correct
# library instance for given library class and module type
#
# track all library class names
LibraryClassSet = set()
for Record in RecordList:
EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))
LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)
# check the file validation
if ErrorCode != 0:
# resolve the specific library instance for each class and each module type
for LibraryClass in LibraryClassSet:
# try all possible module types
for ModuleType in SUP_MODULE_LIST:
if LibraryInstance == None:
continue
# for Edk style library instances, which are listed in different section
for Record in RecordList:
# check the file validation
if ErrorCode != 0:
#
# we need the module name as the library class name, so we have
# to parse it here. (self._Bdb[] will trigger a file parse if it
# hasn't been parsed)
#
return self._LibraryClasses
## Retrieve all PCD settings in platform
## Retrieve [BuildOptions]
def _GetBuildOptions(self):
if self._BuildOptions == None:
#
# Retrieve build option for EDKII style module
#
#
# Retrieve build option for EDK style module
#
return self._BuildOptions
## Retrieve non-dynamic PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH
#
# Find out all possible PCD candidates for self._Arch
# Remove redundant PCD candidates
if Setting == None:
continue
'',
{},
None
)
return Pcds
## Retrieve dynamic PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
#
PcdList = []
# Find out all possible PCD candidates for self._Arch
# Remove redundant PCD candidates, per the ARCH and SKU
if Setting == None:
continue
'',
None
)
return Pcds
## Retrieve dynamic HII PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
#
# Find out all possible PCD candidates for self._Arch
# Remove redundant PCD candidates, per the ARCH and SKU
if Setting == None:
continue
SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)
'',
'',
'',
None
)
return Pcds
## Retrieve dynamic VPD PCD settings
#
# @param Type PCD type
#
# @retval a dict object contains settings of given PCD type
#
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
#
PcdList = []
# Find out all possible PCD candidates for self._Arch
# Remove redundant PCD candidates, per the ARCH and SKU
if Setting == None:
continue
#
# For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
# For the Integer & Boolean type, the optional data can only be InitialValue.
# At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
# until the DEC parser has been called.
#
SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset, InitialValue)
'',
'',
'',
None
)
return Pcds
## Add external modules
#
# The external modules are mostly those listed in FDF file, which don't
# need "build".
#
# @param FilePath The path of module description file
#
## Add external PCDs
#
# The external PCDs are mostly those listed in FDF file to specify address
# or offset information.
#
# @param Name Name of the PCD
# @param Guid Token space guid of the PCD
# @param Value Value of the PCD
#
PcdValue = ''
else:
else:
if PcdValue:
if not Valid:
## Platform build information from DEC file
#
# This class is used to retrieve information stored in database and convert them
# into PackageBuildClassObject form for easier use for AutoGen.
#
class DecBuildData(PackageBuildClassObject):
# dict used to convert PCD type in database to string used by build tool
MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
MODEL_PCD_DYNAMIC : "Dynamic",
MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
MODEL_PCD_DYNAMIC_HII : "DynamicHii",
MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
MODEL_PCD_DYNAMIC_EX : "DynamicEx",
MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
}
# dict used to convert part of [Defines] to members of DecBuildData directly
_PROPERTY_ = {
#
# Required Fields
#
TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName",
TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid",
TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version",
TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile",
}
## Constructor of DecBuildData
#
# Initialize object of DecBuildData
#
# @param FilePath The path of package description file
# @param RawData The raw data of DEC file
# @param BuildDataBase Database used to retrieve module information
# @param Arch The target architecture
# @param Platform (not used for DecBuildData)
# @param Macros Macros used for replacement in DSC file
#
## XXX[key] = value
## value = XXX[key]
## "in" test support
## Set all internal used members of DecBuildData to None
self._PackageName = None
self._PkgUniFile = None
self._Protocols = None
self._LibraryClasses = None
## Get current effective macros
def _GetMacros(self):
## Get architecture
## Set architecture
#
# Changing the default ARCH to another may affect all other information
# because all information in a platform may be ARCH-related. That's
# why we need to clear all internal used members, in order to cause all
# information to be re-retrieved.
#
# @param Value The value of ARCH
#
return
## Retrieve all information in [Defines] section
#
# (Retriving all [Defines] information in one-shot is just to save time.)
#
def _GetHeaderInfo(self):
for Record in RecordList:
## Retrieve package name
def _GetPackageName(self):
if self._PackageName == None:
if self._PackageName == None:
return self._PackageName
## Retrieve file guid
def _GetFileGuid(self):
## Retrieve package version
def _GetVersion(self):
def _GetProtocol(self):
if self._Protocols == None:
#
# tdict is a special kind of dict, used for selecting correct
# protocol defition for given ARCH
#
NameList = []
# find out all protocol definitions for specific and 'common' arch
# use sdict to keep the order
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH for trying
#
return self._Protocols
#
# tdict is a special kind of dict, used for selecting correct
# PPI defition for given ARCH
#
NameList = []
# find out all PPI definitions for specific arch and 'common' arch
# use sdict to keep the order
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH for trying
#
#
# tdict is a special kind of dict, used for selecting correct
# GUID defition for given ARCH
#
NameList = []
# find out all protocol definitions for specific and 'common' arch
# use sdict to keep the order
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH for trying
#
## Retrieve public include paths declared in this package
def _GetInclude(self):
for Record in RecordList:
# validate the path
if ErrorCode != 0:
# avoid duplicate include path
## Retrieve library class declarations (not used in build at present)
def _GetLibraryClass(self):
if self._LibraryClasses == None:
#
# tdict is a special kind of dict, used for selecting correct
# library class declaration for given ARCH
#
LibraryClassSet = set()
# check the file validation
if ErrorCode != 0:
for LibraryClass in LibraryClassSet:
return self._LibraryClasses
## Retrieve PCD declarations
## Retrieve PCD declarations for given type
#
# tdict is a special kind of dict, used for selecting correct
# PCD declaration for given ARCH
#
# for summarizing PCD
# find out all PCDs of the 'type'
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH and try again
#
if Setting == None:
continue
'',
{},
None
)
return Pcds
## Module build information from INF file
#
# This class is used to retrieve information stored in database and convert them
# into ModuleBuildClassObject form for easier use for AutoGen.
#
class InfBuildData(ModuleBuildClassObject):
# dict used to convert PCD type in database to string used by build tool
MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
MODEL_PCD_DYNAMIC : "Dynamic",
MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
MODEL_PCD_DYNAMIC_HII : "DynamicHii",
MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
MODEL_PCD_DYNAMIC_EX : "DynamicEx",
MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
}
# dict used to convert part of [Defines] to members of InfBuildData directly
_PROPERTY_ = {
#
# Required Fields
#
TAB_INF_DEFINES_BASE_NAME : "_BaseName",
TAB_INF_DEFINES_FILE_GUID : "_Guid",
TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",
#
# Optional Fields
#
#TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",
TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",
#TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",
TAB_INF_DEFINES_VERSION_NUMBER : "_Version",
TAB_INF_DEFINES_VERSION_STRING : "_Version",
TAB_INF_DEFINES_VERSION : "_Version",
TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",
TAB_INF_DEFINES_SHADOW : "_Shadow",
TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath",
}
# dict used to convert Component type to Module type
_MODULE_TYPE_ = {
"LIBRARY" : "BASE",
"SECURITY_CORE" : "SEC",
"PEI_CORE" : "PEI_CORE",
"COMBINED_PEIM_DRIVER" : "PEIM",
"PIC_PEIM" : "PEIM",
"RELOCATABLE_PEIM" : "PEIM",
"PE32_PEIM" : "PEIM",
"BS_DRIVER" : "DXE_DRIVER",
"RT_DRIVER" : "DXE_RUNTIME_DRIVER",
"SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
"DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
# "SMM_DRIVER" : "DXE_SMM_DRIVER",
# "BS_DRIVER" : "DXE_SMM_DRIVER",
# "BS_DRIVER" : "UEFI_DRIVER",
"APPLICATION" : "UEFI_APPLICATION",
"LOGO" : "BASE",
}
# regular expression for converting XXX_FLAGS in [nmake] section to new type
_NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)
# dict used to convert old tool name used in [nmake] section to new ones
_TOOL_CODE_ = {
"C" : "CC",
"LIB" : "SLINK",
"LINK" : "DLINK",
}
## Constructor of DscBuildData
#
# Initialize object of DscBuildData
#
# @param FilePath The path of platform description file
# @param RawData The raw data of DSC file
# @param Arch The target architecture
# @param Platform The name of platform employing this module
# @param Macros Macros used for replacement in DSC file
#
self._SourceOverridePath = None
## XXX[key] = value
## value = XXX[key]
## "in" test support
## Set all internal used members of InfBuildData to None
self._AutoGenVersion = None
self._ModuleType = None
self._ComponentType = None
self._BuildType = None
self._PcdIsDriver = None
self._BinaryModule = None
self._MakefileName = None
self._CustomMakefile = None
self._Specification = None
self._LibraryClass = None
self._ModuleEntryPointList = None
self._ModuleUnloadImageList = None
self._ConstructorList = None
self._DestructorList = None
self._LibraryClasses = None
self._Libraries = None
self._Protocols = None
self._BuildOptions = None
self._DepexExpression = None
## Get current effective macros
def _GetMacros(self):
# EDK_GLOBAL defined macros can be applied to EDK module
# VBox hack begin - Required for referencing files outside the workspace, like the reset vectors and logo.
# VBox hack end.
## Get architecture
## Set architecture
#
# Changing the default ARCH to another may affect all other information
# because all information in a platform may be ARCH-related. That's
# why we need to clear all internal used members, in order to cause all
# information to be re-retrieved.
#
# @param Value The value of ARCH
#
return
## Return the name of platform employing this module
def _GetPlatform(self):
## Change the name of platform employing this module
#
# Changing the default name of platform to another may affect some information
# because they may be PLATFORM-related. That's why we need to clear all internal
# used members, in order to cause all information to be re-retrieved.
#
return
## Retrieve all information in [Defines] section
#
# (Retriving all [Defines] information in one-shot is just to save time.)
#
def _GetHeaderInfo(self):
for Record in RecordList:
# items defined _PROPERTY_ don't need additional processing
# some special items in [Defines] section need special treatment
elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
Name = 'UEFI_SPECIFICATION_VERSION'
if self._Specification == None:
elif Name == 'LIBRARY_CLASS':
if self._LibraryClass == None:
self._LibraryClass = []
else:
elif Name == 'ENTRY_POINT':
if self._ModuleEntryPointList == None:
elif Name == 'UNLOAD_IMAGE':
if self._ModuleUnloadImageList == None:
if not Value:
continue
elif Name == 'CONSTRUCTOR':
if self._ConstructorList == None:
self._ConstructorList = []
if not Value:
continue
elif Name == 'DESTRUCTOR':
if self._DestructorList == None:
self._DestructorList = []
if not Value:
continue
elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:
if self._CustomMakefile == None:
self._CustomMakefile = {}
else:
else:
#
# Retrieve information in sections specific to Edk.x modules
#
if not self._ModuleType:
for Record in RecordList:
if Name == "MODULE_TYPE":
break
"MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType,' '.join(l for l in SUP_MODULE_LIST)),
if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)
else:
# check the file validation
if ErrorCode != 0:
else:
if not self._ComponentType:
# make use some [nmake] section macros
if Name == "IMAGE_ENTRY_POINT":
if self._ModuleEntryPointList == None:
elif Name == "DPX_SOURCE":
# check the file validation
if ErrorCode != 0:
else:
pass
# EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
# File=self.MetaFile, Line=LineNo)
else:
if self._BuildOptions == None:
else:
#ignore not replaced macros in value
continue
else:
# set _Header to non-None in order to avoid database re-querying
## Retrieve file version
def _GetInfVersion(self):
if self._AutoGenVersion == None:
for Record in RecordList:
break
if self._AutoGenVersion == None:
return self._AutoGenVersion
## Retrieve BASE_NAME
def _GetBaseName(self):
## Retrieve DxsFile
def _GetDxsFile(self):
## Retrieve MODULE_TYPE
def _GetModuleType(self):
if self._ModuleType == None:
if self._ModuleType == None:
return self._ModuleType
## Retrieve COMPONENT_TYPE
def _GetComponentType(self):
if self._ComponentType == None:
if self._ComponentType == None:
return self._ComponentType
## Retrieve "BUILD_TYPE"
def _GetBuildType(self):
if self._BuildType == None:
if not self._BuildType:
return self._BuildType
## Retrieve file guid
def _GetFileGuid(self):
## Retrieve module version
def _GetVersion(self):
## Retrieve PCD_IS_DRIVER
def _GetPcdIsDriver(self):
if self._PcdIsDriver == None:
if self._PcdIsDriver == None:
return self._PcdIsDriver
## Retrieve SHADOW
def _GetShadow(self):
else:
## Retrieve CUSTOM_MAKEFILE
def _GetMakefile(self):
if self._CustomMakefile == None:
if self._CustomMakefile == None:
self._CustomMakefile = {}
return self._CustomMakefile
## Retrieve EFI_SPECIFICATION_VERSION
if self._Specification == None:
if self._Specification == None:
self._Specification = {}
return self._Specification
## Retrieve LIBRARY_CLASS
def _GetLibraryClass(self):
if self._LibraryClass == None:
if self._LibraryClass == None:
self._LibraryClass = []
return self._LibraryClass
## Retrieve ENTRY_POINT
def _GetEntryPoint(self):
if self._ModuleEntryPointList == None:
if self._ModuleEntryPointList == None:
return self._ModuleEntryPointList
## Retrieve UNLOAD_IMAGE
def _GetUnloadImage(self):
if self._ModuleUnloadImageList == None:
if self._ModuleUnloadImageList == None:
return self._ModuleUnloadImageList
## Retrieve CONSTRUCTOR
def _GetConstructor(self):
if self._ConstructorList == None:
if self._ConstructorList == None:
self._ConstructorList = []
return self._ConstructorList
## Retrieve DESTRUCTOR
def _GetDestructor(self):
if self._DestructorList == None:
if self._DestructorList == None:
self._DestructorList = []
return self._DestructorList
## Retrieve definies other than above ones
def _GetDefines(self):
## Retrieve binary files
def _GetBinaryFiles(self):
for Record in RecordList:
Target = 'COMMON'
FeatureFlag = []
if Record[2]:
if TokenList:
File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)
# check the file validation
if ErrorCode != 0:
## Retrieve source files
def _GetSourceFiles(self):
for Record in RecordList:
# old module source files (Edk)
# check the file validation
if ErrorCode != 0:
continue
else:
else:
# check the file validation
if ErrorCode != 0:
## Retrieve library classes employed by this module
def _GetLibraryClassUses(self):
if self._LibraryClasses == None:
for Record in RecordList:
if Instance:
return self._LibraryClasses
## Retrieve library names (for Edk.x style of modules)
def _GetLibraryNames(self):
if self._Libraries == None:
self._Libraries = []
for Record in RecordList:
# in case of name with '.lib' extension, which is unusual in Edk.x inf
return self._Libraries
def _GetProtocols(self):
if self._Protocols == None:
for Record in RecordList:
if Value == None:
"Value of Protocol [%s] is not found under [Protocols] section in" % CName,
return self._Protocols
for Record in RecordList:
if Value == None:
"Value of PPI [%s] is not found under [Ppis] section in " % CName,
for Record in RecordList:
if Value == None:
"Value of Guid [%s] is not found under [Guids] section in" % CName,
## Retrieve include paths necessary for this module (for Edk.x style of modules)
def _GetIncludes(self):
else:
for Record in RecordList:
else:
if File:
#TRICK: let compiler to choose correct header file
else:
if File:
else:
else:
if File:
## Retrieve packages this module depends on
def _GetPackages(self):
for Record in RecordList:
# check the file validation
if ErrorCode != 0:
## Retrieve PCDs used in this module
## Retrieve build options specific to this module
def _GetBuildOptions(self):
if self._BuildOptions == None:
for Record in RecordList:
else:
# concatenate the option string if they're for the same tool
return self._BuildOptions
## Retrieve dependency expression
# If the module has only Binaries and no Sources, then ignore [Depex]
# PEIM and DXE drivers must have a valid [Depex] section
if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
for Record in RecordList:
if Token in DEPEX_SUPPORTED_OPCODE:
if Module == None:
else:
# get the GUID value now
if Value == None:
if Value == None:
if Value == None:
"Value of [%s] is not found in" % Token,
## Retrieve depedency expression
def _GetDepexExpression(self):
if self._DepexExpression == None:
DepexExpression = sdict()
for Record in RecordList:
return self._DepexExpression
## Retrieve PCD for given type
PcdList = []
# get the guid value
if Value == None:
"Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,
# resolve PCD type, value, datum info, etc. by getting its definition from package
if Setting == None:
continue
'',
'',
'',
'',
{},
)
# get necessary info from package declaring this PCD
#
# 'dynamic' in INF means its type is determined by platform;
# if platform doesn't give its type, use 'lowest' one in the
# following order, if any
#
# "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
#
if Type == MODEL_PCD_DYNAMIC:
for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
PcdType = T
break
else:
#
# Check whether the token value exist or not.
#
'build',
ExtraData=None
)
#
# Check hexadecimal token value length and format.
#
'build',
"The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),
ExtraData=None
)
#
# Check decimal token value length and format.
#
else:
try:
'build',
"The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!"% (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),
ExtraData=None
)
except:
'build',
"The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!"% (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),
ExtraData=None
)
break
else:
'build',
"PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),
)
return Pcds
## Database
#
# This class defined the build database for all modules, packages and platform.
# It will call corresponding parser for the given file if it cannot find it in
# the database.
#
# @param DbPath Path of database file
# @param GlobalMacros Global macros used for replacement during file parsing
# @prarm RenewDb=False Create new database file if it's already there
#
class WorkspaceDatabase(object):
# default database file path
#
# internal class used for call corresponding file parser and caching the result
# to avoid unnecessary re-parsing
#
class BuildObjectFactory(object):
_FILE_TYPE_ = {
".inf" : MODEL_FILE_INF,
".dec" : MODEL_FILE_DEC,
".dsc" : MODEL_FILE_DSC,
}
# file parser
_FILE_PARSER_ = {
}
# convert to xxxBuildData object
_GENERATOR_ = {
}
_CACHE_ = {} # (FilePath, Arch) : <object>
# constructor
# key = (FilePath, Arch=None)
else:
Arch = None
# key = (FilePath, Arch=None, Target=None, Toochain=None)
if KeyLength > 1:
else:
Arch = None
if KeyLength > 2:
else:
Target = None
if KeyLength > 3:
else:
Toolchain = None
# if it's generated before, just return the cached one
# check file type
return None
return None
# get the parser ready for this file
)
# alwasy do post-process, in case of macros change
# object the build is based on
self,
Arch,
)
return BuildObject
# placeholder for file format conversion
class TransformObjectFactory:
# key = FilePath, Arch
pass
## Constructor of WorkspaceDatabase
#
# @param DbPath Path of database file
# @param GlobalMacros Global macros used for replacement during file parsing
# @prarm RenewDb=False Create new database file if it's already there
#
if not DbPath:
# don't create necessary path for db in memory
if DbPath != ':memory:':
# remove db file in case inconsistency between db and file in file system
# create db with optimized parameters
#self.Conn.execute("PRAGMA page_size=8192")
# to avoid non-ascii character conversion issue
# create table for internal uses
# conversion object for build or file format conversion purpose
## Check whether workspace database need to be renew.
# The renew reason maybe:
# 1) If user force to renew;
# 2) If user do not force renew, and
# a) If the time of last modified python source is newer than database file;
# b) If the time of last modified frozen executable file is newer than database file;
#
# @param force User force renew database
# @param DbPath The absolute path of workspace database file
#
# @return Bool value for whether need renew workspace databse
#
# if database does not exist, we need do nothing
# if user force to renew database, then not check whether database is out of date
#
# Check the time of last modified source file or build.exe
# if is newer than time of database, then database need to be re-created.
#
else:
rootPath = os.path.split(curPath)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
# walk the root path of source or build's binary to get the time last modified.
# bypass source control folder
return True
return False
## Initialize build database
def InitDatabase(self):
#
# Create new tables
#
#
# Initialize table DataModel
#
## Query a table
#
# @param Table: The instance of the table to be queried
#
## Close entire database
#
# Commit all first
# Close the connection and cursor
#
if not self._DbClosedFlag:
## Summarize all packages in the database
PackageList =[]
#
# Get Package related to Modules
#
if Package not in PackageList:
#
# Get Packages related to Libraries
#
if Package not in PackageList:
return PackageList
## Summarize all platforms in the database
def _GetPlatformList(self):
PlatformList = []
try:
except:
Platform = None
if Platform != None:
return PlatformList
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
pass