2017-11-24 14:30:11 +08:00
## @file
# This file is used to create a database used by build tool
#
2018-04-04 05:03:09 +08:00
# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
2017-11-24 14:30:11 +08:00
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
2019-04-03 16:03:11 -07:00
# SPDX-License-Identifier: BSD-2-Clause-Patent
2017-11-24 14:30:11 +08:00
#
2018-10-15 08:27:53 +08:00
from __future__ import absolute_import
2017-11-24 14:30:11 +08:00
from Common.DataType import *
from Common.Misc import *
2018-09-11 06:18:09 +08:00
from Common.caching import cached_property , cached_class_function
2017-11-24 14:30:11 +08:00
from types import *
2018-07-13 18:18:46 +08:00
from .MetaFileParser import *
2018-04-04 05:03:09 +08:00
from collections import OrderedDict
2017-11-24 14:30:11 +08:00
from Workspace.BuildClassObject import ModuleBuildClassObject , LibraryClassObject , PcdClassObject
2022-03-22 15:26:11 +08:00
from Common.Expression import ValueExpressionEx , PcdPattern
2018-09-11 06:18:09 +08:00
2019-01-11 02:39:46 +08:00
## Get Protocol value from given packages
#
# @param CName The CName of the GUID
# @param PackageList List of packages looking-up in
# @param Inffile The driver file
#
# @retval GuidValue if the CName is found in any given package
# @retval None if the CName is not found in all given packages
#
def _ProtocolValue ( CName , PackageList , Inffile = None ):
for P in PackageList :
2019-01-28 15:06:30 +08:00
ProtocolKeys = list ( P . Protocols . keys ())
2019-01-11 02:39:46 +08:00
if Inffile and P . _PrivateProtocols :
if not Inffile . startswith ( P . MetaFile . Dir ):
ProtocolKeys = [ x for x in P . Protocols if x not in P . _PrivateProtocols ]
if CName in ProtocolKeys :
return P . Protocols [ CName ]
return None
## Get PPI value from given packages
#
# @param CName The CName of the GUID
# @param PackageList List of packages looking-up in
# @param Inffile The driver file
#
# @retval GuidValue if the CName is found in any given package
# @retval None if the CName is not found in all given packages
#
def _PpiValue ( CName , PackageList , Inffile = None ):
for P in PackageList :
2019-01-28 15:06:30 +08:00
PpiKeys = list ( P . Ppis . keys ())
2019-01-11 02:39:46 +08:00
if Inffile and P . _PrivatePpis :
if not Inffile . startswith ( P . MetaFile . Dir ):
PpiKeys = [ x for x in P . Ppis if x not in P . _PrivatePpis ]
if CName in PpiKeys :
return P . Ppis [ CName ]
return None
2017-11-24 14:30:11 +08:00
## Module build information from INF file
#
# This class is used to retrieve information stored in database and convert them
# into ModuleBuildClassObject form for easier use for AutoGen.
#
class InfBuildData ( ModuleBuildClassObject ):
# dict used to convert part of [Defines] to members of InfBuildData directly
_PROPERTY_ = {
#
# Required Fields
#
TAB_INF_DEFINES_BASE_NAME : "_BaseName" ,
TAB_INF_DEFINES_FILE_GUID : "_Guid" ,
TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType" ,
#
# Optional Fields
#
# TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType" ,
TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName" ,
# TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
TAB_INF_DEFINES_DPX_SOURCE : "_DxsFile" ,
TAB_INF_DEFINES_VERSION_NUMBER : "_Version" ,
TAB_INF_DEFINES_VERSION_STRING : "_Version" ,
TAB_INF_DEFINES_VERSION : "_Version" ,
TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver" ,
2019-03-15 22:59:29 +08:00
TAB_INF_DEFINES_SHADOW : "_Shadow"
2017-11-24 14:30:11 +08:00
}
# regular expression for converting XXX_FLAGS in [nmake] section to new type
_NMAKE_FLAG_PATTERN_ = re . compile ( "(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?" , re . UNICODE )
# dict used to convert old tool name used in [nmake] section to new ones
_TOOL_CODE_ = {
"C" : "CC" ,
2018-04-27 00:57:56 +08:00
BINARY_FILE_TYPE_LIB : "SLINK" ,
2017-11-24 14:30:11 +08:00
"LINK" : "DLINK" ,
}
2018-09-11 06:18:09 +08:00
## Constructor of InfBuildData
2017-11-24 14:30:11 +08:00
#
2018-09-11 06:18:09 +08:00
# Initialize object of InfBuildData
2017-11-24 14:30:11 +08:00
#
# @param FilePath The path of platform description file
# @param RawData The raw data of DSC file
# @param BuildDataBase Database used to retrieve module/package information
# @param Arch The target architecture
# @param Platform The name of platform employing this module
# @param Macros Macros used for replacement in DSC file
#
2018-04-16 21:52:13 +08:00
def __init__ ( self , FilePath , RawData , BuildDatabase , Arch = TAB_ARCH_COMMON , Target = None , Toolchain = None ):
2017-11-24 14:30:11 +08:00
self . MetaFile = FilePath
self . _ModuleDir = FilePath . Dir
self . _RawData = RawData
self . _Bdb = BuildDatabase
self . _Arch = Arch
self . _Target = Target
self . _Toolchain = Toolchain
2018-04-16 21:52:13 +08:00
self . _Platform = TAB_COMMON
2018-09-11 06:18:09 +08:00
self . _BaseName = None
self . _DxsFile = None
self . _ModuleType = None
self . _ComponentType = None
self . _BuildType = None
self . _Guid = None
self . _Version = None
self . _PcdIsDriver = None
self . _Shadow = None
self . _MakefileName = None
self . _CustomMakefile = None
self . _Specification = None
self . _LibraryClass = None
self . _ModuleEntryPointList = None
self . _ModuleUnloadImageList = None
self . _ConstructorList = None
self . _DestructorList = None
self . _Defs = OrderedDict ()
self . _ProtocolComments = None
self . _PpiComments = None
self . _GuidsUsedByPcd = OrderedDict ()
self . _GuidComments = None
self . _PcdComments = None
self . _BuildOptions = None
self . _DependencyFileList = None
2021-06-08 10:31:55 +08:00
self . UpdatePcdTypeDict ()
2019-07-22 11:09:22 +08:00
self . LibInstances = []
self . ReferenceModules = set ()
2019-08-28 17:15:00 +08:00
2019-07-22 11:09:22 +08:00
def SetReferenceModule ( self , Module ):
self . ReferenceModules . add ( Module )
return self
2017-11-24 14:30:11 +08:00
## 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
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def _Macros ( self ):
2018-09-11 06:18:09 +08:00
RetVal = {}
return RetVal
2017-11-24 14:30:11 +08:00
## Get architecture
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Arch ( self ):
2017-11-24 14:30:11 +08:00
return self . _Arch
## Return the name of platform employing this module
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Platform ( self ):
2017-11-24 14:30:11 +08:00
return self . _Platform
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def HeaderComments ( self ):
2018-09-11 06:18:09 +08:00
return [ a [ 0 ] for a in self . _RawData [ MODEL_META_DATA_HEADER_COMMENT ]]
2018-09-11 06:18:05 +08:00
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def TailComments ( self ):
2018-09-11 06:18:09 +08:00
return [ a [ 0 ] for a in self . _RawData [ MODEL_META_DATA_TAIL_COMMENT ]]
2018-09-11 06:18:05 +08:00
2017-11-24 14:30:11 +08:00
## Retrieve all information in [Defines] section
#
2019-02-06 15:44:39 +08:00
# (Retrieving all [Defines] information in one-shot is just to save time.)
2017-11-24 14:30:11 +08:00
#
2018-09-11 06:18:09 +08:00
@cached_class_function
2017-11-24 14:30:11 +08:00
def _GetHeaderInfo ( self ):
RecordList = self . _RawData [ MODEL_META_DATA_HEADER , self . _Arch , self . _Platform ]
for Record in RecordList :
Name , Value = Record [ 1 ], ReplaceMacro ( Record [ 2 ], self . _Macros , False )
# items defined _PROPERTY_ don't need additional processing
if Name in self :
self [ Name ] = Value
self . _Defs [ Name ] = Value
self . _Macros [ Name ] = Value
# some special items in [Defines] section need special treatment
elif Name in ( 'EFI_SPECIFICATION_VERSION' , 'UEFI_SPECIFICATION_VERSION' , 'EDK_RELEASE_VERSION' , 'PI_SPECIFICATION_VERSION' ):
if Name in ( 'EFI_SPECIFICATION_VERSION' , 'UEFI_SPECIFICATION_VERSION' ):
Name = 'UEFI_SPECIFICATION_VERSION'
2018-03-27 04:25:43 +08:00
if self . _Specification is None :
2018-04-04 05:03:09 +08:00
self . _Specification = OrderedDict ()
2017-11-24 14:30:11 +08:00
self . _Specification [ Name ] = GetHexVerValue ( Value )
2018-03-27 04:25:43 +08:00
if self . _Specification [ Name ] is None :
2017-11-24 14:30:11 +08:00
EdkLogger . error ( "build" , FORMAT_NOT_SUPPORTED ,
"' %s ' format is not supported for %s " % ( Value , Name ),
File = self . MetaFile , Line = Record [ - 1 ])
elif Name == 'LIBRARY_CLASS' :
2018-03-27 04:25:43 +08:00
if self . _LibraryClass is None :
2017-11-24 14:30:11 +08:00
self . _LibraryClass = []
ValueList = GetSplitValueList ( Value )
LibraryClass = ValueList [ 0 ]
if len ( ValueList ) > 1 :
SupModuleList = GetSplitValueList ( ValueList [ 1 ], ' ' )
else :
SupModuleList = SUP_MODULE_LIST
self . _LibraryClass . append ( LibraryClassObject ( LibraryClass , SupModuleList ))
elif Name == 'ENTRY_POINT' :
2018-03-27 04:25:43 +08:00
if self . _ModuleEntryPointList is None :
2017-11-24 14:30:11 +08:00
self . _ModuleEntryPointList = []
self . _ModuleEntryPointList . append ( Value )
elif Name == 'UNLOAD_IMAGE' :
2018-03-27 04:25:43 +08:00
if self . _ModuleUnloadImageList is None :
2017-11-24 14:30:11 +08:00
self . _ModuleUnloadImageList = []
if not Value :
continue
self . _ModuleUnloadImageList . append ( Value )
elif Name == 'CONSTRUCTOR' :
2018-03-27 04:25:43 +08:00
if self . _ConstructorList is None :
2017-11-24 14:30:11 +08:00
self . _ConstructorList = []
if not Value :
continue
self . _ConstructorList . append ( Value )
elif Name == 'DESTRUCTOR' :
2018-03-27 04:25:43 +08:00
if self . _DestructorList is None :
2017-11-24 14:30:11 +08:00
self . _DestructorList = []
if not Value :
continue
self . _DestructorList . append ( Value )
elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE :
TokenList = GetSplitValueList ( Value )
2018-03-27 04:25:43 +08:00
if self . _CustomMakefile is None :
2017-11-24 14:30:11 +08:00
self . _CustomMakefile = {}
if len ( TokenList ) < 2 :
2018-08-25 00:33:17 +08:00
self . _CustomMakefile [ TAB_COMPILER_MSFT ] = TokenList [ 0 ]
2017-11-24 14:30:11 +08:00
self . _CustomMakefile [ 'GCC' ] = TokenList [ 0 ]
else :
2018-08-25 00:33:17 +08:00
if TokenList [ 0 ] not in [ TAB_COMPILER_MSFT , 'GCC' ]:
2017-11-24 14:30:11 +08:00
EdkLogger . error ( "build" , FORMAT_NOT_SUPPORTED ,
"No supported family [ %s ]" % TokenList [ 0 ],
File = self . MetaFile , Line = Record [ - 1 ])
self . _CustomMakefile [ TokenList [ 0 ]] = TokenList [ 1 ]
else :
self . _Defs [ Name ] = Value
self . _Macros [ Name ] = Value
#
# Retrieve information in sections specific to Edk.x modules
#
2019-01-14 09:24:12 +08:00
if not self . _ModuleType :
EdkLogger . error ( "build" , ATTRIBUTE_NOT_AVAILABLE ,
"MODULE_TYPE is not given" , File = self . MetaFile )
if self . _ModuleType not in SUP_MODULE_LIST :
RecordList = self . _RawData [ MODEL_META_DATA_HEADER , self . _Arch , self . _Platform ]
for Record in RecordList :
Name = Record [ 1 ]
if Name == "MODULE_TYPE" :
LineNo = Record [ 6 ]
break
EdkLogger . error ( "build" , FORMAT_NOT_SUPPORTED ,
"MODULE_TYPE %s is not supported for EDK II, valid values are: \n %s " % ( self . _ModuleType , ' ' . join ( l for l in SUP_MODULE_LIST )),
File = self . MetaFile , Line = LineNo )
if ( self . _Specification is None ) or ( not 'PI_SPECIFICATION_VERSION' in self . _Specification ) or ( int ( self . _Specification [ 'PI_SPECIFICATION_VERSION' ], 16 ) < 0x0001000A ):
if self . _ModuleType == SUP_MODULE_SMM_CORE :
EdkLogger . error ( "build" , FORMAT_NOT_SUPPORTED , "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A" , File = self . MetaFile )
if ( self . _Specification is None ) or ( not 'PI_SPECIFICATION_VERSION' in self . _Specification ) or ( int ( self . _Specification [ 'PI_SPECIFICATION_VERSION' ], 16 ) < 0x00010032 ):
if self . _ModuleType == SUP_MODULE_MM_CORE_STANDALONE :
EdkLogger . error ( "build" , FORMAT_NOT_SUPPORTED , "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032" , File = self . MetaFile )
if self . _ModuleType == SUP_MODULE_MM_STANDALONE :
EdkLogger . error ( "build" , FORMAT_NOT_SUPPORTED , "MM_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032" , File = self . MetaFile )
if 'PCI_DEVICE_ID' in self . _Defs and 'PCI_VENDOR_ID' in self . _Defs \
and 'PCI_CLASS_CODE' in self . _Defs and 'PCI_REVISION' in self . _Defs :
self . _BuildType = 'UEFI_OPTIONROM'
if 'PCI_COMPRESS' in self . _Defs :
if self . _Defs [ 'PCI_COMPRESS' ] not in ( 'TRUE' , 'FALSE' ):
EdkLogger . error ( "build" , FORMAT_INVALID , "Expected TRUE/FALSE for PCI_COMPRESS: %s " % self . MetaFile )
2017-11-24 14:30:11 +08:00
2019-01-14 09:24:12 +08:00
elif 'UEFI_HII_RESOURCE_SECTION' in self . _Defs \
and self . _Defs [ 'UEFI_HII_RESOURCE_SECTION' ] == 'TRUE' :
self . _BuildType = 'UEFI_HII'
2017-11-24 14:30:11 +08:00
else :
2019-01-14 09:24:12 +08:00
self . _BuildType = self . _ModuleType . upper ()
2017-11-24 14:30:11 +08:00
2019-01-14 09:24:12 +08:00
if self . _DxsFile :
File = PathClass ( NormPath ( self . _DxsFile ), self . _ModuleDir , Arch = self . _Arch )
# check the file validation
ErrorCode , ErrorInfo = File . Validate ( ".dxs" , CaseSensitive = False )
if ErrorCode != 0 :
EdkLogger . error ( 'build' , ErrorCode , ExtraData = ErrorInfo ,
File = self . MetaFile , Line = LineNo )
if not self . _DependencyFileList :
self . _DependencyFileList = []
self . _DependencyFileList . append ( File )
2017-11-24 14:30:11 +08:00
## Retrieve file version
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def AutoGenVersion ( self ):
2018-09-11 06:18:09 +08:00
RetVal = 0x00010000
RecordList = self . _RawData [ MODEL_META_DATA_HEADER , self . _Arch , self . _Platform ]
for Record in RecordList :
if Record [ 1 ] == TAB_INF_DEFINES_INF_VERSION :
if '.' in Record [ 2 ]:
ValueList = Record [ 2 ] . split ( '.' )
Major = ' %04o ' % int ( ValueList [ 0 ], 0 )
Minor = ' %04o ' % int ( ValueList [ 1 ], 0 )
RetVal = int ( '0x' + Major + Minor , 0 )
else :
RetVal = int ( Record [ 2 ], 0 )
break
return RetVal
2017-11-24 14:30:11 +08:00
## Retrieve BASE_NAME
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def BaseName ( self ):
2018-03-27 04:25:43 +08:00
if self . _BaseName is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _BaseName is None :
2017-11-24 14:30:11 +08:00
EdkLogger . error ( 'build' , ATTRIBUTE_NOT_AVAILABLE , "No BASE_NAME name" , File = self . MetaFile )
return self . _BaseName
## Retrieve DxsFile
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def DxsFile ( self ):
2018-03-27 04:25:43 +08:00
if self . _DxsFile is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _DxsFile is None :
2017-11-24 14:30:11 +08:00
self . _DxsFile = ''
return self . _DxsFile
## Retrieve MODULE_TYPE
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def ModuleType ( self ):
2018-03-27 04:25:43 +08:00
if self . _ModuleType is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _ModuleType is None :
2018-04-27 00:57:53 +08:00
self . _ModuleType = SUP_MODULE_BASE
2017-11-24 14:30:11 +08:00
if self . _ModuleType not in SUP_MODULE_LIST :
2018-04-27 00:57:53 +08:00
self . _ModuleType = SUP_MODULE_USER_DEFINED
2017-11-24 14:30:11 +08:00
return self . _ModuleType
## Retrieve COMPONENT_TYPE
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def ComponentType ( self ):
2018-03-27 04:25:43 +08:00
if self . _ComponentType is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _ComponentType is None :
2018-04-27 00:57:53 +08:00
self . _ComponentType = SUP_MODULE_USER_DEFINED
2017-11-24 14:30:11 +08:00
return self . _ComponentType
## Retrieve "BUILD_TYPE"
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def BuildType ( self ):
2018-03-27 04:25:43 +08:00
if self . _BuildType is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2017-11-24 14:30:11 +08:00
if not self . _BuildType :
2018-04-27 00:57:53 +08:00
self . _BuildType = SUP_MODULE_BASE
2017-11-24 14:30:11 +08:00
return self . _BuildType
## Retrieve file guid
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Guid ( self ):
2018-03-27 04:25:43 +08:00
if self . _Guid is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _Guid is None :
2017-11-24 14:30:11 +08:00
self . _Guid = '00000000-0000-0000-0000-000000000000'
return self . _Guid
## Retrieve module version
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Version ( self ):
2018-03-27 04:25:43 +08:00
if self . _Version is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _Version is None :
2017-11-24 14:30:11 +08:00
self . _Version = '0.0'
return self . _Version
## Retrieve PCD_IS_DRIVER
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def PcdIsDriver ( self ):
2018-03-27 04:25:43 +08:00
if self . _PcdIsDriver is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _PcdIsDriver is None :
2017-11-24 14:30:11 +08:00
self . _PcdIsDriver = ''
return self . _PcdIsDriver
## Retrieve SHADOW
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Shadow ( self ):
2018-03-27 04:25:43 +08:00
if self . _Shadow is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
if self . _Shadow and self . _Shadow . upper () == 'TRUE' :
2017-11-24 14:30:11 +08:00
self . _Shadow = True
else :
self . _Shadow = False
return self . _Shadow
## Retrieve CUSTOM_MAKEFILE
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def CustomMakefile ( self ):
2018-03-27 04:25:43 +08:00
if self . _CustomMakefile is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _CustomMakefile is None :
2017-11-24 14:30:11 +08:00
self . _CustomMakefile = {}
return self . _CustomMakefile
## Retrieve EFI_SPECIFICATION_VERSION
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Specification ( self ):
2018-03-27 04:25:43 +08:00
if self . _Specification is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _Specification is None :
2017-11-24 14:30:11 +08:00
self . _Specification = {}
return self . _Specification
## Retrieve LIBRARY_CLASS
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def LibraryClass ( self ):
2018-03-27 04:25:43 +08:00
if self . _LibraryClass is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _LibraryClass is None :
2017-11-24 14:30:11 +08:00
self . _LibraryClass = []
return self . _LibraryClass
## Retrieve ENTRY_POINT
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def ModuleEntryPointList ( self ):
2018-03-27 04:25:43 +08:00
if self . _ModuleEntryPointList is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _ModuleEntryPointList is None :
2017-11-24 14:30:11 +08:00
self . _ModuleEntryPointList = []
return self . _ModuleEntryPointList
## Retrieve UNLOAD_IMAGE
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def ModuleUnloadImageList ( self ):
2018-03-27 04:25:43 +08:00
if self . _ModuleUnloadImageList is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _ModuleUnloadImageList is None :
2017-11-24 14:30:11 +08:00
self . _ModuleUnloadImageList = []
return self . _ModuleUnloadImageList
## Retrieve CONSTRUCTOR
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def ConstructorList ( self ):
2018-03-27 04:25:43 +08:00
if self . _ConstructorList is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _ConstructorList is None :
2017-11-24 14:30:11 +08:00
self . _ConstructorList = []
return self . _ConstructorList
## Retrieve DESTRUCTOR
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def DestructorList ( self ):
2018-03-27 04:25:43 +08:00
if self . _DestructorList is None :
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2018-03-27 04:25:43 +08:00
if self . _DestructorList is None :
2017-11-24 14:30:11 +08:00
self . _DestructorList = []
return self . _DestructorList
## Retrieve definies other than above ones
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Defines ( self ):
2018-09-11 06:18:09 +08:00
self . _GetHeaderInfo ()
2017-11-24 14:30:11 +08:00
return self . _Defs
## Retrieve binary files
2018-09-11 06:18:09 +08:00
@cached_class_function
2017-11-24 14:30:11 +08:00
def _GetBinaries ( self ):
2018-09-11 06:18:09 +08:00
RetVal = []
RecordList = self . _RawData [ MODEL_EFI_BINARY_FILE , self . _Arch , self . _Platform ]
Macros = self . _Macros
Macros [ 'PROCESSOR' ] = self . _Arch
for Record in RecordList :
FileType = Record [ 0 ]
LineNo = Record [ - 1 ]
Target = TAB_COMMON
FeatureFlag = []
if Record [ 2 ]:
TokenList = GetSplitValueList ( Record [ 2 ], TAB_VALUE_SPLIT )
if TokenList :
Target = TokenList [ 0 ]
if len ( TokenList ) > 1 :
FeatureFlag = Record [ 1 :]
2017-11-24 14:30:11 +08:00
2018-09-11 06:18:09 +08:00
File = PathClass ( NormPath ( Record [ 1 ], Macros ), self . _ModuleDir , '' , FileType , True , self . _Arch , '' , Target )
# check the file validation
ErrorCode , ErrorInfo = File . Validate ()
if ErrorCode != 0 :
EdkLogger . error ( 'build' , ErrorCode , ExtraData = ErrorInfo , File = self . MetaFile , Line = LineNo )
RetVal . append ( File )
return RetVal
## Retrieve binary files with error check.
@cached_property
def Binaries ( self ):
RetVal = self . _GetBinaries ()
if GlobalData . gIgnoreSource and not RetVal :
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 )
return RetVal
## Retrieve source files
@cached_property
def Sources ( self ):
self . _GetHeaderInfo ()
# Ignore all source files in a binary build mode
if GlobalData . gIgnoreSource :
return []
RetVal = []
RecordList = self . _RawData [ MODEL_EFI_SOURCE_FILE , self . _Arch , self . _Platform ]
Macros = self . _Macros
for Record in RecordList :
LineNo = Record [ - 1 ]
ToolChainFamily = Record [ 1 ]
2022-03-22 15:26:11 +08:00
# OptionsList := [TagName, ToolCode, FeatureFlag]
OptionsList = [ '' , '' , '' ]
TokenList = GetSplitValueList ( Record [ 2 ], TAB_VALUE_SPLIT )
for Index in range ( len ( TokenList )):
OptionsList [ Index ] = TokenList [ Index ]
if OptionsList [ 2 ]:
FeaturePcdExpression = self . CheckFeatureFlagPcd ( OptionsList [ 2 ])
if not FeaturePcdExpression :
continue
2019-01-14 09:24:12 +08:00
File = PathClass ( NormPath ( Record [ 0 ], Macros ), self . _ModuleDir , '' ,
2022-03-22 15:26:11 +08:00
'' , False , self . _Arch , ToolChainFamily , '' , OptionsList [ 0 ], OptionsList [ 1 ])
2019-01-14 09:24:12 +08:00
# check the file validation
ErrorCode , ErrorInfo = File . Validate ()
if ErrorCode != 0 :
EdkLogger . error ( 'build' , ErrorCode , ExtraData = ErrorInfo , File = self . MetaFile , Line = LineNo )
2017-11-24 14:30:11 +08:00
2018-09-11 06:18:09 +08:00
RetVal . append ( File )
# add any previously found dependency files to the source list
if self . _DependencyFileList :
RetVal . extend ( self . _DependencyFileList )
return RetVal
2017-11-24 14:30:11 +08:00
## Retrieve library classes employed by this module
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def LibraryClasses ( self ):
2018-09-11 06:18:09 +08:00
RetVal = OrderedDict ()
RecordList = self . _RawData [ MODEL_EFI_LIBRARY_CLASS , self . _Arch , self . _Platform ]
for Record in RecordList :
Lib = Record [ 0 ]
Instance = Record [ 1 ]
if Instance :
Instance = NormPath ( Instance , self . _Macros )
2018-11-08 18:16:25 +08:00
RetVal [ Lib ] = Instance
else :
RetVal [ Lib ] = None
2018-09-11 06:18:09 +08:00
return RetVal
2017-11-24 14:30:11 +08:00
## Retrieve library names (for Edk.x style of modules)
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Libraries ( self ):
2018-09-11 06:18:09 +08:00
RetVal = []
RecordList = self . _RawData [ MODEL_EFI_LIBRARY_INSTANCE , self . _Arch , self . _Platform ]
for Record in RecordList :
LibraryName = ReplaceMacro ( Record [ 0 ], self . _Macros , False )
# in case of name with '.lib' extension, which is unusual in Edk.x inf
LibraryName = os . path . splitext ( LibraryName )[ 0 ]
if LibraryName not in RetVal :
RetVal . append ( LibraryName )
return RetVal
2017-11-24 14:30:11 +08:00
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def ProtocolComments ( self ):
self . Protocols
2017-11-24 14:30:11 +08:00
return self . _ProtocolComments
2018-09-11 06:18:05 +08:00
2017-11-24 14:30:11 +08:00
## Retrieve protocols consumed/produced by this module
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Protocols ( self ):
2018-09-11 06:18:09 +08:00
RetVal = OrderedDict ()
self . _ProtocolComments = OrderedDict ()
RecordList = self . _RawData [ MODEL_EFI_PROTOCOL , self . _Arch , self . _Platform ]
for Record in RecordList :
CName = Record [ 0 ]
2024-03-12 14:18:14 -07:00
Value = _ProtocolValue ( CName , self . Packages , self . MetaFile . OriginalPath . Path )
2018-09-11 06:18:09 +08:00
if Value is None :
PackageList = " \n\t " . join ( str ( P ) for P in self . Packages )
EdkLogger . error ( 'build' , RESOURCE_NOT_AVAILABLE ,
"Value of Protocol [ %s ] is not found under [Protocols] section in" % CName ,
ExtraData = PackageList , File = self . MetaFile , Line = Record [ - 1 ])
RetVal [ CName ] = Value
CommentRecords = self . _RawData [ MODEL_META_DATA_COMMENT , self . _Arch , self . _Platform , Record [ 5 ]]
self . _ProtocolComments [ CName ] = [ a [ 0 ] for a in CommentRecords ]
return RetVal
2017-11-24 14:30:11 +08:00
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def PpiComments ( self ):
self . Ppis
2017-11-24 14:30:11 +08:00
return self . _PpiComments
2018-09-11 06:18:05 +08:00
2017-11-24 14:30:11 +08:00
## Retrieve PPIs consumed/produced by this module
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Ppis ( self ):
2018-09-11 06:18:09 +08:00
RetVal = OrderedDict ()
self . _PpiComments = OrderedDict ()
RecordList = self . _RawData [ MODEL_EFI_PPI , self . _Arch , self . _Platform ]
for Record in RecordList :
CName = Record [ 0 ]
2024-03-12 14:18:14 -07:00
Value = _PpiValue ( CName , self . Packages , self . MetaFile . OriginalPath . Path )
2018-09-11 06:18:09 +08:00
if Value is None :
PackageList = " \n\t " . join ( str ( P ) for P in self . Packages )
EdkLogger . error ( 'build' , RESOURCE_NOT_AVAILABLE ,
"Value of PPI [ %s ] is not found under [Ppis] section in " % CName ,
ExtraData = PackageList , File = self . MetaFile , Line = Record [ - 1 ])
RetVal [ CName ] = Value
CommentRecords = self . _RawData [ MODEL_META_DATA_COMMENT , self . _Arch , self . _Platform , Record [ 5 ]]
self . _PpiComments [ CName ] = [ a [ 0 ] for a in CommentRecords ]
return RetVal
2017-11-24 14:30:11 +08:00
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def GuidComments ( self ):
self . Guids
2017-11-24 14:30:11 +08:00
return self . _GuidComments
2018-09-11 06:18:05 +08:00
2017-11-24 14:30:11 +08:00
## Retrieve GUIDs consumed/produced by this module
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Guids ( self ):
2018-09-11 06:18:09 +08:00
RetVal = OrderedDict ()
self . _GuidComments = OrderedDict ()
RecordList = self . _RawData [ MODEL_EFI_GUID , self . _Arch , self . _Platform ]
for Record in RecordList :
CName = Record [ 0 ]
2024-03-12 14:18:14 -07:00
Value = GuidValue ( CName , self . Packages , self . MetaFile . OriginalPath . Path )
2018-09-11 06:18:09 +08:00
if Value is None :
PackageList = " \n\t " . join ( str ( P ) for P in self . Packages )
EdkLogger . error ( 'build' , RESOURCE_NOT_AVAILABLE ,
"Value of Guid [ %s ] is not found under [Guids] section in" % CName ,
ExtraData = PackageList , File = self . MetaFile , Line = Record [ - 1 ])
RetVal [ CName ] = Value
CommentRecords = self . _RawData [ MODEL_META_DATA_COMMENT , self . _Arch , self . _Platform , Record [ 5 ]]
self . _GuidComments [ CName ] = [ a [ 0 ] for a in CommentRecords ]
2019-08-28 17:15:00 +08:00
for Type in [ MODEL_PCD_FIXED_AT_BUILD , MODEL_PCD_PATCHABLE_IN_MODULE , MODEL_PCD_FEATURE_FLAG , MODEL_PCD_DYNAMIC , MODEL_PCD_DYNAMIC_EX ]:
RecordList = self . _RawData [ Type , self . _Arch , self . _Platform ]
for TokenSpaceGuid , _ , _ , _ , _ , _ , LineNo in RecordList :
# get the guid value
if TokenSpaceGuid not in RetVal :
2024-03-12 14:18:14 -07:00
Value = GuidValue ( TokenSpaceGuid , self . Packages , self . MetaFile . OriginalPath . Path )
2019-08-28 17:15:00 +08:00
if Value is None :
PackageList = " \n\t " . join ( str ( P ) for P in self . Packages )
EdkLogger . error ( 'build' , RESOURCE_NOT_AVAILABLE ,
"Value of Guid [ %s ] is not found under [Guids] section in" % TokenSpaceGuid ,
ExtraData = PackageList , File = self . MetaFile , Line = LineNo )
RetVal [ TokenSpaceGuid ] = Value
self . _GuidsUsedByPcd [ TokenSpaceGuid ] = Value
2018-09-11 06:18:09 +08:00
return RetVal
2017-11-24 14:30:11 +08:00
## Retrieve include paths necessary for this module (for Edk.x style of modules)
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Includes ( self ):
2018-09-11 06:18:09 +08:00
RetVal = []
Macros = self . _Macros
Macros [ 'PROCESSOR' ] = GlobalData . gEdkGlobal . get ( 'PROCESSOR' , self . _Arch )
RecordList = self . _RawData [ MODEL_EFI_INCLUDE , self . _Arch , self . _Platform ]
for Record in RecordList :
2019-01-15 18:14:04 +08:00
File = NormPath ( Record [ 0 ], Macros )
if File [ 0 ] == '.' :
File = os . path . join ( self . _ModuleDir , File )
2018-09-11 06:18:09 +08:00
else :
2019-01-15 18:14:04 +08:00
File = mws . join ( GlobalData . gWorkspace , File )
File = RealPath ( os . path . normpath ( File ))
if File :
RetVal . append ( File )
2018-09-11 06:18:09 +08:00
return RetVal
2017-11-24 14:30:11 +08:00
## Retrieve packages this module depends on
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Packages ( self ):
2018-09-11 06:18:09 +08:00
RetVal = []
RecordList = self . _RawData [ MODEL_META_DATA_PACKAGE , self . _Arch , self . _Platform ]
Macros = self . _Macros
for Record in RecordList :
File = PathClass ( NormPath ( Record [ 0 ], Macros ), GlobalData . gWorkspace , Arch = self . _Arch )
# check the file validation
ErrorCode , ErrorInfo = File . Validate ( '.dec' )
if ErrorCode != 0 :
2017-11-24 14:30:11 +08:00
LineNo = Record [ - 1 ]
2018-09-11 06:18:09 +08:00
EdkLogger . error ( 'build' , ErrorCode , ExtraData = ErrorInfo , File = self . MetaFile , Line = LineNo )
# parse this package now. we need it to get protocol/ppi/guid value
RetVal . append ( self . _Bdb [ File , self . _Arch , self . _Target , self . _Toolchain ])
return RetVal
2017-11-24 14:30:11 +08:00
## Retrieve PCD comments
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def PcdComments ( self ):
self . Pcds
2017-11-24 14:30:11 +08:00
return self . _PcdComments
2018-09-11 06:18:05 +08:00
2017-11-24 14:30:11 +08:00
## Retrieve PCDs used in this module
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Pcds ( self ):
2018-09-11 06:18:09 +08:00
self . _PcdComments = OrderedDict ()
RetVal = OrderedDict ()
RetVal . update ( self . _GetPcd ( MODEL_PCD_FIXED_AT_BUILD ))
RetVal . update ( self . _GetPcd ( MODEL_PCD_PATCHABLE_IN_MODULE ))
RetVal . update ( self . _GetPcd ( MODEL_PCD_FEATURE_FLAG ))
RetVal . update ( self . _GetPcd ( MODEL_PCD_DYNAMIC ))
RetVal . update ( self . _GetPcd ( MODEL_PCD_DYNAMIC_EX ))
return RetVal
2017-11-24 14:30:11 +08:00
2018-11-01 22:57:08 +08:00
@cached_property
2019-07-22 11:09:22 +08:00
def ModulePcdList ( self ):
RetVal = self . Pcds
return RetVal
@cached_property
def LibraryPcdList ( self ):
if bool ( self . LibraryClass ):
return []
RetVal = {}
Pcds = set ()
for Library in self . LibInstances :
PcdsInLibrary = OrderedDict ()
for Key in Library . Pcds :
if Key in self . Pcds or Key in Pcds :
continue
Pcds . add ( Key )
PcdsInLibrary [ Key ] = copy . copy ( Library . Pcds [ Key ])
RetVal [ Library ] = PcdsInLibrary
return RetVal
@cached_property
2018-11-01 22:57:08 +08:00
def PcdsName ( self ):
PcdsName = set ()
for Type in ( MODEL_PCD_FIXED_AT_BUILD , MODEL_PCD_PATCHABLE_IN_MODULE , MODEL_PCD_FEATURE_FLAG , MODEL_PCD_DYNAMIC , MODEL_PCD_DYNAMIC_EX ):
RecordList = self . _RawData [ Type , self . _Arch , self . _Platform ]
for TokenSpaceGuid , PcdCName , _ , _ , _ , _ , _ in RecordList :
PcdsName . add (( PcdCName , TokenSpaceGuid ))
return PcdsName
2017-11-24 14:30:11 +08:00
## Retrieve build options specific to this module
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def BuildOptions ( self ):
2018-03-27 04:25:43 +08:00
if self . _BuildOptions is None :
2018-04-04 05:03:09 +08:00
self . _BuildOptions = OrderedDict ()
2017-11-24 14:30:11 +08:00
RecordList = self . _RawData [ MODEL_META_DATA_BUILD_OPTION , self . _Arch , self . _Platform ]
for Record in RecordList :
ToolChainFamily = Record [ 0 ]
ToolChain = Record [ 1 ]
Option = Record [ 2 ]
if ( ToolChainFamily , ToolChain ) not in self . _BuildOptions or Option . startswith ( '=' ):
self . _BuildOptions [ ToolChainFamily , ToolChain ] = Option
else :
# concatenate the option string if they're for the same tool
OptionString = self . _BuildOptions [ ToolChainFamily , ToolChain ]
self . _BuildOptions [ ToolChainFamily , ToolChain ] = OptionString + " " + Option
return self . _BuildOptions
## Retrieve dependency expression
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def Depex ( self ):
2018-09-11 06:18:09 +08:00
RetVal = tdict ( False , 2 )
2017-11-24 14:30:11 +08:00
2018-09-11 06:18:09 +08:00
# If the module has only Binaries and no Sources, then ignore [Depex]
if not self . Sources and self . Binaries :
return RetVal
2017-11-24 14:30:11 +08:00
2018-09-11 06:18:09 +08:00
RecordList = self . _RawData [ MODEL_EFI_DEPEX , self . _Arch ]
# PEIM and DXE drivers must have a valid [Depex] section
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 \
2025-09-23 16:37:43 +05:30
self . ModuleType == SUP_MODULE_DXE_RUNTIME_DRIVER :
2018-09-11 06:18:09 +08:00
EdkLogger . error ( 'build' , RESOURCE_NOT_AVAILABLE , "No [Depex] section or no valid expression in [Depex] section for [ %s ] module" \
% self . ModuleType , File = self . MetaFile )
2017-11-24 14:30:11 +08:00
2019-07-01 06:19:13 +00:00
if len ( RecordList ) != 0 and ( self . ModuleType == SUP_MODULE_USER_DEFINED or self . ModuleType == SUP_MODULE_HOST_APPLICATION ):
2017-11-24 14:30:11 +08:00
for Record in RecordList :
2018-09-11 06:18:09 +08:00
if Record [ 4 ] not in [ SUP_MODULE_PEIM , SUP_MODULE_DXE_DRIVER , SUP_MODULE_DXE_SMM_DRIVER ]:
EdkLogger . error ( 'build' , FORMAT_INVALID ,
"' %s ' module must specify the type of [Depex] section" % self . ModuleType ,
File = self . MetaFile )
2018-07-13 17:05:20 +08:00
2018-09-11 06:18:09 +08:00
TemporaryDictionary = OrderedDict ()
for Record in RecordList :
DepexStr = ReplaceMacro ( Record [ 0 ], self . _Macros , False )
Arch = Record [ 3 ]
ModuleType = Record [ 4 ]
TokenList = DepexStr . split ()
if ( Arch , ModuleType ) not in TemporaryDictionary :
TemporaryDictionary [ Arch , ModuleType ] = []
DepexList = TemporaryDictionary [ Arch , ModuleType ]
for Token in TokenList :
if Token in DEPEX_SUPPORTED_OPCODE_SET :
DepexList . append ( Token )
elif Token . endswith ( ".inf" ): # module file name
ModuleFile = os . path . normpath ( Token )
Module = self . BuildDatabase [ ModuleFile ]
if Module is None :
EdkLogger . error ( 'build' , RESOURCE_NOT_AVAILABLE , "Module is not found in active platform" ,
ExtraData = Token , File = self . MetaFile , Line = Record [ - 1 ])
DepexList . append ( Module . Guid )
else :
# it use the Fixed PCD format
if '.' in Token :
if tuple ( Token . split ( '.' )[:: - 1 ]) not in self . Pcds :
EdkLogger . error ( 'build' , RESOURCE_NOT_AVAILABLE , "PCD [ {} ] used in [Depex] section should be listed in module PCD section" . format ( Token ), File = self . MetaFile , Line = Record [ - 1 ])
else :
if self . Pcds [ tuple ( Token . split ( '.' )[:: - 1 ])] . DatumType != TAB_VOID :
EdkLogger . error ( 'build' , FORMAT_INVALID , "PCD [ {} ] used in [Depex] section should be VOID* datum type" . format ( Token ), File = self . MetaFile , Line = Record [ - 1 ])
Value = Token
else :
# get the GUID value now
2024-03-12 14:18:14 -07:00
Value = _ProtocolValue ( Token , self . Packages , self . MetaFile . OriginalPath . Path )
2018-03-27 04:25:43 +08:00
if Value is None :
2024-03-12 14:18:14 -07:00
Value = _PpiValue ( Token , self . Packages , self . MetaFile . OriginalPath . Path )
2018-09-11 06:18:09 +08:00
if Value is None :
2024-03-12 14:18:14 -07:00
Value = GuidValue ( Token , self . Packages , self . MetaFile . OriginalPath . Path )
2018-09-11 06:18:09 +08:00
if Value is None :
PackageList = " \n\t " . join ( str ( P ) for P in self . Packages )
EdkLogger . error ( 'build' , RESOURCE_NOT_AVAILABLE ,
"Value of [ %s ] is not found in" % Token ,
ExtraData = PackageList , File = self . MetaFile , Line = Record [ - 1 ])
DepexList . append ( Value )
for Arch , ModuleType in TemporaryDictionary :
RetVal [ Arch , ModuleType ] = TemporaryDictionary [ Arch , ModuleType ]
return RetVal
2017-11-24 14:30:11 +08:00
2019-02-06 15:44:39 +08:00
## Retrieve dependency expression
2018-09-11 06:18:09 +08:00
@cached_property
2018-09-11 06:18:05 +08:00
def DepexExpression ( self ):
2018-09-11 06:18:09 +08:00
RetVal = tdict ( False , 2 )
RecordList = self . _RawData [ MODEL_EFI_DEPEX , self . _Arch ]
TemporaryDictionary = OrderedDict ()
for Record in RecordList :
DepexStr = ReplaceMacro ( Record [ 0 ], self . _Macros , False )
Arch = Record [ 3 ]
ModuleType = Record [ 4 ]
TokenList = DepexStr . split ()
if ( Arch , ModuleType ) not in TemporaryDictionary :
TemporaryDictionary [ Arch , ModuleType ] = ''
for Token in TokenList :
TemporaryDictionary [ Arch , ModuleType ] = TemporaryDictionary [ Arch , ModuleType ] + Token . strip () + ' '
for Arch , ModuleType in TemporaryDictionary :
RetVal [ Arch , ModuleType ] = TemporaryDictionary [ Arch , ModuleType ]
return RetVal
2019-05-27 22:19:25 +08:00
def LocalPkg ( self ):
module_path = self . MetaFile . File
subdir = os . path . split ( module_path )[ 0 ]
TopDir = ""
while subdir :
subdir , TopDir = os . path . split ( subdir )
2017-11-24 14:30:11 +08:00
2019-05-27 22:19:25 +08:00
for file_name in os . listdir ( os . path . join ( self . MetaFile . Root , TopDir )):
if file_name . upper () . endswith ( "DEC" ):
pkg = os . path . join ( TopDir , file_name )
return pkg
2018-09-11 06:18:09 +08:00
@cached_class_function
2017-11-24 14:30:11 +08:00
def GetGuidsUsedByPcd ( self ):
2019-08-28 17:15:00 +08:00
self . Guid
2017-11-24 14:30:11 +08:00
return self . _GuidsUsedByPcd
2018-09-11 06:18:05 +08:00
2017-11-24 14:30:11 +08:00
## Retrieve PCD for given type
def _GetPcd ( self , Type ):
2018-04-04 05:03:09 +08:00
Pcds = OrderedDict ()
2017-11-24 14:30:11 +08:00
PcdDict = tdict ( True , 4 )
PcdList = []
RecordList = self . _RawData [ Type , self . _Arch , self . _Platform ]
for TokenSpaceGuid , PcdCName , Setting , Arch , Platform , Id , LineNo in RecordList :
PcdDict [ Arch , Platform , PcdCName , TokenSpaceGuid ] = ( Setting , LineNo )
PcdList . append (( PcdCName , TokenSpaceGuid ))
CommentRecords = self . _RawData [ MODEL_META_DATA_COMMENT , self . _Arch , self . _Platform , Id ]
Comments = []
for CmtRec in CommentRecords :
Comments . append ( CmtRec [ 0 ])
self . _PcdComments [ TokenSpaceGuid , PcdCName ] = Comments
# resolve PCD type, value, datum info, etc. by getting its definition from package
2018-04-13 13:20:31 +08:00
_GuidDict = self . Guids . copy ()
2017-11-24 14:30:11 +08:00
for PcdCName , TokenSpaceGuid in PcdList :
PcdRealName = PcdCName
Setting , LineNo = PcdDict [ self . _Arch , self . Platform , PcdCName , TokenSpaceGuid ]
2018-03-27 04:25:43 +08:00
if Setting is None :
2017-11-24 14:30:11 +08:00
continue
ValueList = AnalyzePcdData ( Setting )
DefaultValue = ValueList [ 0 ]
Pcd = PcdClassObject (
PcdCName ,
TokenSpaceGuid ,
'' ,
'' ,
DefaultValue ,
'' ,
'' ,
{},
False ,
self . Guids [ TokenSpaceGuid ]
)
if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList [ 1 ]:
# Patch PCD: TokenSpace.PcdCName|Value|Offset
Pcd . Offset = ValueList [ 1 ]
if ( PcdRealName , TokenSpaceGuid ) in GlobalData . MixedPcd :
for Package in self . Packages :
for key in Package . Pcds :
if ( Package . Pcds [ key ] . TokenCName , Package . Pcds [ key ] . TokenSpaceGuidCName ) == ( PcdRealName , TokenSpaceGuid ):
for item in GlobalData . MixedPcd [( PcdRealName , TokenSpaceGuid )]:
Pcd_Type = item [ 0 ] . split ( '_' )[ - 1 ]
if Pcd_Type == Package . Pcds [ key ] . Type :
Value = Package . Pcds [ key ]
Value . TokenCName = Package . Pcds [ key ] . TokenCName + '_' + Pcd_Type
if len ( key ) == 2 :
newkey = ( Value . TokenCName , key [ 1 ])
elif len ( key ) == 3 :
newkey = ( Value . TokenCName , key [ 1 ], key [ 2 ])
del Package . Pcds [ key ]
Package . Pcds [ newkey ] = Value
break
else :
pass
else :
pass
# get necessary info from package declaring this PCD
for Package in self . Packages :
#
# 'dynamic' in INF means its type is determined by platform;
# if platform doesn't give its type, use 'lowest' one in the
# following order, if any
#
2018-04-27 00:57:55 +08:00
# TAB_PCDS_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE, TAB_PCDS_FEATURE_FLAG, TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_EX
2017-11-24 14:30:11 +08:00
#
2018-04-13 13:20:31 +08:00
_GuidDict . update ( Package . Guids )
2017-11-24 14:30:11 +08:00
PcdType = self . _PCD_TYPE_STRING_ [ Type ]
if Type == MODEL_PCD_DYNAMIC :
Pcd . Pending = True
2018-04-27 00:57:55 +08:00
for T in PCD_TYPE_LIST :
2017-11-24 14:30:11 +08:00
if ( PcdRealName , TokenSpaceGuid ) in GlobalData . MixedPcd :
for item in GlobalData . MixedPcd [( PcdRealName , TokenSpaceGuid )]:
if str ( item [ 0 ]) . endswith ( T ) and ( item [ 0 ], item [ 1 ], T ) in Package . Pcds :
PcdType = T
PcdCName = item [ 0 ]
break
else :
pass
break
else :
if ( PcdRealName , TokenSpaceGuid , T ) in Package . Pcds :
PcdType = T
break
else :
Pcd . Pending = False
if ( PcdRealName , TokenSpaceGuid ) in GlobalData . MixedPcd :
for item in GlobalData . MixedPcd [( PcdRealName , TokenSpaceGuid )]:
Pcd_Type = item [ 0 ] . split ( '_' )[ - 1 ]
if Pcd_Type == PcdType :
PcdCName = item [ 0 ]
break
else :
pass
else :
pass
if ( PcdCName , TokenSpaceGuid , PcdType ) in Package . Pcds :
PcdInPackage = Package . Pcds [ PcdCName , TokenSpaceGuid , PcdType ]
Pcd . Type = PcdType
Pcd . TokenValue = PcdInPackage . TokenValue
#
# Check whether the token value exist or not.
#
2018-03-27 04:25:43 +08:00
if Pcd . TokenValue is None or Pcd . TokenValue == "" :
2017-11-24 14:30:11 +08:00
EdkLogger . error (
'build' ,
FORMAT_INVALID ,
"No TokenValue for PCD [ %s . %s ] in [ %s ]!" % ( TokenSpaceGuid , PcdRealName , str ( Package )),
File = self . MetaFile , Line = LineNo ,
ExtraData = None
)
#
# Check hexadecimal token value length and format.
#
ReIsValidPcdTokenValue = re . compile ( r "^[0][x|X][0]*[0-9a-fA-F]{1,8}$" , re . DOTALL )
if Pcd . TokenValue . startswith ( "0x" ) or Pcd . TokenValue . startswith ( "0X" ):
2018-03-27 04:25:43 +08:00
if ReIsValidPcdTokenValue . match ( Pcd . TokenValue ) is None :
2017-11-24 14:30:11 +08:00
EdkLogger . error (
'build' ,
FORMAT_INVALID ,
"The format of TokenValue [ %s ] of PCD [ %s . %s ] in [ %s ] is invalid:" % ( Pcd . TokenValue , TokenSpaceGuid , PcdRealName , str ( Package )),
File = self . MetaFile , Line = LineNo ,
ExtraData = None
)
#
# Check decimal token value length and format.
#
else :
try :
TokenValueInt = int ( Pcd . TokenValue , 10 )
if ( TokenValueInt < 0 or TokenValueInt > 4294967295 ):
EdkLogger . error (
'build' ,
FORMAT_INVALID ,
"The format of TokenValue [ %s ] of PCD [ %s . %s ] in [ %s ] is invalid, as a decimal it should between: 0 - 4294967295!" % ( Pcd . TokenValue , TokenSpaceGuid , PcdRealName , str ( Package )),
File = self . MetaFile , Line = LineNo ,
ExtraData = None
)
except :
EdkLogger . error (
'build' ,
FORMAT_INVALID ,
"The format of TokenValue [ %s ] of PCD [ %s . %s ] in [ %s ] is invalid, it should be hexadecimal or decimal!" % ( Pcd . TokenValue , TokenSpaceGuid , PcdRealName , str ( Package )),
File = self . MetaFile , Line = LineNo ,
ExtraData = None
)
Pcd . DatumType = PcdInPackage . DatumType
Pcd . MaxDatumSize = PcdInPackage . MaxDatumSize
Pcd . InfDefaultValue = Pcd . DefaultValue
2018-04-20 23:51:42 +08:00
if not Pcd . DefaultValue :
2017-11-24 14:30:11 +08:00
Pcd . DefaultValue = PcdInPackage . DefaultValue
2017-12-26 16:17:13 +08:00
else :
try :
2018-04-13 13:20:31 +08:00
Pcd . DefaultValue = ValueExpressionEx ( Pcd . DefaultValue , Pcd . DatumType , _GuidDict )( True )
2018-06-25 18:31:25 +08:00
except BadExpression as Value :
2017-12-26 16:17:13 +08:00
EdkLogger . error ( 'Parser' , FORMAT_INVALID , 'PCD [ %s . %s ] Value " %s ", %s ' % ( TokenSpaceGuid , PcdRealName , Pcd . DefaultValue , Value ),
File = self . MetaFile , Line = LineNo )
2017-11-24 14:30:11 +08:00
break
else :
EdkLogger . error (
'build' ,
FORMAT_INVALID ,
"PCD [ %s . %s ] in [ %s ] is not found in dependent packages:" % ( TokenSpaceGuid , PcdRealName , self . MetaFile ),
File = self . MetaFile , Line = LineNo ,
2018-04-28 06:32:54 +08:00
ExtraData = " \t %s " % ' \n\t ' . join ( str ( P ) for P in self . Packages )
2017-11-24 14:30:11 +08:00
)
Pcds [ PcdCName , TokenSpaceGuid ] = Pcd
return Pcds
## check whether current module is binary module
2018-09-11 06:18:05 +08:00
@property
def IsBinaryModule ( self ):
if ( self . Binaries and not self . Sources ) or GlobalData . gIgnoreSource :
2017-11-24 14:30:11 +08:00
return True
2018-09-11 06:18:05 +08:00
return False
2022-03-22 15:26:11 +08:00
def CheckFeatureFlagPcd ( self , Instance ):
2022-04-18 16:15:21 +08:00
Pcds = GlobalData . gPlatformFinalPcds . copy ()
2022-03-22 15:26:11 +08:00
if PcdPattern . search ( Instance ):
PcdTuple = tuple ( Instance . split ( '.' )[:: - 1 ])
if PcdTuple in self . Pcds :
2022-04-18 16:15:21 +08:00
if not ( self . Pcds [ PcdTuple ] . Type == 'FeatureFlag' or self . Pcds [ PcdTuple ] . Type == 'FixedAtBuild' ):
2022-03-22 15:26:11 +08:00
EdkLogger . error ( 'build' , FORMAT_INVALID ,
2022-04-18 16:15:21 +08:00
" \n FeatureFlagPcd must be defined in a [PcdsFeatureFlag] or [PcdsFixedAtBuild] section of Dsc or Dec file" ,
2022-03-22 15:26:11 +08:00
File = str ( self ), ExtraData = Instance )
2022-04-18 16:15:21 +08:00
if not Instance in Pcds :
Pcds [ Instance ] = self . Pcds [ PcdTuple ] . DefaultValue
else : #if PcdTuple not in self.Pcds:
EdkLogger . error ( 'build' , FORMAT_INVALID ,
" \n FeatureFlagPcd must be defined in [FeaturePcd] or [FixedPcd] of Inf file" ,
File = str ( self ), ExtraData = Instance )
2022-03-22 15:26:11 +08:00
if Instance in Pcds :
if Pcds [ Instance ] == '0' :
return False
elif Pcds [ Instance ] == '1' :
return True
try :
Value = ValueExpression ( Instance , Pcds )()
if Value == True :
return True
return False
except :
EdkLogger . warn ( 'build' , FORMAT_INVALID , "The FeatureFlagExpression cannot be evaluated" , File = str ( self ), ExtraData = Instance )
return False
else :
for Name , Guid in self . Pcds :
if self . Pcds [( Name , Guid )] . Type == 'FeatureFlag' or self . Pcds [( Name , Guid )] . Type == 'FixedAtBuild' :
2022-07-11 13:48:14 +08:00
PcdFullName = ' %s . %s ' % ( Guid , Name );
if not PcdFullName in Pcds :
Pcds [ PcdFullName ] = self . Pcds [( Name , Guid )] . DefaultValue
2022-03-22 15:26:11 +08:00
try :
Value = ValueExpression ( Instance , Pcds )()
if Value == True :
return True
return False
except :
EdkLogger . warn ( 'build' , FORMAT_INVALID , "The FeatureFlagExpression cannot be evaluated" , File = str ( self ), ExtraData = Instance )
return False
2019-07-22 11:09:22 +08:00
def ExtendCopyDictionaryLists ( CopyToDict , CopyFromDict ):
for Key in CopyFromDict :
CopyToDict [ Key ] . extend ( CopyFromDict [ Key ])