Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1688 In order to support binary build, build tool add a flag to convert type of Dynamic Pcd to DynamicEx Pcd User can append -D PCD_DYNAMIC_AS_DYNAMICEX to build command to enable this function. Also, user can add "PCD_DYNAMIC_AS_DYNAMICEX = TRUE/FALSE" to the defines section of Dsc file to enable this function. PCD_DYNAMIC_AS_DYNAMICEX is a new reserved key word for this function. Signed-off-by: Bob Feng <bob.c.feng@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Yuwei Chen <yuwei.chen@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
		
			
				
	
	
		
			462 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			462 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| ## @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
 |