BaseTools: refactor to cache InfBuildData data

use Common.caching and auto cache properties and functions of InfBuildData

Cc: Liming Gao <liming.gao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Bob Feng <bob.c.feng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jaben Carsey <jaben.carsey@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
This commit is contained in:
Carsey, Jaben
2018-09-11 06:18:09 +08:00
committed by Yonghong Zhu
parent 4def57d98c
commit 719fd85c73

View File

@ -13,14 +13,14 @@
# #
from __future__ import absolute_import from __future__ import absolute_import
from Common.StringUtils import *
from Common.DataType import * from Common.DataType import *
from Common.Misc import * from Common.Misc import *
from Common.caching import cached_property, cached_class_function
from types import * from types import *
from .MetaFileParser import * from .MetaFileParser import *
from collections import OrderedDict from collections import OrderedDict
from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClassObject, PcdClassObject from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClassObject, PcdClassObject
## Module build information from INF file ## Module build information from INF file
# #
# This class is used to retrieve information stored in database and convert them # This class is used to retrieve information stored in database and convert them
@ -77,9 +77,9 @@ class InfBuildData(ModuleBuildClassObject):
} }
## Constructor of DscBuildData ## Constructor of InfBuildData
# #
# Initialize object of DscBuildData # Initialize object of InfBuildData
# #
# @param FilePath The path of platform description file # @param FilePath The path of platform description file
# @param RawData The raw data of DSC file # @param RawData The raw data of DSC file
@ -97,29 +97,11 @@ class InfBuildData(ModuleBuildClassObject):
self._Target = Target self._Target = Target
self._Toolchain = Toolchain self._Toolchain = Toolchain
self._Platform = TAB_COMMON self._Platform = TAB_COMMON
self._SourceOverridePath = None
if FilePath.Key in GlobalData.gOverrideDir: if FilePath.Key in GlobalData.gOverrideDir:
self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key] self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]
self._Clear() else:
self._SourceOverridePath = None
## XXX[key] = value
def __setitem__(self, key, value):
self.__dict__[self._PROPERTY_[key]] = value
## value = XXX[key]
def __getitem__(self, key):
return self.__dict__[self._PROPERTY_[key]]
## "in" test support
def __contains__(self, key):
return key in self._PROPERTY_
## Set all internal used members of InfBuildData to None
def _Clear(self):
self._HeaderComments = None
self._TailComments = None self._TailComments = None
self._Header_ = None
self._AutoGenVersion = None
self._BaseName = None self._BaseName = None
self._DxsFile = None self._DxsFile = None
self._ModuleType = None self._ModuleType = None
@ -139,64 +121,59 @@ class InfBuildData(ModuleBuildClassObject):
self._ConstructorList = None self._ConstructorList = None
self._DestructorList = None self._DestructorList = None
self._Defs = OrderedDict() self._Defs = OrderedDict()
self._Binaries = None
self._Sources = None
self._LibraryClasses = None
self._Libraries = None
self._Protocols = None
self._ProtocolComments = None self._ProtocolComments = None
self._Ppis = None
self._PpiComments = None self._PpiComments = None
self._Guids = None
self._GuidsUsedByPcd = OrderedDict() self._GuidsUsedByPcd = OrderedDict()
self._GuidComments = None self._GuidComments = None
self._Includes = None
self._Packages = None
self._Pcds = None
self._PcdComments = None self._PcdComments = None
self._BuildOptions = None self._BuildOptions = None
self._Depex = None self._DependencyFileList = None
self._DepexExpression = None
self._MacroDict = None ## XXX[key] = value
def __setitem__(self, key, value):
self.__dict__[self._PROPERTY_[key]] = value
## value = XXX[key]
def __getitem__(self, key):
return self.__dict__[self._PROPERTY_[key]]
## "in" test support
def __contains__(self, key):
return key in self._PROPERTY_
## Get current effective macros ## Get current effective macros
@property @cached_property
def _Macros(self): def _Macros(self):
if self._MacroDict is None: RetVal = {}
self._MacroDict = {}
# EDK_GLOBAL defined macros can be applied to EDK module # EDK_GLOBAL defined macros can be applied to EDK module
if self.AutoGenVersion < 0x00010005: if self.AutoGenVersion < 0x00010005:
self._MacroDict.update(GlobalData.gEdkGlobal) RetVal.update(GlobalData.gEdkGlobal)
self._MacroDict.update(GlobalData.gGlobalDefines) RetVal.update(GlobalData.gGlobalDefines)
return self._MacroDict return RetVal
## Get architecture ## Get architecture
@property @cached_property
def Arch(self): def Arch(self):
return self._Arch return self._Arch
## Return the name of platform employing this module ## Return the name of platform employing this module
@property @cached_property
def Platform(self): def Platform(self):
return self._Platform return self._Platform
@cached_property
@property
def HeaderComments(self): def HeaderComments(self):
if not self._HeaderComments: return [a[0] for a in self._RawData[MODEL_META_DATA_HEADER_COMMENT]]
self._HeaderComments = [a[0] for a in self._RawData[MODEL_META_DATA_HEADER_COMMENT]]
return self._HeaderComments
@property @cached_property
def TailComments(self): def TailComments(self):
if not self._TailComments: return [a[0] for a in self._RawData[MODEL_META_DATA_TAIL_COMMENT]]
self._TailComments = [a[0] for a in self._RawData[MODEL_META_DATA_TAIL_COMMENT]]
return self._TailComments
## Retrieve all information in [Defines] section ## Retrieve all information in [Defines] section
# #
# (Retriving all [Defines] information in one-shot is just to save time.) # (Retriving all [Defines] information in one-shot is just to save time.)
# #
@cached_class_function
def _GetHeaderInfo(self): def _GetHeaderInfo(self):
RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform] RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
for Record in RecordList: for Record in RecordList:
@ -311,9 +288,9 @@ class InfBuildData(ModuleBuildClassObject):
if ErrorCode != 0: if ErrorCode != 0:
EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,
File=self.MetaFile, Line=LineNo) File=self.MetaFile, Line=LineNo)
if self.Sources is None: if not self._DependencyFileList:
self._Sources = [] self._DependencyFileList = []
self._Sources.append(File) self._DependencyFileList.append(File)
else: else:
if not self._ComponentType: if not self._ComponentType:
EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
@ -341,9 +318,9 @@ class InfBuildData(ModuleBuildClassObject):
if ErrorCode != 0: if ErrorCode != 0:
EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,
File=self.MetaFile, Line=LineNo) File=self.MetaFile, Line=LineNo)
if self.Sources is None: if not self._DependencyFileList:
self._Sources = [] self._DependencyFileList = []
self._Sources.append(File) self._DependencyFileList.append(File)
else: else:
ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name) ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)
if len(ToolList) == 1: if len(ToolList) == 1:
@ -369,13 +346,11 @@ class InfBuildData(ModuleBuildClassObject):
else: else:
OptionString = self._BuildOptions[TAB_COMPILER_MSFT, ToolChain] OptionString = self._BuildOptions[TAB_COMPILER_MSFT, ToolChain]
self._BuildOptions[TAB_COMPILER_MSFT, ToolChain] = OptionString + " " + Value self._BuildOptions[TAB_COMPILER_MSFT, ToolChain] = OptionString + " " + Value
# set _Header to non-None in order to avoid database re-querying
self._Header_ = 'DUMMY'
## Retrieve file version ## Retrieve file version
@property @cached_property
def AutoGenVersion(self): def AutoGenVersion(self):
if self._AutoGenVersion is None: RetVal = 0x00010000
RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform] RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
for Record in RecordList: for Record in RecordList:
if Record[1] == TAB_INF_DEFINES_INF_VERSION: if Record[1] == TAB_INF_DEFINES_INF_VERSION:
@ -383,39 +358,34 @@ class InfBuildData(ModuleBuildClassObject):
ValueList = Record[2].split('.') ValueList = Record[2].split('.')
Major = '%04o' % int(ValueList[0], 0) Major = '%04o' % int(ValueList[0], 0)
Minor = '%04o' % int(ValueList[1], 0) Minor = '%04o' % int(ValueList[1], 0)
self._AutoGenVersion = int('0x' + Major + Minor, 0) RetVal = int('0x' + Major + Minor, 0)
else: else:
self._AutoGenVersion = int(Record[2], 0) RetVal = int(Record[2], 0)
break break
if self._AutoGenVersion is None: return RetVal
self._AutoGenVersion = 0x00010000
return self._AutoGenVersion
## Retrieve BASE_NAME ## Retrieve BASE_NAME
@property @cached_property
def BaseName(self): def BaseName(self):
if self._BaseName is None: if self._BaseName is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._BaseName is None: if self._BaseName is None:
EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile) EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)
return self._BaseName return self._BaseName
## Retrieve DxsFile ## Retrieve DxsFile
@property @cached_property
def DxsFile(self): def DxsFile(self):
if self._DxsFile is None: if self._DxsFile is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._DxsFile is None: if self._DxsFile is None:
self._DxsFile = '' self._DxsFile = ''
return self._DxsFile return self._DxsFile
## Retrieve MODULE_TYPE ## Retrieve MODULE_TYPE
@property @cached_property
def ModuleType(self): def ModuleType(self):
if self._ModuleType is None: if self._ModuleType is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._ModuleType is None: if self._ModuleType is None:
self._ModuleType = SUP_MODULE_BASE self._ModuleType = SUP_MODULE_BASE
@ -424,148 +394,134 @@ class InfBuildData(ModuleBuildClassObject):
return self._ModuleType return self._ModuleType
## Retrieve COMPONENT_TYPE ## Retrieve COMPONENT_TYPE
@property @cached_property
def ComponentType(self): def ComponentType(self):
if self._ComponentType is None: if self._ComponentType is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._ComponentType is None: if self._ComponentType is None:
self._ComponentType = SUP_MODULE_USER_DEFINED self._ComponentType = SUP_MODULE_USER_DEFINED
return self._ComponentType return self._ComponentType
## Retrieve "BUILD_TYPE" ## Retrieve "BUILD_TYPE"
@property @cached_property
def BuildType(self): def BuildType(self):
if self._BuildType is None: if self._BuildType is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if not self._BuildType: if not self._BuildType:
self._BuildType = SUP_MODULE_BASE self._BuildType = SUP_MODULE_BASE
return self._BuildType return self._BuildType
## Retrieve file guid ## Retrieve file guid
@property @cached_property
def Guid(self): def Guid(self):
if self._Guid is None: if self._Guid is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._Guid is None: if self._Guid is None:
self._Guid = '00000000-0000-0000-0000-000000000000' self._Guid = '00000000-0000-0000-0000-000000000000'
return self._Guid return self._Guid
## Retrieve module version ## Retrieve module version
@property @cached_property
def Version(self): def Version(self):
if self._Version is None: if self._Version is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._Version is None: if self._Version is None:
self._Version = '0.0' self._Version = '0.0'
return self._Version return self._Version
## Retrieve PCD_IS_DRIVER ## Retrieve PCD_IS_DRIVER
@property @cached_property
def PcdIsDriver(self): def PcdIsDriver(self):
if self._PcdIsDriver is None: if self._PcdIsDriver is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._PcdIsDriver is None: if self._PcdIsDriver is None:
self._PcdIsDriver = '' self._PcdIsDriver = ''
return self._PcdIsDriver return self._PcdIsDriver
## Retrieve SHADOW ## Retrieve SHADOW
@property @cached_property
def Shadow(self): def Shadow(self):
if self._Shadow is None: if self._Shadow is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._Shadow is not None and self._Shadow.upper() == 'TRUE': if self._Shadow and self._Shadow.upper() == 'TRUE':
self._Shadow = True self._Shadow = True
else: else:
self._Shadow = False self._Shadow = False
return self._Shadow return self._Shadow
## Retrieve CUSTOM_MAKEFILE ## Retrieve CUSTOM_MAKEFILE
@property @cached_property
def CustomMakefile(self): def CustomMakefile(self):
if self._CustomMakefile is None: if self._CustomMakefile is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._CustomMakefile is None: if self._CustomMakefile is None:
self._CustomMakefile = {} self._CustomMakefile = {}
return self._CustomMakefile return self._CustomMakefile
## Retrieve EFI_SPECIFICATION_VERSION ## Retrieve EFI_SPECIFICATION_VERSION
@property @cached_property
def Specification(self): def Specification(self):
if self._Specification is None: if self._Specification is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._Specification is None: if self._Specification is None:
self._Specification = {} self._Specification = {}
return self._Specification return self._Specification
## Retrieve LIBRARY_CLASS ## Retrieve LIBRARY_CLASS
@property @cached_property
def LibraryClass(self): def LibraryClass(self):
if self._LibraryClass is None: if self._LibraryClass is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._LibraryClass is None: if self._LibraryClass is None:
self._LibraryClass = [] self._LibraryClass = []
return self._LibraryClass return self._LibraryClass
## Retrieve ENTRY_POINT ## Retrieve ENTRY_POINT
@property @cached_property
def ModuleEntryPointList(self): def ModuleEntryPointList(self):
if self._ModuleEntryPointList is None: if self._ModuleEntryPointList is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._ModuleEntryPointList is None: if self._ModuleEntryPointList is None:
self._ModuleEntryPointList = [] self._ModuleEntryPointList = []
return self._ModuleEntryPointList return self._ModuleEntryPointList
## Retrieve UNLOAD_IMAGE ## Retrieve UNLOAD_IMAGE
@property @cached_property
def ModuleUnloadImageList(self): def ModuleUnloadImageList(self):
if self._ModuleUnloadImageList is None: if self._ModuleUnloadImageList is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._ModuleUnloadImageList is None: if self._ModuleUnloadImageList is None:
self._ModuleUnloadImageList = [] self._ModuleUnloadImageList = []
return self._ModuleUnloadImageList return self._ModuleUnloadImageList
## Retrieve CONSTRUCTOR ## Retrieve CONSTRUCTOR
@property @cached_property
def ConstructorList(self): def ConstructorList(self):
if self._ConstructorList is None: if self._ConstructorList is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._ConstructorList is None: if self._ConstructorList is None:
self._ConstructorList = [] self._ConstructorList = []
return self._ConstructorList return self._ConstructorList
## Retrieve DESTRUCTOR ## Retrieve DESTRUCTOR
@property @cached_property
def DestructorList(self): def DestructorList(self):
if self._DestructorList is None: if self._DestructorList is None:
if self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
if self._DestructorList is None: if self._DestructorList is None:
self._DestructorList = [] self._DestructorList = []
return self._DestructorList return self._DestructorList
## Retrieve definies other than above ones ## Retrieve definies other than above ones
@property @cached_property
def Defines(self): def Defines(self):
if len(self._Defs) == 0 and self._Header_ is None:
self._GetHeaderInfo() self._GetHeaderInfo()
return self._Defs return self._Defs
## Retrieve binary files ## Retrieve binary files
@cached_class_function
def _GetBinaries(self): def _GetBinaries(self):
if self._Binaries is None: RetVal = []
self._Binaries = []
RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform] RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]
Macros = self._Macros Macros = self._Macros
Macros["EDK_SOURCE"] = GlobalData.gEcpSource Macros["EDK_SOURCE"] = GlobalData.gEcpSource
@ -587,29 +543,28 @@ class InfBuildData(ModuleBuildClassObject):
ErrorCode, ErrorInfo = File.Validate() ErrorCode, ErrorInfo = File.Validate()
if ErrorCode != 0: if ErrorCode != 0:
EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
self._Binaries.append(File) RetVal.append(File)
return self._Binaries return RetVal
## Retrieve binary files with error check. ## Retrieve binary files with error check.
@property @cached_property
def Binaries(self): def Binaries(self):
Binaries = self._GetBinaries() RetVal = self._GetBinaries()
if GlobalData.gIgnoreSource and Binaries == []: if GlobalData.gIgnoreSource and not RetVal:
ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n" ErrorInfo = "The INF file does not contain any RetVal to use in creating the image\n"
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile) EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)
return Binaries return RetVal
## Retrieve source files ## Retrieve source files
@property @cached_property
def Sources(self): def Sources(self):
self._GetHeaderInfo()
# Ignore all source files in a binary build mode # Ignore all source files in a binary build mode
if GlobalData.gIgnoreSource: if GlobalData.gIgnoreSource:
self._Sources = [] return []
return self._Sources
if self._Sources is None: RetVal = []
self._Sources = []
RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform] RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]
Macros = self._Macros Macros = self._Macros
for Record in RecordList: for Record in RecordList:
@ -617,7 +572,6 @@ class InfBuildData(ModuleBuildClassObject):
ToolChainFamily = Record[1] ToolChainFamily = Record[1]
TagName = Record[2] TagName = Record[2]
ToolCode = Record[3] ToolCode = Record[3]
FeatureFlag = Record[4]
if self.AutoGenVersion < 0x00010005: if self.AutoGenVersion < 0x00010005:
Macros["EDK_SOURCE"] = GlobalData.gEcpSource Macros["EDK_SOURCE"] = GlobalData.gEcpSource
Macros['PROCESSOR'] = self._Arch Macros['PROCESSOR'] = self._Arch
@ -644,47 +598,47 @@ class InfBuildData(ModuleBuildClassObject):
if ErrorCode != 0: if ErrorCode != 0:
EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
self._Sources.append(File) RetVal.append(File)
return self._Sources # add any previously found dependency files to the source list
if self._DependencyFileList:
RetVal.extend(self._DependencyFileList)
return RetVal
## Retrieve library classes employed by this module ## Retrieve library classes employed by this module
@property @cached_property
def LibraryClasses(self): def LibraryClasses(self):
if self._LibraryClasses is None: RetVal = OrderedDict()
self._LibraryClasses = OrderedDict()
RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform] RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]
for Record in RecordList: for Record in RecordList:
Lib = Record[0] Lib = Record[0]
Instance = Record[1] Instance = Record[1]
if Instance: if Instance:
Instance = NormPath(Instance, self._Macros) Instance = NormPath(Instance, self._Macros)
self._LibraryClasses[Lib] = Instance RetVal[Lib] = Instance
return self._LibraryClasses return RetVal
## Retrieve library names (for Edk.x style of modules) ## Retrieve library names (for Edk.x style of modules)
@property @cached_property
def Libraries(self): def Libraries(self):
if self._Libraries is None: RetVal = []
self._Libraries = []
RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform] RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]
for Record in RecordList: for Record in RecordList:
LibraryName = ReplaceMacro(Record[0], self._Macros, False) LibraryName = ReplaceMacro(Record[0], self._Macros, False)
# in case of name with '.lib' extension, which is unusual in Edk.x inf # in case of name with '.lib' extension, which is unusual in Edk.x inf
LibraryName = os.path.splitext(LibraryName)[0] LibraryName = os.path.splitext(LibraryName)[0]
if LibraryName not in self._Libraries: if LibraryName not in RetVal:
self._Libraries.append(LibraryName) RetVal.append(LibraryName)
return self._Libraries return RetVal
@property @cached_property
def ProtocolComments(self): def ProtocolComments(self):
self.Protocols self.Protocols
return self._ProtocolComments return self._ProtocolComments
## Retrieve protocols consumed/produced by this module ## Retrieve protocols consumed/produced by this module
@property @cached_property
def Protocols(self): def Protocols(self):
if self._Protocols is None: RetVal = OrderedDict()
self._Protocols = OrderedDict()
self._ProtocolComments = OrderedDict() self._ProtocolComments = OrderedDict()
RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform] RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]
for Record in RecordList: for Record in RecordList:
@ -695,24 +649,20 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
"Value of Protocol [%s] is not found under [Protocols] section in" % CName, "Value of Protocol [%s] is not found under [Protocols] section in" % CName,
ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
self._Protocols[CName] = Value RetVal[CName] = Value
CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]] CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
Comments = [] self._ProtocolComments[CName] = [a[0] for a in CommentRecords]
for CmtRec in CommentRecords: return RetVal
Comments.append(CmtRec[0])
self._ProtocolComments[CName] = Comments
return self._Protocols
@property @cached_property
def PpiComments(self): def PpiComments(self):
self.Ppis self.Ppis
return self._PpiComments return self._PpiComments
## Retrieve PPIs consumed/produced by this module ## Retrieve PPIs consumed/produced by this module
@property @cached_property
def Ppis(self): def Ppis(self):
if self._Ppis is None: RetVal = OrderedDict()
self._Ppis = OrderedDict()
self._PpiComments = OrderedDict() self._PpiComments = OrderedDict()
RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform] RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]
for Record in RecordList: for Record in RecordList:
@ -723,24 +673,20 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
"Value of PPI [%s] is not found under [Ppis] section in " % CName, "Value of PPI [%s] is not found under [Ppis] section in " % CName,
ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
self._Ppis[CName] = Value RetVal[CName] = Value
CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]] CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
Comments = [] self._PpiComments[CName] = [a[0] for a in CommentRecords]
for CmtRec in CommentRecords: return RetVal
Comments.append(CmtRec[0])
self._PpiComments[CName] = Comments
return self._Ppis
@property @cached_property
def GuidComments(self): def GuidComments(self):
self.Guids self.Guids
return self._GuidComments return self._GuidComments
## Retrieve GUIDs consumed/produced by this module ## Retrieve GUIDs consumed/produced by this module
@property @cached_property
def Guids(self): def Guids(self):
if self._Guids is None: RetVal = OrderedDict()
self._Guids = OrderedDict()
self._GuidComments = OrderedDict() self._GuidComments = OrderedDict()
RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform] RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]
for Record in RecordList: for Record in RecordList:
@ -751,21 +697,17 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
"Value of Guid [%s] is not found under [Guids] section in" % CName, "Value of Guid [%s] is not found under [Guids] section in" % CName,
ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
self._Guids[CName] = Value RetVal[CName] = Value
CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]] CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
Comments = [] self._GuidComments[CName] = [a[0] for a in CommentRecords]
for CmtRec in CommentRecords: return RetVal
Comments.append(CmtRec[0])
self._GuidComments[CName] = Comments
return self._Guids
## Retrieve include paths necessary for this module (for Edk.x style of modules) ## Retrieve include paths necessary for this module (for Edk.x style of modules)
@property @cached_property
def Includes(self): def Includes(self):
if self._Includes is None: RetVal = []
self._Includes = []
if self._SourceOverridePath: if self._SourceOverridePath:
self._Includes.append(self._SourceOverridePath) RetVal.append(self._SourceOverridePath)
Macros = self._Macros Macros = self._Macros
Macros['PROCESSOR'] = GlobalData.gEdkGlobal.get('PROCESSOR', self._Arch) Macros['PROCESSOR'] = GlobalData.gEdkGlobal.get('PROCESSOR', self._Arch)
@ -780,7 +722,7 @@ class InfBuildData(ModuleBuildClassObject):
File = os.path.join(GlobalData.gWorkspace, File) File = os.path.join(GlobalData.gWorkspace, File)
File = RealPath(os.path.normpath(File)) File = RealPath(os.path.normpath(File))
if File: if File:
self._Includes.append(File) RetVal.append(File)
# TRICK: let compiler to choose correct header file # TRICK: let compiler to choose correct header file
Macros['EDK_SOURCE'] = GlobalData.gEdkSource Macros['EDK_SOURCE'] = GlobalData.gEdkSource
@ -791,7 +733,7 @@ class InfBuildData(ModuleBuildClassObject):
File = os.path.join(GlobalData.gWorkspace, File) File = os.path.join(GlobalData.gWorkspace, File)
File = RealPath(os.path.normpath(File)) File = RealPath(os.path.normpath(File))
if File: if File:
self._Includes.append(File) RetVal.append(File)
else: else:
File = NormPath(Record[0], Macros) File = NormPath(Record[0], Macros)
if File[0] == '.': if File[0] == '.':
@ -800,7 +742,7 @@ class InfBuildData(ModuleBuildClassObject):
File = mws.join(GlobalData.gWorkspace, File) File = mws.join(GlobalData.gWorkspace, File)
File = RealPath(os.path.normpath(File)) File = RealPath(os.path.normpath(File))
if File: if File:
self._Includes.append(File) RetVal.append(File)
if not File and Record[0].find('EFI_SOURCE') > -1: if not File and Record[0].find('EFI_SOURCE') > -1:
# tricky to regard WorkSpace as EFI_SOURCE # tricky to regard WorkSpace as EFI_SOURCE
Macros['EFI_SOURCE'] = GlobalData.gWorkspace Macros['EFI_SOURCE'] = GlobalData.gWorkspace
@ -811,50 +753,47 @@ class InfBuildData(ModuleBuildClassObject):
File = os.path.join(GlobalData.gWorkspace, File) File = os.path.join(GlobalData.gWorkspace, File)
File = RealPath(os.path.normpath(File)) File = RealPath(os.path.normpath(File))
if File: if File:
self._Includes.append(File) RetVal.append(File)
return self._Includes return RetVal
## Retrieve packages this module depends on ## Retrieve packages this module depends on
@property @cached_property
def Packages(self): def Packages(self):
if self._Packages is None: RetVal = []
self._Packages = []
RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform] RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]
Macros = self._Macros Macros = self._Macros
Macros['EDK_SOURCE'] = GlobalData.gEcpSource Macros['EDK_SOURCE'] = GlobalData.gEcpSource
for Record in RecordList: for Record in RecordList:
File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch) File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
LineNo = Record[-1]
# check the file validation # check the file validation
ErrorCode, ErrorInfo = File.Validate('.dec') ErrorCode, ErrorInfo = File.Validate('.dec')
if ErrorCode != 0: if ErrorCode != 0:
LineNo = Record[-1]
EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
# parse this package now. we need it to get protocol/ppi/guid value # parse this package now. we need it to get protocol/ppi/guid value
Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain] RetVal.append(self._Bdb[File, self._Arch, self._Target, self._Toolchain])
self._Packages.append(Package) return RetVal
return self._Packages
## Retrieve PCD comments ## Retrieve PCD comments
@property @cached_property
def PcdComments(self): def PcdComments(self):
self.Pcds self.Pcds
return self._PcdComments return self._PcdComments
## Retrieve PCDs used in this module ## Retrieve PCDs used in this module
@property @cached_property
def Pcds(self): def Pcds(self):
if self._Pcds is None:
self._Pcds = OrderedDict()
self._PcdComments = OrderedDict() self._PcdComments = OrderedDict()
self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD)) RetVal = OrderedDict()
self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE)) RetVal.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG)) RetVal.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC)) RetVal.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX)) RetVal.update(self._GetPcd(MODEL_PCD_DYNAMIC))
return self._Pcds RetVal.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
return RetVal
## Retrieve build options specific to this module ## Retrieve build options specific to this module
@property @cached_property
def BuildOptions(self): def BuildOptions(self):
if self._BuildOptions is None: if self._BuildOptions is None:
self._BuildOptions = OrderedDict() self._BuildOptions = OrderedDict()
@ -872,17 +811,15 @@ class InfBuildData(ModuleBuildClassObject):
return self._BuildOptions return self._BuildOptions
## Retrieve dependency expression ## Retrieve dependency expression
@property @cached_property
def Depex(self): def Depex(self):
if self._Depex is None: RetVal = tdict(False, 2)
self._Depex = tdict(False, 2)
RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
# If the module has only Binaries and no Sources, then ignore [Depex] # If the module has only Binaries and no Sources, then ignore [Depex]
if self.Sources is None or self.Sources == []: if not self.Sources and self.Binaries:
if self.Binaries is not None and self.Binaries != []: return RetVal
return self._Depex
RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
# PEIM and DXE drivers must have a valid [Depex] section # PEIM and DXE drivers must have a valid [Depex] section
if len(self.LibraryClass) == 0 and len(RecordList) == 0: if len(self.LibraryClass) == 0 and len(RecordList) == 0:
if self.ModuleType == SUP_MODULE_DXE_DRIVER or self.ModuleType == SUP_MODULE_PEIM or self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER or \ if self.ModuleType == SUP_MODULE_DXE_DRIVER or self.ModuleType == SUP_MODULE_PEIM or self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER or \
@ -897,15 +834,15 @@ class InfBuildData(ModuleBuildClassObject):
"'%s' module must specify the type of [Depex] section" % self.ModuleType, "'%s' module must specify the type of [Depex] section" % self.ModuleType,
File=self.MetaFile) File=self.MetaFile)
Depex = OrderedDict() TemporaryDictionary = OrderedDict()
for Record in RecordList: for Record in RecordList:
DepexStr = ReplaceMacro(Record[0], self._Macros, False) DepexStr = ReplaceMacro(Record[0], self._Macros, False)
Arch = Record[3] Arch = Record[3]
ModuleType = Record[4] ModuleType = Record[4]
TokenList = DepexStr.split() TokenList = DepexStr.split()
if (Arch, ModuleType) not in Depex: if (Arch, ModuleType) not in TemporaryDictionary:
Depex[Arch, ModuleType] = [] TemporaryDictionary[Arch, ModuleType] = []
DepexList = Depex[Arch, ModuleType] DepexList = TemporaryDictionary[Arch, ModuleType]
for Token in TokenList: for Token in TokenList:
if Token in DEPEX_SUPPORTED_OPCODE_SET: if Token in DEPEX_SUPPORTED_OPCODE_SET:
DepexList.append(Token) DepexList.append(Token)
@ -939,31 +876,32 @@ class InfBuildData(ModuleBuildClassObject):
"Value of [%s] is not found in" % Token, "Value of [%s] is not found in" % Token,
ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
DepexList.append(Value) DepexList.append(Value)
for Arch, ModuleType in Depex: for Arch, ModuleType in TemporaryDictionary:
self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType] RetVal[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType]
return self._Depex return RetVal
## Retrieve depedency expression ## Retrieve depedency expression
@property @cached_property
def DepexExpression(self): def DepexExpression(self):
if self._DepexExpression is None: RetVal = tdict(False, 2)
self._DepexExpression = tdict(False, 2)
RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch] RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
DepexExpression = OrderedDict() TemporaryDictionary = OrderedDict()
for Record in RecordList: for Record in RecordList:
DepexStr = ReplaceMacro(Record[0], self._Macros, False) DepexStr = ReplaceMacro(Record[0], self._Macros, False)
Arch = Record[3] Arch = Record[3]
ModuleType = Record[4] ModuleType = Record[4]
TokenList = DepexStr.split() TokenList = DepexStr.split()
if (Arch, ModuleType) not in DepexExpression: if (Arch, ModuleType) not in TemporaryDictionary:
DepexExpression[Arch, ModuleType] = '' TemporaryDictionary[Arch, ModuleType] = ''
for Token in TokenList: for Token in TokenList:
DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' ' TemporaryDictionary[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType] + Token.strip() + ' '
for Arch, ModuleType in DepexExpression: for Arch, ModuleType in TemporaryDictionary:
self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] RetVal[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType]
return self._DepexExpression return RetVal
@cached_class_function
def GetGuidsUsedByPcd(self): def GetGuidsUsedByPcd(self):
self.Pcds
return self._GuidsUsedByPcd return self._GuidsUsedByPcd
## Retrieve PCD for given type ## Retrieve PCD for given type