summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/Workspace/DecBuildData.py
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/Python/Workspace/DecBuildData.py')
-rw-r--r--BaseTools/Source/Python/Workspace/DecBuildData.py922
1 files changed, 461 insertions, 461 deletions
diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py b/BaseTools/Source/Python/Workspace/DecBuildData.py
index eeb7c490ac..9289e969fb 100644
--- a/BaseTools/Source/Python/Workspace/DecBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DecBuildData.py
@@ -1,461 +1,461 @@
-## @file
-# This file is used to create a database used by build tool
-#
-# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
-# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-from Common.StringUtils import *
-from Common.DataType import *
-from Common.Misc import *
-from types import *
-from collections import OrderedDict
-from CommonDataClass.DataClass import *
-from Workspace.BuildClassObject import PackageBuildClassObject, StructurePcd, PcdClassObject
-from Common.GlobalData import gGlobalDefines
-from re import compile
-
-## 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 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
- #
- def __init__(self, File, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
- self.MetaFile = File
- self._PackageDir = File.Dir
- self._RawData = RawData
- self._Bdb = BuildDataBase
- self._Arch = Arch
- self._Target = Target
- self._Toolchain = Toolchain
- self._Clear()
- self.UpdatePcdTypeDict()
-
- ## 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 DecBuildData to None
- def _Clear(self):
- self._Header = None
- self._PackageName = None
- self._Guid = None
- self._Version = None
- self._PkgUniFile = None
- self._Protocols = None
- self._Ppis = None
- self._Guids = None
- self._Includes = None
- self._CommonIncludes = None
- self._LibraryClasses = None
- self._Pcds = None
- self._MacroDict = None
- self._PrivateProtocols = None
- self._PrivatePpis = None
- self._PrivateGuids = None
- self._PrivateIncludes = None
-
- ## Get current effective macros
- @property
- def _Macros(self):
- if self._MacroDict is None:
- self._MacroDict = dict(gGlobalDefines)
- return self._MacroDict
-
- ## Get architecture
- @property
- def Arch(self):
- return self._Arch
-
- ## Retrieve all information in [Defines] section
- #
- # (Retrieving all [Defines] information in one-shot is just to save time.)
- #
- def _GetHeaderInfo(self):
- RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
- for Record in RecordList:
- Name = Record[1]
- if Name in self:
- self[Name] = Record[2]
- self._Header = 'DUMMY'
-
- ## Retrieve package name
- @property
- def PackageName(self):
- if self._PackageName is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._PackageName is None:
- EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)
- return self._PackageName
-
- ## Retrieve file guid
- @property
- def PackageName(self):
- if self._Guid is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._Guid is None:
- EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)
- return self._Guid
-
- ## Retrieve package version
- @property
- def Version(self):
- if self._Version is None:
- if self._Header is None:
- self._GetHeaderInfo()
- if self._Version is None:
- self._Version = ''
- return self._Version
-
- ## Retrieve protocol definitions (name/value pairs)
- @property
- def Protocols(self):
- if self._Protocols is None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # protocol definition for given ARCH
- #
- ProtocolDict = tdict(True)
- PrivateProtocolDict = tdict(True)
- NameList = []
- PrivateNameList = []
- PublicNameList = []
- # find out all protocol definitions for specific and 'common' arch
- RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]
- for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
- if PrivateFlag == 'PRIVATE':
- if Name not in PrivateNameList:
- PrivateNameList.append(Name)
- PrivateProtocolDict[Arch, Name] = Guid
- if Name in PublicNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- else:
- if Name not in PublicNameList:
- PublicNameList.append(Name)
- if Name in PrivateNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- if Name not in NameList:
- NameList.append(Name)
- ProtocolDict[Arch, Name] = Guid
- # use OrderedDict to keep the order
- self._Protocols = OrderedDict()
- self._PrivateProtocols = OrderedDict()
- for Name in NameList:
- #
- # limit the ARCH to self._Arch, if no self._Arch found, tdict
- # will automatically turn to 'common' ARCH for trying
- #
- self._Protocols[Name] = ProtocolDict[self._Arch, Name]
- for Name in PrivateNameList:
- self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]
- return self._Protocols
-
- ## Retrieve PPI definitions (name/value pairs)
- @property
- def Ppis(self):
- if self._Ppis is None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # PPI definition for given ARCH
- #
- PpiDict = tdict(True)
- PrivatePpiDict = tdict(True)
- NameList = []
- PrivateNameList = []
- PublicNameList = []
- # find out all PPI definitions for specific arch and 'common' arch
- RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]
- for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
- if PrivateFlag == 'PRIVATE':
- if Name not in PrivateNameList:
- PrivateNameList.append(Name)
- PrivatePpiDict[Arch, Name] = Guid
- if Name in PublicNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- else:
- if Name not in PublicNameList:
- PublicNameList.append(Name)
- if Name in PrivateNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- if Name not in NameList:
- NameList.append(Name)
- PpiDict[Arch, Name] = Guid
- # use OrderedDict to keep the order
- self._Ppis = OrderedDict()
- self._PrivatePpis = OrderedDict()
- for Name in NameList:
- #
- # limit the ARCH to self._Arch, if no self._Arch found, tdict
- # will automatically turn to 'common' ARCH for trying
- #
- self._Ppis[Name] = PpiDict[self._Arch, Name]
- for Name in PrivateNameList:
- self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]
- return self._Ppis
-
- ## Retrieve GUID definitions (name/value pairs)
- @property
- def Guids(self):
- if self._Guids is None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # GUID definition for given ARCH
- #
- GuidDict = tdict(True)
- PrivateGuidDict = tdict(True)
- NameList = []
- PrivateNameList = []
- PublicNameList = []
- # find out all protocol definitions for specific and 'common' arch
- RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]
- for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
- if PrivateFlag == 'PRIVATE':
- if Name not in PrivateNameList:
- PrivateNameList.append(Name)
- PrivateGuidDict[Arch, Name] = Guid
- if Name in PublicNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- else:
- if Name not in PublicNameList:
- PublicNameList.append(Name)
- if Name in PrivateNameList:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
- if Name not in NameList:
- NameList.append(Name)
- GuidDict[Arch, Name] = Guid
- # use OrderedDict to keep the order
- self._Guids = OrderedDict()
- self._PrivateGuids = OrderedDict()
- for Name in NameList:
- #
- # limit the ARCH to self._Arch, if no self._Arch found, tdict
- # will automatically turn to 'common' ARCH for trying
- #
- self._Guids[Name] = GuidDict[self._Arch, Name]
- for Name in PrivateNameList:
- self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]
- return self._Guids
-
- ## Retrieve public include paths declared in this package
- @property
- def Includes(self):
- if self._Includes is None or self._CommonIncludes is None:
- self._CommonIncludes = []
- self._Includes = []
- self._PrivateIncludes = []
- PublicInclues = []
- RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]
- Macros = self._Macros
- for Record in RecordList:
- File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)
- LineNo = Record[-1]
- # validate the path
- ErrorCode, ErrorInfo = File.Validate()
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
-
- # avoid duplicate include path
- if File not in self._Includes:
- self._Includes.append(File)
- if Record[4] == 'PRIVATE':
- if File not in self._PrivateIncludes:
- self._PrivateIncludes.append(File)
- if File in PublicInclues:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
- else:
- if File not in PublicInclues:
- PublicInclues.append(File)
- if File in self._PrivateIncludes:
- EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
- if Record[3] == TAB_COMMON:
- self._CommonIncludes.append(File)
- return self._Includes
-
- ## Retrieve library class declarations (not used in build at present)
- @property
- def LibraryClasses(self):
- if self._LibraryClasses is None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # library class declaration for given ARCH
- #
- LibraryClassDict = tdict(True)
- LibraryClassSet = set()
- RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]
- Macros = self._Macros
- for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
- File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate()
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
- LibraryClassSet.add(LibraryClass)
- LibraryClassDict[Arch, LibraryClass] = File
- self._LibraryClasses = OrderedDict()
- for LibraryClass in LibraryClassSet:
- self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]
- return self._LibraryClasses
-
- ## Retrieve PCD declarations
- @property
- def Pcds(self):
- if self._Pcds is None:
- self._Pcds = OrderedDict()
- self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
- self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
- self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
- self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))
- self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
- return self._Pcds
-
- def ParsePcdName(self,TokenCName):
- TokenCName = TokenCName.strip()
- if TokenCName.startswith("["):
- if "." in TokenCName:
- Demesionattr = TokenCName[:TokenCName.index(".")]
- Fields = TokenCName[TokenCName.index(".")+1:]
- else:
- Demesionattr = TokenCName
- Fields = ""
- else:
- Demesionattr = ""
- Fields = TokenCName
-
- return Demesionattr,Fields
-
- def ProcessStructurePcd(self, StructurePcdRawDataSet):
- s_pcd_set = OrderedDict()
- for s_pcd, LineNo in StructurePcdRawDataSet:
- if s_pcd.TokenSpaceGuidCName not in s_pcd_set:
- s_pcd_set[s_pcd.TokenSpaceGuidCName] = []
- s_pcd_set[s_pcd.TokenSpaceGuidCName].append((s_pcd, LineNo))
-
- str_pcd_set = []
- for pcdname in s_pcd_set:
- dep_pkgs = []
- struct_pcd = StructurePcd()
- for item, LineNo in s_pcd_set[pcdname]:
- if not item.TokenCName:
- continue
- if "<HeaderFiles>" in item.TokenCName:
- struct_pcd.StructuredPcdIncludeFile.append(item.DefaultValue)
- elif "<Packages>" in item.TokenCName:
- dep_pkgs.append(item.DefaultValue)
- elif item.DatumType == item.TokenCName:
- struct_pcd.copy(item)
- struct_pcd.TokenValue = struct_pcd.TokenValue.strip("{").strip()
- struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName = pcdname.split(".")
- struct_pcd.PcdDefineLineNo = LineNo
- struct_pcd.PkgPath = self.MetaFile.File
- struct_pcd.SetDecDefaultValue(item.DefaultValue,self.MetaFile.File,LineNo)
- else:
- DemesionAttr, Fields = self.ParsePcdName(item.TokenCName)
- struct_pcd.AddDefaultValue(Fields, item.DefaultValue, self.MetaFile.File, LineNo,DemesionAttr)
-
- struct_pcd.PackageDecs = dep_pkgs
- str_pcd_set.append(struct_pcd)
- return str_pcd_set
-
- ## Retrieve PCD declarations for given type
- def _GetPcd(self, Type):
- Pcds = OrderedDict()
- #
- # tdict is a special kind of dict, used for selecting correct
- # PCD declaration for given ARCH
- #
- PcdDict = tdict(True, 3)
- # for summarizing PCD
- PcdSet = []
- # find out all PCDs of the 'type'
-
- StrPcdSet = []
- RecordList = self._RawData[Type, self._Arch]
- for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:
- PcdDict[Arch, PcdCName, TokenSpaceGuid] = (Setting, Dummy2)
- if not (PcdCName, TokenSpaceGuid) in PcdSet:
- PcdSet.append((PcdCName, TokenSpaceGuid))
-
- DefinitionPosition = {}
- for PcdCName, TokenSpaceGuid in PcdSet:
- #
- # limit the ARCH to self._Arch, if no self._Arch found, tdict
- # will automatically turn to 'common' ARCH and try again
- #
- Setting, LineNo = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
- if Setting is None:
- continue
-
- DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)
- validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)
- PcdObj = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- DatumType,
- DefaultValue,
- TokenNumber,
- '',
- {},
- False,
- None,
- list(validateranges),
- list(validlists),
- list(expressions)
- )
- DefinitionPosition[PcdObj] = (self.MetaFile.File, LineNo)
- if "." in TokenSpaceGuid:
- StrPcdSet.append((PcdObj, LineNo))
- else:
- Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdObj
-
- StructurePcds = self.ProcessStructurePcd(StrPcdSet)
- for pcd in StructurePcds:
- Pcds[pcd.TokenCName, pcd.TokenSpaceGuidCName, self._PCD_TYPE_STRING_[Type]] = pcd
- StructPattern = compile(r'[_a-zA-Z][0-9A-Za-z_]*$')
- for pcd in Pcds.values():
- if pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
- if not pcd.IsAggregateDatumType():
- EdkLogger.error('build', FORMAT_INVALID, "DatumType only support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct name.", DefinitionPosition[pcd][0], DefinitionPosition[pcd][1])
- elif not pcd.IsArray() and not pcd.StructuredPcdIncludeFile:
- EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (pcd.TokenSpaceGuidCName, pcd.TokenCName, pcd.DefinitionPosition[0], pcd.DefinitionPosition[1] ))
- return Pcds
-
- @property
- def CommonIncludes(self):
- if self._CommonIncludes is None:
- self.Includes
- return self._CommonIncludes
+## @file
+# This file is used to create a database used by build tool
+#
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+from Common.StringUtils import *
+from Common.DataType import *
+from Common.Misc import *
+from types import *
+from collections import OrderedDict
+from CommonDataClass.DataClass import *
+from Workspace.BuildClassObject import PackageBuildClassObject, StructurePcd, PcdClassObject
+from Common.GlobalData import gGlobalDefines
+from re import compile
+
+## 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 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
+ #
+ def __init__(self, File, RawData, BuildDataBase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):
+ self.MetaFile = File
+ self._PackageDir = File.Dir
+ self._RawData = RawData
+ self._Bdb = BuildDataBase
+ self._Arch = Arch
+ self._Target = Target
+ self._Toolchain = Toolchain
+ self._Clear()
+ self.UpdatePcdTypeDict()
+
+ ## 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 DecBuildData to None
+ def _Clear(self):
+ self._Header = None
+ self._PackageName = None
+ self._Guid = None
+ self._Version = None
+ self._PkgUniFile = None
+ self._Protocols = None
+ self._Ppis = None
+ self._Guids = None
+ self._Includes = None
+ self._CommonIncludes = None
+ self._LibraryClasses = None
+ self._Pcds = None
+ self._MacroDict = None
+ self._PrivateProtocols = None
+ self._PrivatePpis = None
+ self._PrivateGuids = None
+ self._PrivateIncludes = None
+
+ ## Get current effective macros
+ @property
+ def _Macros(self):
+ if self._MacroDict is None:
+ self._MacroDict = dict(gGlobalDefines)
+ return self._MacroDict
+
+ ## Get architecture
+ @property
+ def Arch(self):
+ return self._Arch
+
+ ## Retrieve all information in [Defines] section
+ #
+ # (Retrieving all [Defines] information in one-shot is just to save time.)
+ #
+ def _GetHeaderInfo(self):
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
+ for Record in RecordList:
+ Name = Record[1]
+ if Name in self:
+ self[Name] = Record[2]
+ self._Header = 'DUMMY'
+
+ ## Retrieve package name
+ @property
+ def PackageName(self):
+ if self._PackageName is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._PackageName is None:
+ EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)
+ return self._PackageName
+
+ ## Retrieve file guid
+ @property
+ def PackageName(self):
+ if self._Guid is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._Guid is None:
+ EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)
+ return self._Guid
+
+ ## Retrieve package version
+ @property
+ def Version(self):
+ if self._Version is None:
+ if self._Header is None:
+ self._GetHeaderInfo()
+ if self._Version is None:
+ self._Version = ''
+ return self._Version
+
+ ## Retrieve protocol definitions (name/value pairs)
+ @property
+ def Protocols(self):
+ if self._Protocols is None:
+ #
+ # tdict is a special kind of dict, used for selecting correct
+ # protocol definition for given ARCH
+ #
+ ProtocolDict = tdict(True)
+ PrivateProtocolDict = tdict(True)
+ NameList = []
+ PrivateNameList = []
+ PublicNameList = []
+ # find out all protocol definitions for specific and 'common' arch
+ RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]
+ for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
+ if PrivateFlag == 'PRIVATE':
+ if Name not in PrivateNameList:
+ PrivateNameList.append(Name)
+ PrivateProtocolDict[Arch, Name] = Guid
+ if Name in PublicNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
+ else:
+ if Name not in PublicNameList:
+ PublicNameList.append(Name)
+ if Name in PrivateNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
+ if Name not in NameList:
+ NameList.append(Name)
+ ProtocolDict[Arch, Name] = Guid
+ # use OrderedDict to keep the order
+ self._Protocols = OrderedDict()
+ self._PrivateProtocols = OrderedDict()
+ for Name in NameList:
+ #
+ # limit the ARCH to self._Arch, if no self._Arch found, tdict
+ # will automatically turn to 'common' ARCH for trying
+ #
+ self._Protocols[Name] = ProtocolDict[self._Arch, Name]
+ for Name in PrivateNameList:
+ self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]
+ return self._Protocols
+
+ ## Retrieve PPI definitions (name/value pairs)
+ @property
+ def Ppis(self):
+ if self._Ppis is None:
+ #
+ # tdict is a special kind of dict, used for selecting correct
+ # PPI definition for given ARCH
+ #
+ PpiDict = tdict(True)
+ PrivatePpiDict = tdict(True)
+ NameList = []
+ PrivateNameList = []
+ PublicNameList = []
+ # find out all PPI definitions for specific arch and 'common' arch
+ RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]
+ for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
+ if PrivateFlag == 'PRIVATE':
+ if Name not in PrivateNameList:
+ PrivateNameList.append(Name)
+ PrivatePpiDict[Arch, Name] = Guid
+ if Name in PublicNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
+ else:
+ if Name not in PublicNameList:
+ PublicNameList.append(Name)
+ if Name in PrivateNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
+ if Name not in NameList:
+ NameList.append(Name)
+ PpiDict[Arch, Name] = Guid
+ # use OrderedDict to keep the order
+ self._Ppis = OrderedDict()
+ self._PrivatePpis = OrderedDict()
+ for Name in NameList:
+ #
+ # limit the ARCH to self._Arch, if no self._Arch found, tdict
+ # will automatically turn to 'common' ARCH for trying
+ #
+ self._Ppis[Name] = PpiDict[self._Arch, Name]
+ for Name in PrivateNameList:
+ self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]
+ return self._Ppis
+
+ ## Retrieve GUID definitions (name/value pairs)
+ @property
+ def Guids(self):
+ if self._Guids is None:
+ #
+ # tdict is a special kind of dict, used for selecting correct
+ # GUID definition for given ARCH
+ #
+ GuidDict = tdict(True)
+ PrivateGuidDict = tdict(True)
+ NameList = []
+ PrivateNameList = []
+ PublicNameList = []
+ # find out all protocol definitions for specific and 'common' arch
+ RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]
+ for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
+ if PrivateFlag == 'PRIVATE':
+ if Name not in PrivateNameList:
+ PrivateNameList.append(Name)
+ PrivateGuidDict[Arch, Name] = Guid
+ if Name in PublicNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
+ else:
+ if Name not in PublicNameList:
+ PublicNameList.append(Name)
+ if Name in PrivateNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
+ if Name not in NameList:
+ NameList.append(Name)
+ GuidDict[Arch, Name] = Guid
+ # use OrderedDict to keep the order
+ self._Guids = OrderedDict()
+ self._PrivateGuids = OrderedDict()
+ for Name in NameList:
+ #
+ # limit the ARCH to self._Arch, if no self._Arch found, tdict
+ # will automatically turn to 'common' ARCH for trying
+ #
+ self._Guids[Name] = GuidDict[self._Arch, Name]
+ for Name in PrivateNameList:
+ self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]
+ return self._Guids
+
+ ## Retrieve public include paths declared in this package
+ @property
+ def Includes(self):
+ if self._Includes is None or self._CommonIncludes is None:
+ self._CommonIncludes = []
+ self._Includes = []
+ self._PrivateIncludes = []
+ PublicInclues = []
+ RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]
+ Macros = self._Macros
+ for Record in RecordList:
+ File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)
+ LineNo = Record[-1]
+ # validate the path
+ ErrorCode, ErrorInfo = File.Validate()
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
+
+ # avoid duplicate include path
+ if File not in self._Includes:
+ self._Includes.append(File)
+ if Record[4] == 'PRIVATE':
+ if File not in self._PrivateIncludes:
+ self._PrivateIncludes.append(File)
+ if File in PublicInclues:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
+ else:
+ if File not in PublicInclues:
+ PublicInclues.append(File)
+ if File in self._PrivateIncludes:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
+ if Record[3] == TAB_COMMON:
+ self._CommonIncludes.append(File)
+ return self._Includes
+
+ ## Retrieve library class declarations (not used in build at present)
+ @property
+ def LibraryClasses(self):
+ if self._LibraryClasses is None:
+ #
+ # tdict is a special kind of dict, used for selecting correct
+ # library class declaration for given ARCH
+ #
+ LibraryClassDict = tdict(True)
+ LibraryClassSet = set()
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]
+ Macros = self._Macros
+ for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
+ File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate()
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
+ LibraryClassSet.add(LibraryClass)
+ LibraryClassDict[Arch, LibraryClass] = File
+ self._LibraryClasses = OrderedDict()
+ for LibraryClass in LibraryClassSet:
+ self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]
+ return self._LibraryClasses
+
+ ## Retrieve PCD declarations
+ @property
+ def Pcds(self):
+ if self._Pcds is None:
+ self._Pcds = OrderedDict()
+ self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
+ self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
+ self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
+ self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))
+ self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))
+ return self._Pcds
+
+ def ParsePcdName(self,TokenCName):
+ TokenCName = TokenCName.strip()
+ if TokenCName.startswith("["):
+ if "." in TokenCName:
+ Demesionattr = TokenCName[:TokenCName.index(".")]
+ Fields = TokenCName[TokenCName.index(".")+1:]
+ else:
+ Demesionattr = TokenCName
+ Fields = ""
+ else:
+ Demesionattr = ""
+ Fields = TokenCName
+
+ return Demesionattr,Fields
+
+ def ProcessStructurePcd(self, StructurePcdRawDataSet):
+ s_pcd_set = OrderedDict()
+ for s_pcd, LineNo in StructurePcdRawDataSet:
+ if s_pcd.TokenSpaceGuidCName not in s_pcd_set:
+ s_pcd_set[s_pcd.TokenSpaceGuidCName] = []
+ s_pcd_set[s_pcd.TokenSpaceGuidCName].append((s_pcd, LineNo))
+
+ str_pcd_set = []
+ for pcdname in s_pcd_set:
+ dep_pkgs = []
+ struct_pcd = StructurePcd()
+ for item, LineNo in s_pcd_set[pcdname]:
+ if not item.TokenCName:
+ continue
+ if "<HeaderFiles>" in item.TokenCName:
+ struct_pcd.StructuredPcdIncludeFile.append(item.DefaultValue)
+ elif "<Packages>" in item.TokenCName:
+ dep_pkgs.append(item.DefaultValue)
+ elif item.DatumType == item.TokenCName:
+ struct_pcd.copy(item)
+ struct_pcd.TokenValue = struct_pcd.TokenValue.strip("{").strip()
+ struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName = pcdname.split(".")
+ struct_pcd.PcdDefineLineNo = LineNo
+ struct_pcd.PkgPath = self.MetaFile.File
+ struct_pcd.SetDecDefaultValue(item.DefaultValue,self.MetaFile.File,LineNo)
+ else:
+ DemesionAttr, Fields = self.ParsePcdName(item.TokenCName)
+ struct_pcd.AddDefaultValue(Fields, item.DefaultValue, self.MetaFile.File, LineNo,DemesionAttr)
+
+ struct_pcd.PackageDecs = dep_pkgs
+ str_pcd_set.append(struct_pcd)
+ return str_pcd_set
+
+ ## Retrieve PCD declarations for given type
+ def _GetPcd(self, Type):
+ Pcds = OrderedDict()
+ #
+ # tdict is a special kind of dict, used for selecting correct
+ # PCD declaration for given ARCH
+ #
+ PcdDict = tdict(True, 3)
+ # for summarizing PCD
+ PcdSet = []
+ # find out all PCDs of the 'type'
+
+ StrPcdSet = []
+ RecordList = self._RawData[Type, self._Arch]
+ for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:
+ PcdDict[Arch, PcdCName, TokenSpaceGuid] = (Setting, Dummy2)
+ if not (PcdCName, TokenSpaceGuid) in PcdSet:
+ PcdSet.append((PcdCName, TokenSpaceGuid))
+
+ DefinitionPosition = {}
+ for PcdCName, TokenSpaceGuid in PcdSet:
+ #
+ # limit the ARCH to self._Arch, if no self._Arch found, tdict
+ # will automatically turn to 'common' ARCH and try again
+ #
+ Setting, LineNo = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
+ if Setting is None:
+ continue
+
+ DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)
+ validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)
+ PcdObj = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ DatumType,
+ DefaultValue,
+ TokenNumber,
+ '',
+ {},
+ False,
+ None,
+ list(validateranges),
+ list(validlists),
+ list(expressions)
+ )
+ DefinitionPosition[PcdObj] = (self.MetaFile.File, LineNo)
+ if "." in TokenSpaceGuid:
+ StrPcdSet.append((PcdObj, LineNo))
+ else:
+ Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdObj
+
+ StructurePcds = self.ProcessStructurePcd(StrPcdSet)
+ for pcd in StructurePcds:
+ Pcds[pcd.TokenCName, pcd.TokenSpaceGuidCName, self._PCD_TYPE_STRING_[Type]] = pcd
+ StructPattern = compile(r'[_a-zA-Z][0-9A-Za-z_]*$')
+ for pcd in Pcds.values():
+ if pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
+ if not pcd.IsAggregateDatumType():
+ EdkLogger.error('build', FORMAT_INVALID, "DatumType only support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct name.", DefinitionPosition[pcd][0], DefinitionPosition[pcd][1])
+ elif not pcd.IsArray() and not pcd.StructuredPcdIncludeFile:
+ EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (pcd.TokenSpaceGuidCName, pcd.TokenCName, pcd.DefinitionPosition[0], pcd.DefinitionPosition[1] ))
+ return Pcds
+
+ @property
+ def CommonIncludes(self):
+ if self._CommonIncludes is None:
+ self.Includes
+ return self._CommonIncludes