diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index b00390ce7d..12861399ac 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -316,8 +316,8 @@ class WorkspaceAutoGen(AutoGen):
EdkLogger.verbose("\nFLASH_DEFINITION = %s" % self.FdfFile)
- if Progress:
- Progress.Start("\nProcessing meta-data")
+# if Progress:
+# Progress.Start("\nProcessing meta-data")
if self.FdfFile:
#
@@ -1557,12 +1557,19 @@ class PlatformAutoGen(AutoGen):
if pcd not in self._PlatformPcds.keys():
self._PlatformPcds[pcd] = self.Platform.Pcds[pcd]
+ for item in self._PlatformPcds:
+ if self._PlatformPcds[item].DatumType and self._PlatformPcds[item].DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
+ self._PlatformPcds[item].DatumType = "VOID*"
+
if (self.Workspace.ArchList[-1] == self.Arch):
for Pcd in self._DynamicPcdList:
# just pick the a value to determine whether is unicode string type
Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]
Sku.VpdOffset = Sku.VpdOffset.strip()
+ if Pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
+ Pcd.DatumType = "VOID*"
+
PcdValue = Sku.DefaultValue
if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):
# if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
@@ -4059,7 +4066,7 @@ class ModuleAutoGen(AutoGen):
elif BoolValue == 'FALSE':
Pcd.DefaultValue = '0'
- if Pcd.DatumType != 'VOID*':
+ if Pcd.DatumType in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
HexFormat = '0x%02x'
if Pcd.DatumType == 'UINT16':
HexFormat = '0x%04x'
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py
index 7aa2016196..2bc4fbdb6e 100644
--- a/BaseTools/Source/Python/AutoGen/GenC.py
+++ b/BaseTools/Source/Python/AutoGen/GenC.py
@@ -869,7 +869,7 @@ def DynExPcdTokenNumberMapping(Info, AutoGenH):
TokenCNameList.append(TokenCName)
def GetPcdSize(Pcd):
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
Value = Pcd.DefaultValue
if Value in [None, '']:
return 1
@@ -889,6 +889,8 @@ def GetPcdSize(Pcd):
return 1
if Pcd.DatumType == 'BOOLEAN':
return 1
+ else:
+ return Pcd.MaxDatumSize
## Create code for module PCDs
@@ -951,16 +953,12 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
EdkLogger.error("build", AUTOGEN_ERROR,
"Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, TokenCName),
ExtraData="[%s]" % str(Info))
- if Pcd.DatumType not in gDatumSizeStringDatabase:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
- ExtraData="[%s]" % str(Info))
- DatumSize = gDatumSizeStringDatabase[Pcd.DatumType]
- DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType]
- GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName
- SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName
- SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + TokenCName
+ DatumSize = gDatumSizeStringDatabase[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabase else gDatumSizeStringDatabase['VOID*']
+ DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabaseLib else gDatumSizeStringDatabaseLib['VOID*']
+ GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_' + TokenCName
+ SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_' + TokenCName
+ SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_S_' + TokenCName
GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + TokenCName
PcdExCNameList = []
@@ -980,7 +978,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
AutoGenH.Append('// #define %s %s\n' % (PcdTokenName, PcdExTokenName))
AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('// #define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else:
@@ -990,7 +988,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName))
AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('#define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else:
@@ -1009,7 +1007,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
else:
AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
AutoGenH.Append('#define %s LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
else:
@@ -1087,7 +1085,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
ExtraData="[%s]" % str(Info))
if not Value.endswith('U'):
Value += 'U'
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
EdkLogger.error("build", AUTOGEN_ERROR,
"Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName),
@@ -1120,15 +1118,25 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
# skip casting for fixed at build since it breaks ARM assembly.
# Long term we need PCD macros that work in assembly
#
- elif Pcd.Type != TAB_PCDS_FIXED_AT_BUILD:
+ elif Pcd.Type != TAB_PCDS_FIXED_AT_BUILD and Pcd.DatumType in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN', 'VOID*']:
Value = "((%s)%s)" % (Pcd.DatumType, Value)
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN', 'VOID*']:
+ # handle structure PCD
+ if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName),
+ ExtraData="[%s]" % str(Info))
+
+ ArraySize = int(Pcd.MaxDatumSize, 0)
+ Array = '[%d]' % ArraySize
+
if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
PcdValueName = '_PCD_PATCHABLE_VALUE_' + TokenCName
else:
PcdValueName = '_PCD_VALUE_' + TokenCName
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
#
# For unicode, UINT16 array will be generated, so the alignment of unicode is guaranteed.
#
@@ -1176,7 +1184,7 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
AutoGenH.Append('#define %s %s%s\n' % (GetModeName, Type, PcdVariableName))
if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
else:
@@ -1239,22 +1247,18 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
EdkLogger.error("build", AUTOGEN_ERROR,
"Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, TokenCName),
ExtraData="[%s]" % str(Info))
- if Pcd.DatumType not in gDatumSizeStringDatabase:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
- ExtraData="[%s]" % str(Info))
DatumType = Pcd.DatumType
- DatumSize = gDatumSizeStringDatabaseH[DatumType]
- DatumSizeLib= gDatumSizeStringDatabaseLib[DatumType]
- GetModeName = '_PCD_GET_MODE_' + DatumSize + '_' + TokenCName
- SetModeName = '_PCD_SET_MODE_' + DatumSize + '_' + TokenCName
- SetModeStatusName = '_PCD_SET_MODE_' + DatumSize + '_S_' + TokenCName
+ DatumSize = gDatumSizeStringDatabase[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabase else gDatumSizeStringDatabase['VOID*']
+ DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabaseLib else gDatumSizeStringDatabaseLib['VOID*']
+ GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_' + TokenCName
+ SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_' + TokenCName
+ SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH['VOID*'] + '_S_' + TokenCName
GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + TokenCName
Type = ''
Array = ''
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
if Pcd.DefaultValue[0]== '{':
Type = '(VOID *)'
Array = '[]'
@@ -1279,7 +1283,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
AutoGenH.Append('// #define %s %s\n' % (PcdTokenName, PcdExTokenName))
AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('// #define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else:
@@ -1289,7 +1293,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName))
AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('#define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName,Pcd.TokenSpaceGuidCName, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else:
@@ -1310,7 +1314,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
else:
AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
AutoGenH.Append('#define %s LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))
- if DatumType == 'VOID*':
+ if DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
else:
@@ -1318,7 +1322,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
AutoGenH.Append('#define %s(Value) LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:
PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName
- if DatumType == 'VOID*':
+ if DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
ArraySize = int(Pcd.MaxDatumSize, 0)
if Pcd.DefaultValue[0] == 'L':
ArraySize = ArraySize / 2
@@ -1329,7 +1333,7 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
AutoGenH.Append('extern volatile %s %s%s;\n' % (DatumType, PcdVariableName, Array))
AutoGenH.Append('#define %s %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))
PcdDataSize = GetPcdSize(Pcd)
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, TokenCName, TokenCName, TokenCName))
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, TokenCName, TokenCName, TokenCName))
AutoGenH.Append('#define %s %s\n' % (PatchPcdSizeTokenName, Pcd.MaxDatumSize))
@@ -1346,12 +1350,14 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + TokenCName
if DatumType == 'VOID*' and Array == '[]':
DatumType = ['UINT8', 'UINT16'][Pcd.DefaultValue[0] == 'L']
+ if DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN', 'VOID*']:
+ DatumType = 'UINT8'
AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))
AutoGenH.Append('#define %s %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName))
AutoGenH.Append('//#define %s ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
if PcdItemType == TAB_PCDS_FIXED_AT_BUILD and (key in Info.ConstPcd or (Info.IsLibrary and not Info._ReferenceModules)):
- if Pcd.DatumType == 'VOID*':
+ if Pcd.DatumType not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
AutoGenH.Append('#define _PCD_VALUE_%s %s%s\n' %(TokenCName, Type, PcdVariableName))
else:
AutoGenH.Append('#define _PCD_VALUE_%s %s\n' %(TokenCName, Pcd.DefaultValue))
diff --git a/BaseTools/Source/Python/AutoGen/GenPcdDb.py b/BaseTools/Source/Python/AutoGen/GenPcdDb.py
index fc9ac7178f..ddbfe281b8 100644
--- a/BaseTools/Source/Python/AutoGen/GenPcdDb.py
+++ b/BaseTools/Source/Python/AutoGen/GenPcdDb.py
@@ -1158,6 +1158,9 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
VarCheckTab = VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER()
i = 0
ReorderedDynPcdList = GetOrderedDynamicPcdList(Platform.DynamicPcdList, Platform.PcdTokenNumber)
+ for item in ReorderedDynPcdList:
+ if item.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
+ item.DatumType = "VOID*"
for Pcd in ReorderedDynPcdList:
VoidStarTypeCurrSize = []
i += 1
diff --git a/BaseTools/Source/Python/Common/BuildToolError.py b/BaseTools/Source/Python/Common/BuildToolError.py
index bee5850fc5..2ee899ac44 100644
--- a/BaseTools/Source/Python/Common/BuildToolError.py
+++ b/BaseTools/Source/Python/Common/BuildToolError.py
@@ -86,6 +86,7 @@ MIGRATION_ERROR = 0xF010
PCD_VALIDATION_INFO_ERROR = 0xF011
PCD_VARIABLE_ATTRIBUTES_ERROR = 0xF012
PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR = 0xF013
+PCD_STRUCTURE_PCD_ERROR = 0xF014
ABORT_ERROR = 0xFFFE
UNKNOWN_ERROR = 0xFFFF
diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py
index 8b7562daa1..57ba0546ed 100644
--- a/BaseTools/Source/Python/Common/GlobalData.py
+++ b/BaseTools/Source/Python/Common/GlobalData.py
@@ -86,6 +86,9 @@ BuildOptionPcd = []
#
MixedPcd = {}
+# Structure Pcd dict
+gStructurePcd = {}
+
# Pcd name for the Pcd which used in the Conditional directives
gConditionalPcds = []
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index 2a5125d72d..2bbd9945fc 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -36,6 +36,7 @@ from CommonDataClass.DataClass import *
from Parsing import GetSplitValueList
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
+import uuid
## Regular expression used to find out place holders in string template
gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)
@@ -1471,6 +1472,100 @@ def AnalyzePcdExpression(Setting):
return FieldList
+def ParseFieldValue (Value):
+ if type(Value) == type(0):
+ return Value, (Value.bit_length() + 7) / 8
+ if type(Value) <> type(''):
+ raise ValueError
+ Value = Value.strip()
+ if Value.startswith('UINT8') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 1:
+ raise ValueError
+ return Value, 1
+ if Value.startswith('UINT16') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 2:
+ raise ValueError
+ return Value, 2
+ if Value.startswith('UINT32') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 4:
+ raise ValueError
+ return Value, 4
+ if Value.startswith('UINT64') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 8:
+ raise ValueError
+ return Value, 8
+ if Value.startswith('GUID') and Value.endswith(')'):
+ Value = Value.split('(', 1)[1][:-1].strip()
+ if Value[0] == '{' and Value[-1] == '}':
+ Value = Value[1:-1].strip()
+ Value = Value.split('{', 1)
+ Value = [Item.strip()[2:] for Item in (Value[0] + Value[1][:-1]).split(',')]
+ Value = '-'.join(Value[0:3]) + '-' + ''.join(Value[3:5]) + '-' + ''.join(Value[5:11])
+ if Value[0] == '"' and Value[-1] == '"':
+ Value = Value[1:-1]
+ Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"
+ Value, Size = ParseFieldValue(Value)
+ return Value, 16
+ if Value.startswith('L"') and Value.endswith('"'):
+ # Unicode String
+ List = list(Value[2:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 16) | ord(Char)
+ return Value, (len(List) + 1) * 2
+ if Value.startswith('"') and Value.endswith('"'):
+ # ASCII String
+ List = list(Value[1:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 8) | ord(Char)
+ return Value, len(List) + 1
+ if Value.startswith("L'") and Value.endswith("'"):
+ # Unicode Character Constant
+ List = list(Value[2:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 16) | ord(Char)
+ return Value, len(List) * 2
+ if Value.startswith("'") and Value.endswith("'"):
+ # Character constant
+ List = list(Value[1:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 8) | ord(Char)
+ return Value, len(List)
+ if Value.startswith('{') and Value.endswith('}'):
+ # Byte array
+ Value = Value[1:-1]
+ List = [Item.strip() for Item in Value.split(',')]
+ List.reverse()
+ Value = 0
+ for Item in List:
+ ItemValue, Size = ParseFieldValue(Item)
+ if Size > 1:
+ raise ValueError
+ Value = (Value << 8) | ItemValue
+ return Value, len(List)
+ if Value.lower().startswith('0x'):
+ Value = int(Value, 16)
+ return Value, (Value.bit_length() + 7) / 8
+ if Value[0].isdigit():
+ Value = int(Value, 10)
+ return Value, (Value.bit_length() + 7) / 8
+ if Value.lower() == 'true':
+ return 1, 1
+ if Value.lower() == 'false':
+ return 0, 1
+ return Value, 1
+
## AnalyzeDscPcd
#
# Analyze DSC PCD value, since there is no data type info in DSC
@@ -1504,19 +1599,19 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
Value = FieldList[0]
Size = ''
if len(FieldList) > 1:
- Type = FieldList[1]
- # Fix the PCD type when no DataType input
- if Type == 'VOID*':
- DataType = 'VOID*'
- else:
+ if FieldList[1].upper().startswith("0X") or FieldList[1].isdigit():
Size = FieldList[1]
+ else:
+ DataType = FieldList[1]
+
if len(FieldList) > 2:
Size = FieldList[2]
- if DataType == 'VOID*':
- IsValid = (len(FieldList) <= 3)
- else:
+ if DataType == "":
IsValid = (len(FieldList) <= 1)
- return [Value, '', Size], IsValid, 0
+ else:
+ IsValid = (len(FieldList) <= 3)
+# Value, Size = ParseFieldValue(Value)
+ return [str(Value), '', str(Size)], IsValid, 0
elif PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):
Value = FieldList[0]
Size = Type = ''
@@ -1534,10 +1629,10 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
Size = str(len(Value.split(",")))
else:
Size = str(len(Value) -2 + 1 )
- if DataType == 'VOID*':
- IsValid = (len(FieldList) <= 3)
- else:
+ if DataType == "":
IsValid = (len(FieldList) <= 1)
+ else:
+ IsValid = (len(FieldList) <= 3)
return [Value, Type, Size], IsValid, 0
elif PcdType in (MODEL_PCD_DYNAMIC_VPD, MODEL_PCD_DYNAMIC_EX_VPD):
VpdOffset = FieldList[0]
@@ -1550,10 +1645,11 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
Size = FieldList[1]
if len(FieldList) > 2:
Value = FieldList[2]
- if DataType == 'VOID*':
- IsValid = (len(FieldList) <= 3)
+ if DataType == "":
+ IsValid = (len(FieldList) <= 1)
else:
- IsValid = (len(FieldList) <= 2)
+ IsValid = (len(FieldList) <= 3)
+
return [VpdOffset, Size, Value], IsValid, 2
elif PcdType in (MODEL_PCD_DYNAMIC_HII, MODEL_PCD_DYNAMIC_EX_HII):
HiiString = FieldList[0]
@@ -1682,7 +1778,7 @@ def CheckPcdDatum(Type, Value):
return False, "Invalid value [%s] of type [%s];"\
" must be a hexadecimal, decimal or octal in C language format." % (Value, Type)
else:
- return False, "Invalid type [%s]; must be one of VOID*, BOOLEAN, UINT8, UINT16, UINT32, UINT64." % (Type)
+ return True, "StructurePcd"
return True, ""
diff --git a/BaseTools/Source/Python/Common/ToolDefClassObject.py b/BaseTools/Source/Python/Common/ToolDefClassObject.py
index c65cb8a36d..dc90b4783f 100644
--- a/BaseTools/Source/Python/Common/ToolDefClassObject.py
+++ b/BaseTools/Source/Python/Common/ToolDefClassObject.py
@@ -246,7 +246,6 @@ class ToolDefClassObject(object):
Value = Value.replace(Ref, self.MacroDictionary[Ref])
else:
Value = Value.replace(Ref, self.MacroDictionary[Ref.upper()])
-
MacroReference = gMacroRefPattern.findall(Value)
for Ref in MacroReference:
if Ref not in self.MacroDictionary:
diff --git a/BaseTools/Source/Python/CommonDataClass/DataClass.py b/BaseTools/Source/Python/CommonDataClass/DataClass.py
index 3be369a0f4..efeba3e5dc 100644
--- a/BaseTools/Source/Python/CommonDataClass/DataClass.py
+++ b/BaseTools/Source/Python/CommonDataClass/DataClass.py
@@ -77,6 +77,16 @@ MODEL_PCD_DYNAMIC = 4008
MODEL_PCD_DYNAMIC_DEFAULT = 4009
MODEL_PCD_DYNAMIC_VPD = 4010
MODEL_PCD_DYNAMIC_HII = 4011
+MODEL_PCD_TYPE_LIST = [MODEL_PCD_FIXED_AT_BUILD,
+ MODEL_PCD_PATCHABLE_IN_MODULE,
+ MODEL_PCD_FEATURE_FLAG,
+ MODEL_PCD_DYNAMIC_DEFAULT,
+ MODEL_PCD_DYNAMIC_HII,
+ MODEL_PCD_DYNAMIC_VPD,
+ MODEL_PCD_DYNAMIC_EX_DEFAULT,
+ MODEL_PCD_DYNAMIC_EX_HII,
+ MODEL_PCD_DYNAMIC_EX_VPD
+ ]
MODEL_META_DATA_HEADER_COMMENT = 5000
MODEL_META_DATA_HEADER = 5001
diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py
index 5fa497b803..da265b68f1 100644
--- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
+++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
@@ -16,6 +16,7 @@ import Common.LongFilePathOs as os
from Common.Misc import sdict
from Common.Misc import RealPath2
from Common.BuildToolError import *
+import collections
## PcdClassObject
#
@@ -106,6 +107,63 @@ class PcdClassObject(object):
def __hash__(self):
return hash((self.TokenCName, self.TokenSpaceGuidCName))
+class StructurePcd(PcdClassObject):
+ def __init__(self, StructuredPcdIncludeFile="", Packages=None, Name=None, Guid=None, Type=None, DatumType=None, Value=None, Token=None, MaxDatumSize=None, SkuInfoList={}, IsOverrided=False, GuidValue=None, validateranges=[], validlists=[], expressions=[]):
+ super(StructurePcd, self).__init__(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided, GuidValue, validateranges, validlists, expressions)
+ self.StructuredPcdIncludeFile = StructuredPcdIncludeFile
+ self.PackageDecs = Packages
+ self.DefaultStoreName = ['STANDARD']
+ self.DefaultValues = collections.OrderedDict({})
+ self.PcdMode = None
+ self.SkuOverrideValues = collections.OrderedDict({})
+ self.FlexibleFieldName = None
+
+ def __repr__(self):
+ return self.TypeName
+
+ def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0):
+ self.DefaultValues[FieldName] = [Value.strip(), FileName, LineNo]
+ return self.DefaultValues[FieldName]
+
+ def AddOverrideValue (self, FieldName, Value, SkuName, FileName="", LineNo=0):
+ if SkuName not in self.SkuOverrideValues:
+ self.SkuOverrideValues[SkuName] = collections.OrderedDict({})
+ self.SkuOverrideValues[SkuName][FieldName] = [Value.strip(), FileName, LineNo]
+ return self.SkuOverrideValues[SkuName][FieldName]
+
+ def SetPcdMode (self, PcdMode):
+ self.PcdMode = PcdMode
+
+ def SetFlexibleFieldName (self, FlexibleFieldName):
+ self.FlexibleFieldName = FlexibleFieldName
+
+ def copy(self, PcdObject):
+ self.TokenCName = PcdObject.TokenCName if PcdObject.TokenCName else self.TokenCName
+ self.TokenSpaceGuidCName = PcdObject.TokenSpaceGuidCName if PcdObject.TokenSpaceGuidCName else PcdObject.TokenSpaceGuidCName
+ self.TokenSpaceGuidValue = PcdObject.TokenSpaceGuidValue if PcdObject.TokenSpaceGuidValue else self.TokenSpaceGuidValue
+ self.Type = PcdObject.Type if PcdObject.Type else self.Type
+ self.DatumType = PcdObject.DatumType if PcdObject.DatumType else self.DatumType
+ self.DefaultValue = PcdObject.DefaultValue if PcdObject.DefaultValue else self.DefaultValue
+ self.TokenValue = PcdObject.TokenValue if PcdObject.TokenValue else self.TokenValue
+ self.MaxDatumSize = PcdObject.MaxDatumSize if PcdObject.MaxDatumSize else self.MaxDatumSize
+ self.SkuInfoList = PcdObject.SkuInfoList if PcdObject.SkuInfoList else self.SkuInfoList
+ self.Phase = PcdObject.Phase if PcdObject.Phase else self.Phase
+ self.Pending = PcdObject.Pending if PcdObject.Pending else self.Pending
+ self.IsOverrided = PcdObject.IsOverrided if PcdObject.IsOverrided else self.IsOverrided
+ self.IsFromBinaryInf = PcdObject.IsFromBinaryInf if PcdObject.IsFromBinaryInf else self.IsFromBinaryInf
+ self.IsFromDsc = PcdObject.IsFromDsc if PcdObject.IsFromDsc else self.IsFromDsc
+ self.validateranges = PcdObject.validateranges if PcdObject.validateranges else self.validateranges
+ self.validlists = PcdObject.validlists if PcdObject.validlists else self.validlists
+ self.expressions = PcdObject.expressions if PcdObject.expressions else self.expressions
+ if type(PcdObject) is StructurePcd:
+ self.StructuredPcdIncludeFile = PcdObject.StructuredPcdIncludeFile if PcdObject.StructuredPcdIncludeFile else self.StructuredPcdIncludeFile
+ self.PackageDecs = PcdObject.PackageDecs if PcdObject.PackageDecs else self.PackageDecs
+ self.DefaultValues = PcdObject.DefaultValues if PcdObject.DefaultValues else self.DefaultValues
+ self.PcdMode = PcdObject.PcdMode if PcdObject.PcdMode else self.PcdMode
+ self.DefaultFromDSC=None
+ self.OverrideValues = PcdObject.SkuOverrideValues if PcdObject.SkuOverrideValues else self.SkuOverrideValues
+ self.FlexibleFieldName = PcdObject.FlexibleFieldName if PcdObject.FlexibleFieldName else self.FlexibleFieldName
+
## LibraryClassObject
#
# This Class defines LibraryClassObject used in BuildDatabase
diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py b/BaseTools/Source/Python/Workspace/DecBuildData.py
new file mode 100644
index 0000000000..d0e77fa440
--- /dev/null
+++ b/BaseTools/Source/Python/Workspace/DecBuildData.py
@@ -0,0 +1,462 @@
+## @file
+# This file is used to create a database used by build tool
+#
+# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+from Common.String import *
+from Common.DataType import *
+from Common.Misc import *
+from types import *
+
+from Workspace.BuildClassObject import PackageBuildClassObject, StructurePcd, PcdClassObject
+
+## Platform build information from DEC file
+#
+# This class is used to retrieve information stored in database and convert them
+# into PackageBuildClassObject form for easier use for AutoGen.
+#
+class DecBuildData(PackageBuildClassObject):
+ # dict used to convert PCD type in database to string used by build tool
+ _PCD_TYPE_STRING_ = {
+ MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
+ MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
+ MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
+ MODEL_PCD_DYNAMIC : "Dynamic",
+ MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
+ MODEL_PCD_DYNAMIC_HII : "DynamicHii",
+ MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
+ MODEL_PCD_DYNAMIC_EX : "DynamicEx",
+ MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
+ MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
+ MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
+ }
+
+ # dict used to convert part of [Defines] to members of DecBuildData directly
+ _PROPERTY_ = {
+ #
+ # Required Fields
+ #
+ TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName",
+ TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid",
+ TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version",
+ TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile",
+ }
+
+
+ ## Constructor of DecBuildData
+ #
+ # Initialize object of DecBuildData
+ #
+ # @param FilePath The path of package description file
+ # @param RawData The raw data of DEC file
+ # @param BuildDataBase Database used to retrieve module information
+ # @param Arch The target architecture
+ # @param Platform (not used for DecBuildData)
+ # @param Macros Macros used for replacement in DSC file
+ #
+ def __init__(self, File, RawData, BuildDataBase, 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()
+
+ ## 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._LibraryClasses = None
+ self._Pcds = None
+ self.__Macros = None
+ self._PrivateProtocols = None
+ self._PrivatePpis = None
+ self._PrivateGuids = None
+ self._PrivateIncludes = None
+
+ ## Get current effective macros
+ def _GetMacros(self):
+ if self.__Macros == None:
+ self.__Macros = {}
+ self.__Macros.update(GlobalData.gGlobalDefines)
+ return self.__Macros
+
+ ## Get architecture
+ def _GetArch(self):
+ return self._Arch
+
+ ## Set architecture
+ #
+ # Changing the default ARCH to another may affect all other information
+ # because all information in a platform may be ARCH-related. That's
+ # why we need to clear all internal used members, in order to cause all
+ # information to be re-retrieved.
+ #
+ # @param Value The value of ARCH
+ #
+ def _SetArch(self, Value):
+ if self._Arch == Value:
+ return
+ self._Arch = Value
+ self._Clear()
+
+ ## Retrieve all information in [Defines] section
+ #
+ # (Retriving 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
+ def _GetPackageName(self):
+ if self._PackageName == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._PackageName == None:
+ EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)
+ return self._PackageName
+
+ ## Retrieve file guid
+ def _GetFileGuid(self):
+ if self._Guid == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._Guid == None:
+ EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)
+ return self._Guid
+
+ ## Retrieve package version
+ def _GetVersion(self):
+ if self._Version == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._Version == None:
+ self._Version = ''
+ return self._Version
+
+ ## Retrieve protocol definitions (name/value pairs)
+ def _GetProtocol(self):
+ if self._Protocols == None:
+ #
+ # tdict is a special kind of dict, used for selecting correct
+ # protocol defition 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 sdict to keep the order
+ self._Protocols = sdict()
+ self._PrivateProtocols = sdict()
+ 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)
+ def _GetPpi(self):
+ if self._Ppis == None:
+ #
+ # tdict is a special kind of dict, used for selecting correct
+ # PPI defition 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 sdict to keep the order
+ self._Ppis = sdict()
+ self._PrivatePpis = sdict()
+ 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)
+ def _GetGuid(self):
+ if self._Guids == None:
+ #
+ # tdict is a special kind of dict, used for selecting correct
+ # GUID defition 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 sdict to keep the order
+ self._Guids = sdict()
+ self._PrivateGuids = sdict()
+ 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
+ def _GetInclude(self):
+ if self._Includes == None:
+ self._Includes = []
+ self._PrivateIncludes = []
+ PublicInclues = []
+ RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ 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)
+
+ return self._Includes
+
+ ## Retrieve library class declarations (not used in build at present)
+ def _GetLibraryClass(self):
+ if self._LibraryClasses == None:
+ #
+ # tdict is a special kind of dict, used for selecting correct
+ # library class declaration for given ARCH
+ #
+ 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 = sdict()
+ for LibraryClass in LibraryClassSet:
+ self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]
+ return self._LibraryClasses
+
+ ## Retrieve PCD declarations
+ def _GetPcds(self):
+ if self._Pcds == None:
+ self._Pcds = sdict()
+ 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 ProcessStructurePcd(self, StructurePcdRawDataSet):
+ s_pcd_set = dict()
+ 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 "" in item.TokenCName:
+ struct_pcd.StructuredPcdIncludeFile = item.DefaultValue
+ elif "" 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(".")
+ else:
+ struct_pcd.AddDefaultValue(item.TokenCName, item.DefaultValue,self.MetaFile.File,LineNo)
+
+ 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 = sdict()
+ #
+ # tdict is a special kind of dict, used for selecting correct
+ # PCD declaration for given ARCH
+ #
+ PcdDict = tdict(True, 3)
+ # for summarizing PCD
+ PcdSet = set()
+ # 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)
+ PcdSet.add((PcdCName, TokenSpaceGuid))
+
+ 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 == 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)
+ )
+ 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
+
+ return Pcds
+
+
+ _Macros = property(_GetMacros)
+ Arch = property(_GetArch, _SetArch)
+ PackageName = property(_GetPackageName)
+ Guid = property(_GetFileGuid)
+ Version = property(_GetVersion)
+
+ Protocols = property(_GetProtocol)
+ Ppis = property(_GetPpi)
+ Guids = property(_GetGuid)
+ Includes = property(_GetInclude)
+ LibraryClasses = property(_GetLibraryClass)
+ Pcds = property(_GetPcds)
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
new file mode 100644
index 0000000000..302de724b1
--- /dev/null
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -0,0 +1,1740 @@
+## @file
+# This file is used to create a database used by build tool
+#
+# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+## Platform build information from DSC file
+#
+# This class is used to retrieve information stored in database and convert them
+# into PlatformBuildClassObject form for easier use for AutoGen.
+#
+from Common.String import *
+from Common.DataType import *
+from Common.Misc import *
+from types import *
+
+from CommonDataClass.CommonClass import SkuInfoClass
+
+from MetaDataTable import *
+from MetaFileTable import *
+from MetaFileParser import *
+
+from WorkspaceCommon import GetDeclaredPcd
+from Common.Misc import AnalyzeDscPcd
+from Common.Misc import ProcessDuplicatedInf
+import re
+from Common.Parsing import IsValidWord
+from Common.VariableAttributes import VariableAttributes
+import Common.GlobalData as GlobalData
+import subprocess
+from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
+
+#
+# Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs
+#
+PcdValueInitName = 'PcdValueInit'
+PcdSupportedBaseTypes = ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']
+PcdSupportedBaseTypeWidth = {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}
+PcdUnsupportedBaseTypes = ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']
+
+PcdMainCHeader = '''
+/**
+ DO NOT EDIT
+ FILE auto-generated
+**/
+
+#include
+#include
+#include
+#include
+'''
+
+PcdMainCEntry = '''
+int
+main (
+ int argc,
+ char *argv[]
+ )
+{
+ return PcdValueMain (argc, argv);
+}
+'''
+
+PcdMakefileHeader = '''
+#
+# DO NOT EDIT
+# This file is auto-generated by build utility
+#
+
+'''
+
+PcdMakefileEnd = '''
+!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
+
+CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101
+
+LIBS = $(LIB_PATH)\Common.lib
+
+!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
+'''
+
+PcdGccMakefile = '''
+ARCH ?= IA32
+MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
+LIBS = -lCommon
+'''
+
+class DscBuildData(PlatformBuildClassObject):
+ # dict used to convert PCD type in database to string used by build tool
+ _PCD_TYPE_STRING_ = {
+ MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
+ MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
+ MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
+ MODEL_PCD_DYNAMIC : "Dynamic",
+ MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
+ MODEL_PCD_DYNAMIC_HII : "DynamicHii",
+ MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
+ MODEL_PCD_DYNAMIC_EX : "DynamicEx",
+ MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
+ MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
+ MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
+ }
+
+ # dict used to convert part of [Defines] to members of DscBuildData directly
+ _PROPERTY_ = {
+ #
+ # Required Fields
+ #
+ TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",
+ TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",
+ TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",
+ TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",
+ # TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
+ # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
+ # TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
+ TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
+ # TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
+ TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",
+ TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",
+ TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",
+ TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",
+ # TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
+ # TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
+ }
+
+ # used to compose dummy library class name for those forced library instances
+ _NullLibraryNumber = 0
+
+ ## Constructor of DscBuildData
+ #
+ # Initialize object of DscBuildData
+ #
+ # @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 (not used for DscBuildData)
+ # @param Macros Macros used for replacement in DSC file
+ #
+ def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):
+ self.MetaFile = FilePath
+ self._RawData = RawData
+ self._Bdb = BuildDataBase
+ self._Arch = Arch
+ self._Target = Target
+ self._Toolchain = Toolchain
+ self._Clear()
+ self._HandleOverridePath()
+ if os.getenv("WORKSPACE"):
+ self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName)
+ else:
+ self.OutputPath = os.path.dirname(self.DscFile)
+
+ ## 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 DscBuildData to None
+ def _Clear(self):
+ self._Header = None
+ self._PlatformName = None
+ self._Guid = None
+ self._Version = None
+ self._DscSpecification = None
+ self._OutputDirectory = None
+ self._SupArchList = None
+ self._BuildTargets = None
+ self._SkuName = None
+ self._SkuIdentifier = None
+ self._AvilableSkuIds = None
+ self._PcdInfoFlag = None
+ self._VarCheckFlag = None
+ self._FlashDefinition = None
+ self._Prebuild = None
+ self._Postbuild = None
+ self._BuildNumber = None
+ self._MakefileName = None
+ self._BsBaseAddress = None
+ self._RtBaseAddress = None
+ self._SkuIds = None
+ self._Modules = None
+ self._LibraryInstances = None
+ self._LibraryClasses = None
+ self._Pcds = None
+ self._DecPcds = None
+ self._BuildOptions = None
+ self._ModuleTypeOptions = None
+ self._LoadFixAddress = None
+ self._RFCLanguages = None
+ self._ISOLanguages = None
+ self._VpdToolGuid = None
+ self.__Macros = None
+
+
+ ## handle Override Path of Module
+ def _HandleOverridePath(self):
+ RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ for Record in RecordList:
+ ModuleId = Record[5]
+ LineNo = Record[6]
+ ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)
+ RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]
+ if RecordList != []:
+ SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))
+
+ # Check if the source override path exists
+ if not os.path.isdir(SourceOverridePath):
+ EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)
+
+ # Add to GlobalData Variables
+ GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath
+
+ ## Get current effective macros
+ def _GetMacros(self):
+ if self.__Macros == None:
+ self.__Macros = {}
+ self.__Macros.update(GlobalData.gPlatformDefines)
+ self.__Macros.update(GlobalData.gGlobalDefines)
+ self.__Macros.update(GlobalData.gCommandLineDefines)
+ return self.__Macros
+
+ ## Get architecture
+ def _GetArch(self):
+ return self._Arch
+
+ ## Set architecture
+ #
+ # Changing the default ARCH to another may affect all other information
+ # because all information in a platform may be ARCH-related. That's
+ # why we need to clear all internal used members, in order to cause all
+ # information to be re-retrieved.
+ #
+ # @param Value The value of ARCH
+ #
+ def _SetArch(self, Value):
+ if self._Arch == Value:
+ return
+ self._Arch = Value
+ self._Clear()
+
+ ## Retrieve all information in [Defines] section
+ #
+ # (Retriving 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]
+ # items defined _PROPERTY_ don't need additional processing
+
+ # some special items in [Defines] section need special treatment
+ if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
+ self._OutputDirectory = NormPath(Record[2], self._Macros)
+ if ' ' in self._OutputDirectory:
+ EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",
+ File=self.MetaFile, Line=Record[-1],
+ ExtraData=self._OutputDirectory)
+ elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:
+ self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
+ ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],
+ ExtraData=ErrorInfo)
+ elif Name == TAB_DSC_PREBUILD:
+ PrebuildValue = Record[2]
+ if Record[2][0] == '"':
+ if Record[2][-1] != '"':
+ EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,
+ File=self.MetaFile, Line=Record[-1])
+ PrebuildValue = Record[2][1:-1]
+ self._Prebuild = PrebuildValue
+ elif Name == TAB_DSC_POSTBUILD:
+ PostbuildValue = Record[2]
+ if Record[2][0] == '"':
+ if Record[2][-1] != '"':
+ EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,
+ File=self.MetaFile, Line=Record[-1])
+ PostbuildValue = Record[2][1:-1]
+ self._Postbuild = PostbuildValue
+ elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:
+ self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
+ elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
+ self._BuildTargets = GetSplitValueList(Record[2])
+ elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
+ if self._SkuName == None:
+ self._SkuName = Record[2]
+ self._SkuIdentifier = Record[2]
+ self._AvilableSkuIds = Record[2]
+ elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:
+ self._PcdInfoFlag = Record[2]
+ elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:
+ self._VarCheckFlag = Record[2]
+ elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
+ try:
+ self._LoadFixAddress = int (Record[2], 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))
+ elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:
+ if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageCodes = Record[2][1:-1]
+ if not LanguageCodes:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)
+ # check whether there is empty entries in the list
+ if None in LanguageList:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',
+ File=self.MetaFile, Line=Record[-1])
+ self._RFCLanguages = LanguageList
+ elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:
+ if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageCodes = Record[2][1:-1]
+ if not LanguageCodes:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
+ File=self.MetaFile, Line=Record[-1])
+ if len(LanguageCodes) % 3:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageList = []
+ for i in range(0, len(LanguageCodes), 3):
+ LanguageList.append(LanguageCodes[i:i + 3])
+ self._ISOLanguages = LanguageList
+ elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:
+ #
+ # try to convert GUID to a real UUID value to see whether the GUID is format
+ # for VPD_TOOL_GUID is correct.
+ #
+ try:
+ uuid.UUID(Record[2])
+ except:
+ EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
+ self._VpdToolGuid = Record[2]
+ elif Name in self:
+ self[Name] = Record[2]
+ # set _Header to non-None in order to avoid database re-querying
+ self._Header = 'DUMMY'
+
+ ## Retrieve platform name
+ def _GetPlatformName(self):
+ if self._PlatformName == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._PlatformName == None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)
+ return self._PlatformName
+
+ ## Retrieve file guid
+ def _GetFileGuid(self):
+ if self._Guid == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._Guid == None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)
+ return self._Guid
+
+ ## Retrieve platform version
+ def _GetVersion(self):
+ if self._Version == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._Version == None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)
+ return self._Version
+
+ ## Retrieve platform description file version
+ def _GetDscSpec(self):
+ if self._DscSpecification == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._DscSpecification == None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)
+ return self._DscSpecification
+
+ ## Retrieve OUTPUT_DIRECTORY
+ def _GetOutpuDir(self):
+ if self._OutputDirectory == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._OutputDirectory == None:
+ self._OutputDirectory = os.path.join("Build", self._PlatformName)
+ return self._OutputDirectory
+
+ ## Retrieve SUPPORTED_ARCHITECTURES
+ def _GetSupArch(self):
+ if self._SupArchList == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._SupArchList == None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)
+ return self._SupArchList
+
+ ## Retrieve BUILD_TARGETS
+ def _GetBuildTarget(self):
+ if self._BuildTargets == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._BuildTargets == None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)
+ return self._BuildTargets
+
+ def _GetPcdInfoFlag(self):
+ if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE':
+ return False
+ elif self._PcdInfoFlag.upper() == 'TRUE':
+ return True
+ else:
+ return False
+ def _GetVarCheckFlag(self):
+ if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE':
+ return False
+ elif self._VarCheckFlag.upper() == 'TRUE':
+ return True
+ else:
+ return False
+ def _GetAviableSkuIds(self):
+ if self._AvilableSkuIds:
+ return self._AvilableSkuIds
+ return self.SkuIdentifier
+ def _GetSkuIdentifier(self):
+ if self._SkuName:
+ return self._SkuName
+ if self._SkuIdentifier == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ return self._SkuIdentifier
+ ## Retrieve SKUID_IDENTIFIER
+ def _GetSkuName(self):
+ if self._SkuName == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if (self._SkuName == None or self._SkuName not in self.SkuIds):
+ self._SkuName = 'DEFAULT'
+ return self._SkuName
+
+ ## Override SKUID_IDENTIFIER
+ def _SetSkuName(self, Value):
+ self._SkuName = Value
+ self._Pcds = None
+
+ def _GetFdfFile(self):
+ if self._FlashDefinition == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._FlashDefinition == None:
+ self._FlashDefinition = ''
+ return self._FlashDefinition
+
+ def _GetPrebuild(self):
+ if self._Prebuild == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._Prebuild == None:
+ self._Prebuild = ''
+ return self._Prebuild
+
+ def _GetPostbuild(self):
+ if self._Postbuild == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._Postbuild == None:
+ self._Postbuild = ''
+ return self._Postbuild
+
+ ## Retrieve FLASH_DEFINITION
+ def _GetBuildNumber(self):
+ if self._BuildNumber == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._BuildNumber == None:
+ self._BuildNumber = ''
+ return self._BuildNumber
+
+ ## Retrieve MAKEFILE_NAME
+ def _GetMakefileName(self):
+ if self._MakefileName == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._MakefileName == None:
+ self._MakefileName = ''
+ return self._MakefileName
+
+ ## Retrieve BsBaseAddress
+ def _GetBsBaseAddress(self):
+ if self._BsBaseAddress == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._BsBaseAddress == None:
+ self._BsBaseAddress = ''
+ return self._BsBaseAddress
+
+ ## Retrieve RtBaseAddress
+ def _GetRtBaseAddress(self):
+ if self._RtBaseAddress == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._RtBaseAddress == None:
+ self._RtBaseAddress = ''
+ return self._RtBaseAddress
+
+ ## Retrieve the top address for the load fix address
+ def _GetLoadFixAddress(self):
+ if self._LoadFixAddress == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+
+ if self._LoadFixAddress == None:
+ self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')
+
+ try:
+ self._LoadFixAddress = int (self._LoadFixAddress, 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))
+
+ #
+ # If command line defined, should override the value in DSC file.
+ #
+ if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():
+ try:
+ self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))
+
+ if self._LoadFixAddress < 0:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))
+ if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))
+
+ return self._LoadFixAddress
+
+ ## Retrieve RFCLanguage filter
+ def _GetRFCLanguages(self):
+ if self._RFCLanguages == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._RFCLanguages == None:
+ self._RFCLanguages = []
+ return self._RFCLanguages
+
+ ## Retrieve ISOLanguage filter
+ def _GetISOLanguages(self):
+ if self._ISOLanguages == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._ISOLanguages == None:
+ self._ISOLanguages = []
+ return self._ISOLanguages
+ ## Retrieve the GUID string for VPD tool
+ def _GetVpdToolGuid(self):
+ if self._VpdToolGuid == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._VpdToolGuid == None:
+ self._VpdToolGuid = ''
+ return self._VpdToolGuid
+
+ ## Retrieve [SkuIds] section information
+ def _GetSkuIds(self):
+ if self._SkuIds == None:
+ self._SkuIds = sdict()
+ RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]
+ for Record in RecordList:
+ if Record[0] in [None, '']:
+ EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',
+ File=self.MetaFile, Line=Record[-1])
+ if Record[1] in [None, '']:
+ EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',
+ File=self.MetaFile, Line=Record[-1])
+ self._SkuIds[Record[1]] = Record[0]
+ if 'DEFAULT' not in self._SkuIds:
+ self._SkuIds['DEFAULT'] = '0'
+ if 'COMMON' not in self._SkuIds:
+ self._SkuIds['COMMON'] = '0'
+ return self._SkuIds
+
+ ## Retrieve [Components] section information
+ def _GetModules(self):
+ if self._Modules != None:
+ return self._Modules
+
+ self._Modules = sdict()
+ RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ for Record in RecordList:
+ DuplicatedFile = False
+
+ ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ ModuleId = Record[5]
+ LineNo = Record[6]
+
+ # check the file validation
+ ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
+ ExtraData=ErrorInfo)
+ # Check duplication
+ # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
+ if self._Arch != 'COMMON' and ModuleFile in self._Modules:
+ DuplicatedFile = True
+
+ Module = ModuleBuildClassObject()
+ Module.MetaFile = ModuleFile
+
+ # get module private library instance
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
+ for Record in RecordList:
+ LibraryClass = Record[0]
+ LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ LineNo = Record[-1]
+
+ # check the file validation
+ ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
+ ExtraData=ErrorInfo)
+
+ if LibraryClass == '' or LibraryClass == 'NULL':
+ self._NullLibraryNumber += 1
+ LibraryClass = 'NULL%d' % self._NullLibraryNumber
+ EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
+ Module.LibraryClasses[LibraryClass] = LibraryPath
+ if LibraryPath not in self.LibraryInstances:
+ self.LibraryInstances.append(LibraryPath)
+
+ # get module private PCD setting
+ 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, None, ModuleId]
+ for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
+ TokenList = GetSplitValueList(Setting)
+ DefaultValue = TokenList[0]
+ if len(TokenList) > 1:
+ MaxDatumSize = TokenList[1]
+ else:
+ MaxDatumSize = ''
+ TypeString = self._PCD_TYPE_STRING_[Type]
+ Pcd = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ TypeString,
+ '',
+ DefaultValue,
+ '',
+ MaxDatumSize,
+ {},
+ False,
+ None
+ )
+ Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
+
+ # get module private build options
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]
+ for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
+ if (ToolChainFamily, ToolChain) not in Module.BuildOptions:
+ Module.BuildOptions[ToolChainFamily, ToolChain] = Option
+ else:
+ OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]
+ Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
+
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
+ if DuplicatedFile and not RecordList:
+ EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
+ if RecordList:
+ if len(RecordList) != 1:
+ EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in section.',
+ File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
+ ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
+ ModuleFile.Arch = self._Arch
+
+ self._Modules[ModuleFile] = Module
+ return self._Modules
+
+ ## Retrieve all possible library instances used in this platform
+ def _GetLibraryInstances(self):
+ if self._LibraryInstances == None:
+ self._GetLibraryClasses()
+ return self._LibraryInstances
+
+ ## Retrieve [LibraryClasses] information
+ def _GetLibraryClasses(self):
+ if self._LibraryClasses == None:
+ self._LibraryInstances = []
+ #
+ # tdict is a special dict kind of type, used for selecting correct
+ # library instance for given library class and module type
+ #
+ LibraryClassDict = tdict(True, 3)
+ # track all library class names
+ LibraryClassSet = set()
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
+ Macros = self._Macros
+ for Record in RecordList:
+ LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record
+ if LibraryClass == '' or LibraryClass == 'NULL':
+ self._NullLibraryNumber += 1
+ LibraryClass = 'NULL%d' % self._NullLibraryNumber
+ EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))
+ LibraryClassSet.add(LibraryClass)
+ LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ # check the file validation
+ ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
+ ExtraData=ErrorInfo)
+
+ if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:
+ EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,
+ File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)
+ LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance
+ if LibraryInstance not in self._LibraryInstances:
+ self._LibraryInstances.append(LibraryInstance)
+
+ # resolve the specific library instance for each class and each module type
+ self._LibraryClasses = tdict(True)
+ for LibraryClass in LibraryClassSet:
+ # try all possible module types
+ for ModuleType in SUP_MODULE_LIST:
+ LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]
+ if LibraryInstance == None:
+ continue
+ self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
+
+ # for Edk style library instances, which are listed in different section
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
+ for Record in RecordList:
+ File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ LineNo = Record[-1]
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate('.inf')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
+ ExtraData=ErrorInfo)
+ if File not in self._LibraryInstances:
+ self._LibraryInstances.append(File)
+ #
+ # we need the module name as the library class name, so we have
+ # to parse it here. (self._Bdb[] will trigger a file parse if it
+ # hasn't been parsed)
+ #
+ Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
+ self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
+ return self._LibraryClasses
+
+ def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
+ if self._DecPcds == None:
+ self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain)
+ FdfInfList = []
+ if GlobalData.gFdfParser:
+ FdfInfList = GlobalData.gFdfParser.Profile.InfList
+
+ PkgSet = set()
+ for Inf in FdfInfList:
+ ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
+ if ModuleFile in self._Modules:
+ continue
+ ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
+ PkgSet.update(ModuleData.Packages)
+ DecPcds = {}
+ for Pkg in PkgSet:
+ for Pcd in Pkg.Pcds:
+ DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]
+ self._DecPcds.update(DecPcds)
+
+ if (PcdCName, TokenSpaceGuid) not in self._DecPcds and "." in TokenSpaceGuid and (TokenSpaceGuid.split(".")[1], TokenSpaceGuid.split(".")[0]) not in self._DecPcds:
+ EdkLogger.error('build', PARSER_ERROR,
+ "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
+ File=self.MetaFile, Line=LineNo)
+ ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)
+ if not IsValid and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
+ EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
+ ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
+ if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
+ try:
+ ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)
+ except WrnExpression, Value:
+ ValueList[Index] = Value.result
+ except EvaluationException, Excpt:
+ if hasattr(Excpt, 'Pcd'):
+ if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
+ " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
+ " of the DSC file" % Excpt.Pcd,
+ File=self.MetaFile, Line=LineNo)
+ else:
+ EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
+ File=self.MetaFile, Line=LineNo)
+ else:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
+ File=self.MetaFile, Line=LineNo)
+ if ValueList[Index] == 'True':
+ ValueList[Index] = '1'
+ elif ValueList[Index] == 'False':
+ ValueList[Index] = '0'
+ if ValueList[Index]:
+ Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
+ if not Valid:
+ EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
+ ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
+ return ValueList
+
+ ## Retrieve all PCD settings in platform
+ def _GetPcds(self):
+ if self._Pcds == None:
+ self._Pcds = sdict()
+ 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._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
+ self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
+ self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
+ self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
+ self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
+ self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
+
+ self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
+ return self._Pcds
+
+ ## Retrieve [BuildOptions]
+ def _GetBuildOptions(self):
+ if self._BuildOptions == None:
+ self._BuildOptions = sdict()
+ #
+ # Retrieve build option for EDKII and EDK style module
+ #
+ for CodeBase in (EDKII_NAME, EDK_NAME):
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
+ for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
+ CurKey = (ToolChainFamily, ToolChain, CodeBase)
+ #
+ # Only flags can be appended
+ #
+ if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
+ self._BuildOptions[CurKey] = Option
+ else:
+ self._BuildOptions[CurKey] += ' ' + Option
+ return self._BuildOptions
+
+ def GetBuildOptionsByModuleType(self, Edk, ModuleType):
+ if self._ModuleTypeOptions == None:
+ self._ModuleTypeOptions = sdict()
+ if (Edk, ModuleType) not in self._ModuleTypeOptions:
+ options = sdict()
+ self._ModuleTypeOptions[Edk, ModuleType] = options
+ DriverType = '%s.%s' % (Edk, ModuleType)
+ CommonDriverType = '%s.%s' % ('COMMON', ModuleType)
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]
+ for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList:
+ if Type == DriverType or Type == CommonDriverType:
+ Key = (ToolChainFamily, ToolChain, Edk)
+ if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
+ options[Key] = Option
+ else:
+ options[Key] += ' ' + Option
+ return self._ModuleTypeOptions[Edk, ModuleType]
+
+ def GetStructurePcdInfo(self, PcdSet):
+ structure_pcd_data = {}
+ for item in PcdSet:
+ if item[1] not in structure_pcd_data:
+ structure_pcd_data[item[1]] = []
+ structure_pcd_data[item[1]].append(item)
+
+ return structure_pcd_data
+
+ def UpdateStructuredPcds(self, TypeList, AllPcds):
+ Pcds = AllPcds
+ SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds)
+
+ S_PcdSet = []
+ # Find out all possible PCD candidates for self._Arch
+ RecordList = []
+ for Type in TypeList:
+ RecordList.extend(self._RawData[Type, self._Arch])
+
+ for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
+ SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
+ if SkuName in SkuObj.SkuIdSet and "." in TokenSpaceGuid:
+ S_PcdSet.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4, AnalyzePcdExpression(Setting)[0]))
+
+ # handle pcd value override
+ StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)
+ S_pcd_set = {}
+ for str_pcd in StrPcdSet:
+ str_pcd_obj = Pcds.get((str_pcd.split(".")[1], str_pcd.split(".")[0]), None)
+ str_pcd_dec = self._DecPcds.get((str_pcd.split(".")[1], str_pcd.split(".")[0]), None)
+ if str_pcd_dec:
+ str_pcd_obj_str = StructurePcd()
+ str_pcd_obj_str.copy(str_pcd_dec)
+ if str_pcd_obj:
+ str_pcd_obj_str.copy(str_pcd_obj)
+ if str_pcd_obj.DefaultValue:
+ str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue
+ for str_pcd_data in StrPcdSet[str_pcd]:
+ if str_pcd_data[2] in SkuObj.SkuIdSet:
+ str_pcd_obj_str.AddOverrideValue(str_pcd_data[0], str(str_pcd_data[4]), 'DEFAULT' if str_pcd_data[2] == 'COMMON' else str_pcd_data[2],self.MetaFile.File,LineNo=str_pcd_data[3])
+ S_pcd_set[str_pcd.split(".")[1], str_pcd.split(".")[0]] = str_pcd_obj_str
+ # Add the Structure PCD that only defined in DEC, don't have override in DSC file
+ for Pcd in self._DecPcds:
+ if type (self._DecPcds[Pcd]) is StructurePcd:
+ if Pcd not in S_pcd_set:
+ str_pcd_obj_str = StructurePcd()
+ str_pcd_obj_str.copy(self._DecPcds[Pcd])
+ str_pcd_obj = Pcds.get(Pcd, None)
+ if str_pcd_obj:
+ str_pcd_obj_str.copy(str_pcd_obj)
+ if str_pcd_obj.DefaultValue:
+ str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue
+ S_pcd_set[Pcd] = str_pcd_obj_str
+ if S_pcd_set:
+ GlobalData.gStructurePcd[self.Arch] = S_pcd_set
+ Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
+ if Str_Pcd_Values:
+ for item in Str_Pcd_Values:
+ str_pcd_obj = S_pcd_set.get((item[2], item[1]))
+ if str_pcd_obj is None:
+ raise
+ if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
+ self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
+ if item[0] not in str_pcd_obj.SkuInfoList:
+ str_pcd_obj.SkuInfoList[item[0]] = SkuInfoClass(SkuIdName=item[0], SkuId=self.SkuIds[item[0]], HiiDefaultValue=item[3])
+ else:
+ str_pcd_obj.SkuInfoList[item[0]].HiiDefaultValue = item[3]
+ elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+ self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
+ if item[0] in (SkuObj.SystemSkuId, 'DEFAULT', 'COMMON'):
+ str_pcd_obj.DefaultValue = item[3]
+ else:
+ if item[0] not in str_pcd_obj.SkuInfoList:
+ str_pcd_obj.SkuInfoList[item[0]] = SkuInfoClass(SkuIdName=item[0], SkuId=self.SkuIds[item[0]], DefaultValue=item[3])
+ else:
+ str_pcd_obj.SkuInfoList[item[0]].DefaultValue = item[3]
+
+ for str_pcd_obj in S_pcd_set.values():
+ str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)
+ Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
+
+ return Pcds
+
+ ## Retrieve non-dynamic PCD settings
+ #
+ # @param Type PCD type
+ #
+ # @retval a dict object contains settings of given PCD type
+ #
+ def _GetPcd(self, Type):
+ Pcds = sdict()
+ #
+ # tdict is a special dict kind of type, used for selecting correct
+ # PCD settings for certain ARCH
+ #
+
+ SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds)
+
+ PcdDict = tdict(True, 3)
+ PcdSet = set()
+ # Find out all possible PCD candidates for self._Arch
+ RecordList = self._RawData[Type, self._Arch]
+ AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
+ AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0})
+ PcdValueDict = sdict()
+ for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
+ if SkuName not in AvailableSkuIdSet:
+ EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName)
+ if "." not in TokenSpaceGuid:
+ PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4))
+ PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
+ else:
+ TokenSpaceGuid, PcdCName = TokenSpaceGuid.split('.')
+ Flag = True
+ for PcdItem in RecordList:
+ if (TokenSpaceGuid, PcdCName) == (PcdItem[0], PcdItem[1]):
+ Flag = False
+ break
+ if Flag:
+ PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, 0))
+ PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = ''
+
+ for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
+ Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
+ if Setting == None:
+ continue
+ PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ if (PcdCName, TokenSpaceGuid) in PcdValueDict:
+ PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
+ else:
+ PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
+
+ PcdsKeys = PcdValueDict.keys()
+ for PcdCName, TokenSpaceGuid in PcdsKeys:
+
+ PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]
+ PcdValue = None
+ DatumType = None
+ MaxDatumSize = None
+ if 'COMMON' in PcdSetting:
+ PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']
+ if 'DEFAULT' in PcdSetting:
+ PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']
+ if SkuObj.SystemSkuId in PcdSetting:
+ PcdValue, DatumType, MaxDatumSize = PcdSetting[SkuObj.SystemSkuId]
+
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ DatumType,
+ PcdValue,
+ '',
+ MaxDatumSize,
+ {},
+ False,
+ None,
+ IsDsc=True)
+
+
+ return Pcds
+
+ def GetStructurePcdMaxSize(self, str_pcd):
+ pcd_default_value = str_pcd.DefaultValue
+ sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()]
+ sku_values.append(pcd_default_value)
+
+ def get_length(value):
+ Value = value.strip()
+ if Value.startswith('GUID') and Value.endswith(')'):
+ return 16
+ if Value.startswith('L"') and Value.endswith('"'):
+ return len(Value[2:-1])
+ if Value[0] == '"' and Value[-1] == '"':
+ return len(Value) - 2
+ if Value[0] == '{' and Value[-1] == '}':
+ return len(Value.split(","))
+ if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
+ return len(list(Value[2:-1]))
+ if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
+ return len(Value) - 2
+ return len(Value)
+
+ return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))
+
+ def IsFieldValueAnArray (self, Value):
+ Value = Value.strip()
+ if Value.startswith('GUID') and Value.endswith(')'):
+ return True
+ if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:
+ return True
+ if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:
+ return True
+ if Value[0] == '{' and Value[-1] == '}':
+ return True
+ if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
+ print 'foo = ', list(Value[2:-1])
+ return True
+ if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
+ print 'bar = ', list(Value[1:-1])
+ return True
+ return False
+
+ def ExecuteCommand (self, Command):
+ try:
+ Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ except:
+ print 'ERROR: Can not execute command:', Command
+ sys.exit(1)
+ Result = Process.communicate()
+ if Process.returncode <> 0:
+ print 'ERROR: Can not collect output from command:', Command
+ return Result[0], Result[1]
+
+ def IntToCString(self, Value, ValueSize):
+ Result = '"'
+ if not isinstance (Value, str):
+ for Index in range(0, ValueSize):
+ Result = Result + '\\x%02x' % (Value & 0xff)
+ Value = Value >> 8
+ Result = Result + '"'
+ return Result
+
+ def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp):
+ OverrideValues = None
+ if Pcd.SkuOverrideValues:
+ OverrideValues = Pcd.SkuOverrideValues[SkuName]
+ CApp = CApp + 'void\n'
+ CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ CApp = CApp + ' void\n'
+ CApp = CApp + ' )\n'
+ CApp = CApp + '{\n'
+ CApp = CApp + ' UINT32 Size;\n'
+ CApp = CApp + ' UINT32 FieldSize;\n'
+ CApp = CApp + ' UINT8 *Value;\n'
+ CApp = CApp + ' UINT32 OriginalSize;\n'
+ CApp = CApp + ' VOID *OriginalPcd;\n'
+ CApp = CApp + ' %s *Pcd;\n' % (Pcd.DatumType)
+ CApp = CApp + '\n'
+ InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, Pcd.DefaultValue)
+
+ #
+ # Get current PCD value and size
+ #
+ CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+
+ #
+ # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
+ # the correct value. For structures with a flexible array member, the flexible
+ # array member is detected, and the size is based on the highest index used with
+ # the flexible array member. The flexible array member must be the last field
+ # in a structure. The size formula for this case is:
+ # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
+ #
+ CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType)
+ for FieldList in [Pcd.DefaultValues, OverrideValues]:
+ if not FieldList:
+ continue
+ for FieldName in FieldList:
+ FieldName = "." + FieldName
+ IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
+ if IsArray:
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0])
+ CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."))
+ else:
+ NewFieldName = ''
+ while '[' in FieldName:
+ NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
+ ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+ FieldName = FieldName.split(']', 1)[1]
+ FieldName = NewFieldName + FieldName
+ while '[' in FieldName:
+ FieldName = FieldName.rsplit('[', 1)[0]
+ CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1)
+
+ #
+ # Allocate and zero buffer for the PCD
+ # Must handle cases where current value is smaller, larger, or same size
+ # Always keep that larger one as the current size
+ #
+ CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
+ CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType)
+ CApp = CApp + ' memset (Pcd, 0, Size);\n'
+
+ #
+ # Copy current PCD value into allocated buffer.
+ #
+ CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
+ CApp = CApp + ' free (OriginalPcd);\n'
+
+ #
+ # Assign field values in PCD
+ #
+ for FieldList in [Pcd.DefaultValues, Pcd.DefaultFromDSC, OverrideValues]:
+ if not FieldList:
+ continue
+ if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC:
+ IsArray = self.IsFieldValueAnArray(FieldList)
+ Value, ValueSize = ParseFieldValue (FieldList)
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC)
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC)
+ CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
+ continue
+
+ for FieldName in FieldList:
+ IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
+ CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
+ else:
+ if ValueSize > 4:
+ CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ else:
+ CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+
+ #
+ # Set new PCD value and size
+ #
+ CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+
+ #
+ # Free PCD
+ #
+ CApp = CApp + ' free (Pcd);\n'
+ CApp = CApp + '}\n'
+ CApp = CApp + '\n'
+ return InitByteValue, CApp
+
+ def GenerateByteArrayValue (self, StructuredPcds):
+ #
+ # Generate/Compile/Run C application to determine if there are any flexible array members
+ #
+ if not StructuredPcds:
+ return
+
+ InitByteValue = ""
+ CApp = PcdMainCHeader
+
+ Includes = {}
+ for PcdName in StructuredPcds:
+ Pcd = StructuredPcds[PcdName]
+ IncludeFile = Pcd.StructuredPcdIncludeFile
+ if IncludeFile not in Includes:
+ Includes[IncludeFile] = True
+ CApp = CApp + '#include <%s>\n' % (IncludeFile)
+ CApp = CApp + '\n'
+
+ for PcdName in StructuredPcds:
+ Pcd = StructuredPcds[PcdName]
+ if not Pcd.SkuOverrideValues:
+ InitByteValue, CApp = self.GenerateInitializeFunc('DEFAULT', 'STANDARD', Pcd, InitByteValue, CApp)
+ else:
+ for SkuName in Pcd.SkuOverrideValues:
+ for DefaultStoreName in Pcd.DefaultStoreName:
+ Pcd = StructuredPcds[PcdName]
+ InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
+
+ CApp = CApp + 'VOID\n'
+ CApp = CApp + 'PcdEntryPoint(\n'
+ CApp = CApp + ' VOID\n'
+ CApp = CApp + ' )\n'
+ CApp = CApp + '{\n'
+ for Pcd in StructuredPcds.values():
+ if not Pcd.SkuOverrideValues:
+ CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % ('DEFAULT', 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ else:
+ for SkuName in Pcd.SkuOverrideValues:
+ for DefaultStoreName in Pcd.DefaultStoreName:
+ CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ CApp = CApp + '}\n'
+
+ CApp = CApp + PcdMainCEntry + '\n'
+
+ if not os.path.exists(self.OutputPath):
+ os.makedirs(self.OutputPath)
+ CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
+ File = open (CAppBaseFileName + '.c', 'w')
+ File.write(CApp)
+ File.close()
+
+ MakeApp = PcdMakefileHeader
+ if sys.platform == "win32":
+ MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = '
+ else:
+ MakeApp = MakeApp + PcdGccMakefile
+ MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \
+ 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-error\n' + 'INCLUDE +='
+
+ PlatformInc = {}
+ for Cache in self._Bdb._CACHE_.values():
+ if Cache.MetaFile.Ext.lower() != '.dec':
+ continue
+ if Cache.Includes:
+ if str(Cache.MetaFile.Path) not in PlatformInc:
+ PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes
+
+ PcdDependDEC = []
+ for Pcd in StructuredPcds.values():
+ for PackageDec in Pcd.PackageDecs:
+ Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
+ if not os.path.exists(Package):
+ EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ if Package not in PcdDependDEC:
+ PcdDependDEC.append(Package)
+
+ if PlatformInc and PcdDependDEC:
+ for pkg in PcdDependDEC:
+ if pkg in PlatformInc:
+ for inc in PlatformInc[pkg]:
+ MakeApp += '-I' + str(inc) + ' '
+ MakeApp = MakeApp + '\n'
+ if sys.platform == "win32":
+ MakeApp = MakeApp + PcdMakefileEnd
+ MakeFileName = os.path.join(self.OutputPath, 'Makefile')
+ File = open (MakeFileName, 'w')
+ File.write(MakeApp)
+ File.close()
+
+ InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
+ OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
+ File = open (InputValueFile, 'w')
+ File.write(InitByteValue)
+ File.close()
+
+ if sys.platform == "win32":
+ StdOut, StdErr = self.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName))
+ else:
+ StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName))
+ Messages = StdOut.split('\r')
+ for Message in Messages:
+ if " error " in Message:
+ FileInfo = Message.strip().split('(')
+ if len (FileInfo) > 0:
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1].split (')')[0]
+ else:
+ FileInfo = Message.strip().split(':')
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1]
+
+ File = open (FileName, 'r')
+ FileData = File.readlines()
+ File.close()
+ error_line = FileData[int (FileLine) - 1]
+ if r"//" in error_line:
+ c_line,dsc_line = error_line.split(r"//")
+ else:
+ dsc_line = error_line
+
+ message_itmes = Message.split(":")
+ for item in message_itmes:
+ if "PcdValueInit.c" in item:
+ message_itmes[message_itmes.index(item)] = dsc_line.strip()
+
+ EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[1:]))
+
+ PcdValueInitExe = PcdValueInitName
+ if not sys.platform == "win32":
+ PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
+
+ StdOut, StdErr = self.ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile))
+ File = open (OutputValueFile, 'r')
+ FileBuffer = File.readlines()
+ File.close()
+
+ StructurePcdSet = []
+ for Pcd in FileBuffer:
+ PcdValue = Pcd.split ('|')
+ PcdInfo = PcdValue[0].split ('.')
+ StructurePcdSet.append((PcdInfo[0], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
+ return StructurePcdSet
+
+ ## Retrieve dynamic PCD settings
+ #
+ # @param Type PCD type
+ #
+ # @retval a dict object contains settings of given PCD type
+ #
+ def _GetDynamicPcd(self, Type):
+
+ SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds)
+
+ Pcds = sdict()
+ #
+ # tdict is a special dict kind of type, used for selecting correct
+ # PCD settings for certain ARCH and SKU
+ #
+ PcdDict = tdict(True, 4)
+ PcdList = []
+ # Find out all possible PCD candidates for self._Arch
+ RecordList = self._RawData[Type, self._Arch]
+ AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
+
+ AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0})
+
+ for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
+ if SkuName not in AvailableSkuIdSet:
+ EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName)
+ if "." not in TokenSpaceGuid:
+ PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))
+ PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
+
+ # Remove redundant PCD candidates, per the ARCH and SKU
+ for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
+
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
+ if Setting == None:
+ continue
+
+ PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue)
+ if (PcdCName, TokenSpaceGuid) in Pcds.keys():
+ pcdObject = Pcds[PcdCName, TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ if MaxDatumSize.strip():
+ CurrentMaxSize = int(MaxDatumSize.strip(), 0)
+ else:
+ CurrentMaxSize = 0
+ if pcdObject.MaxDatumSize:
+ PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
+ else:
+ PcdMaxSize = 0
+ if CurrentMaxSize > PcdMaxSize:
+ pcdObject.MaxDatumSize = str(CurrentMaxSize)
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ DatumType,
+ PcdValue,
+ '',
+ MaxDatumSize,
+ {SkuName : SkuInfo},
+ False,
+ None,
+ IsDsc=True)
+
+ for pcd in Pcds.values():
+ pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
+ if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)
+ pcd.SkuInfoList['DEFAULT'] = SkuInfo
+ elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
+ del(pcd.SkuInfoList['COMMON'])
+ elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ del(pcd.SkuInfoList['COMMON'])
+ if SkuObj.SkuUsageType == SkuObj.SINGLE:
+ if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
+ del(pcd.SkuInfoList['DEFAULT'])
+
+ return Pcds
+
+ def CompareVarAttr(self, Attr1, Attr2):
+ if not Attr1 or not Attr2: # for empty string
+ return True
+ Attr1s = [attr.strip() for attr in Attr1.split(",")]
+ Attr1Set = set(Attr1s)
+ Attr2s = [attr.strip() for attr in Attr2.split(",")]
+ Attr2Set = set(Attr2s)
+ if Attr2Set == Attr1Set:
+ return True
+ else:
+ return False
+ ## Retrieve dynamic HII PCD settings
+ #
+ # @param Type PCD type
+ #
+ # @retval a dict object contains settings of given PCD type
+ #
+ def _GetDynamicHiiPcd(self, Type):
+
+ SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds)
+ VariableAttrs = {}
+
+ Pcds = sdict()
+ #
+ # tdict is a special dict kind of type, used for selecting correct
+ # PCD settings for certain ARCH and SKU
+ #
+ PcdDict = tdict(True, 4)
+ PcdSet = set()
+ RecordList = self._RawData[Type, self._Arch]
+ # Find out all possible PCD candidates for self._Arch
+ AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
+
+ AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0})
+ for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
+ if SkuName not in AvailableSkuIdSet:
+ EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName)
+ if "." not in TokenSpaceGuid:
+ PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4))
+ PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
+
+
+ # Remove redundant PCD candidates, per the ARCH and SKU
+ for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
+
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
+ if Setting == None:
+ continue
+ VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+
+ rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
+ if not rt:
+ EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
+ ExtraData="[%s]" % VarAttribute)
+ ExceedMax = False
+ FormatCorrect = True
+ if VariableOffset.isdigit():
+ if int(VariableOffset, 10) > 0xFFFF:
+ ExceedMax = True
+ elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):
+ if int(VariableOffset, 16) > 0xFFFF:
+ ExceedMax = True
+ # For Offset written in "A.B"
+ elif VariableOffset.find('.') > -1:
+ VariableOffsetList = VariableOffset.split(".")
+ if not (len(VariableOffsetList) == 2
+ and IsValidWord(VariableOffsetList[0])
+ and IsValidWord(VariableOffsetList[1])):
+ FormatCorrect = False
+ else:
+ FormatCorrect = False
+ if not FormatCorrect:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
+
+ if ExceedMax:
+ EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
+ if (VariableName, VariableGuid) not in VariableAttrs:
+ VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
+ else:
+ if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
+ EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))
+
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute)
+ pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
+ if (PcdCName, TokenSpaceGuid) in Pcds.keys():
+ pcdObject = Pcds[PcdCName, TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ '',
+ DefaultValue,
+ '',
+ '',
+ {SkuName : SkuInfo},
+ False,
+ None,
+ pcdDecObject.validateranges,
+ pcdDecObject.validlists,
+ pcdDecObject.expressions,
+ IsDsc=True)
+
+
+ for pcd in Pcds.values():
+ SkuInfoObj = pcd.SkuInfoList.values()[0]
+ pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
+ # Only fix the value while no value provided in DSC file.
+ for sku in pcd.SkuInfoList.values():
+ if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue == None):
+ sku.HiiDefaultValue = pcdDecObject.DefaultValue
+ if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)
+ pcd.SkuInfoList['DEFAULT'] = SkuInfo
+ elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
+ del(pcd.SkuInfoList['COMMON'])
+ elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ del(pcd.SkuInfoList['COMMON'])
+
+ if SkuObj.SkuUsageType == SkuObj.SINGLE:
+ if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
+ del(pcd.SkuInfoList['DEFAULT'])
+
+ if pcd.MaxDatumSize.strip():
+ MaxSize = int(pcd.MaxDatumSize, 0)
+ else:
+ MaxSize = 0
+ if pcdDecObject.DatumType == 'VOID*':
+ for (skuname, skuobj) in pcd.SkuInfoList.items():
+ datalen = 0
+ if skuobj.HiiDefaultValue.startswith("L"):
+ datalen = (len(skuobj.HiiDefaultValue) - 3 + 1) * 2
+ elif skuobj.HiiDefaultValue.startswith("{"):
+ datalen = len(skuobj.HiiDefaultValue.split(","))
+ else:
+ datalen = len(skuobj.HiiDefaultValue) - 2 + 1
+ if datalen > MaxSize:
+ MaxSize = datalen
+ pcd.MaxDatumSize = str(MaxSize)
+ return Pcds
+
+
+ ## Retrieve dynamic VPD PCD settings
+ #
+ # @param Type PCD type
+ #
+ # @retval a dict object contains settings of given PCD type
+ #
+ def _GetDynamicVpdPcd(self, Type):
+
+ SkuObj = SkuClass(self.SkuIdentifier, self.SkuIds)
+
+ Pcds = sdict()
+ #
+ # tdict is a special dict kind of type, used for selecting correct
+ # PCD settings for certain ARCH and SKU
+ #
+ PcdDict = tdict(True, 4)
+ PcdList = []
+
+ # Find out all possible PCD candidates for self._Arch
+ RecordList = self._RawData[Type, self._Arch]
+ AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
+
+ AvailableSkuIdSet.update({'DEFAULT':0, 'COMMON':0})
+ for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
+ if SkuName not in AvailableSkuIdSet:
+ EdkLogger.error('Build', OPTION_VALUE_INVALID, "The SKUID name %s is not supported by the platform." % SkuName)
+ if "." not in TokenSpaceGuid:
+ PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4))
+ PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
+
+ # Remove redundant PCD candidates, per the ARCH and SKU
+ for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
+ if Setting == None:
+ continue
+ #
+ # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
+ # For the Integer & Boolean type, the optional data can only be InitialValue.
+ # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
+ # until the DEC parser has been called.
+ #
+ VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue)
+ if (PcdCName, TokenSpaceGuid) in Pcds.keys():
+ pcdObject = Pcds[PcdCName, TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ if MaxDatumSize.strip():
+ CurrentMaxSize = int(MaxDatumSize.strip(), 0)
+ else:
+ CurrentMaxSize = 0
+ if pcdObject.MaxDatumSize:
+ PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
+ else:
+ PcdMaxSize = 0
+ if CurrentMaxSize > PcdMaxSize:
+ pcdObject.MaxDatumSize = str(CurrentMaxSize)
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ '',
+ InitialValue,
+ '',
+ MaxDatumSize,
+ {SkuName : SkuInfo},
+ False,
+ None,
+ IsDsc=True)
+ for pcd in Pcds.values():
+ SkuInfoObj = pcd.SkuInfoList.values()[0]
+ pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
+ if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
+ pcd.SkuInfoList['DEFAULT'] = SkuInfo
+ elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
+ del(pcd.SkuInfoList['COMMON'])
+ elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ del(pcd.SkuInfoList['COMMON'])
+ if SkuObj.SkuUsageType == SkuObj.SINGLE:
+ if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
+ del(pcd.SkuInfoList['DEFAULT'])
+
+ return Pcds
+
+ ## Add external modules
+ #
+ # The external modules are mostly those listed in FDF file, which don't
+ # need "build".
+ #
+ # @param FilePath The path of module description file
+ #
+ def AddModule(self, FilePath):
+ FilePath = NormPath(FilePath)
+ if FilePath not in self.Modules:
+ Module = ModuleBuildClassObject()
+ Module.MetaFile = FilePath
+ self.Modules.append(Module)
+
+ ## Add external PCDs
+ #
+ # The external PCDs are mostly those listed in FDF file to specify address
+ # or offset information.
+ #
+ # @param Name Name of the PCD
+ # @param Guid Token space guid of the PCD
+ # @param Value Value of the PCD
+ #
+ def AddPcd(self, Name, Guid, Value):
+ if (Name, Guid) not in self.Pcds:
+ self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
+ self.Pcds[Name, Guid].DefaultValue = Value
+
+ _Macros = property(_GetMacros)
+ Arch = property(_GetArch, _SetArch)
+ Platform = property(_GetPlatformName)
+ PlatformName = property(_GetPlatformName)
+ Guid = property(_GetFileGuid)
+ Version = property(_GetVersion)
+ DscSpecification = property(_GetDscSpec)
+ OutputDirectory = property(_GetOutpuDir)
+ SupArchList = property(_GetSupArch)
+ BuildTargets = property(_GetBuildTarget)
+ SkuName = property(_GetSkuName, _SetSkuName)
+ SkuIdentifier = property(_GetSkuIdentifier)
+ AvilableSkuIds = property(_GetAviableSkuIds)
+ PcdInfoFlag = property(_GetPcdInfoFlag)
+ VarCheckFlag = property(_GetVarCheckFlag)
+ FlashDefinition = property(_GetFdfFile)
+ Prebuild = property(_GetPrebuild)
+ Postbuild = property(_GetPostbuild)
+ BuildNumber = property(_GetBuildNumber)
+ MakefileName = property(_GetMakefileName)
+ BsBaseAddress = property(_GetBsBaseAddress)
+ RtBaseAddress = property(_GetRtBaseAddress)
+ LoadFixAddress = property(_GetLoadFixAddress)
+ RFCLanguages = property(_GetRFCLanguages)
+ ISOLanguages = property(_GetISOLanguages)
+ VpdToolGuid = property(_GetVpdToolGuid)
+ SkuIds = property(_GetSkuIds)
+ Modules = property(_GetModules)
+ LibraryInstances = property(_GetLibraryInstances)
+ LibraryClasses = property(_GetLibraryClasses)
+ Pcds = property(_GetPcds)
+ BuildOptions = property(_GetBuildOptions)
diff --git a/BaseTools/Source/Python/Workspace/InfBuildData.py b/BaseTools/Source/Python/Workspace/InfBuildData.py
new file mode 100644
index 0000000000..71151402a2
--- /dev/null
+++ b/BaseTools/Source/Python/Workspace/InfBuildData.py
@@ -0,0 +1,1212 @@
+## @file
+# This file is used to create a database used by build tool
+#
+# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+from Common.String import *
+from Common.DataType import *
+from Common.Misc import *
+from types import *
+
+from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClassObject, PcdClassObject
+## Module build information from INF file
+#
+# This class is used to retrieve information stored in database and convert them
+# into ModuleBuildClassObject form for easier use for AutoGen.
+#
+class InfBuildData(ModuleBuildClassObject):
+ # dict used to convert PCD type in database to string used by build tool
+ _PCD_TYPE_STRING_ = {
+ MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
+ MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
+ MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
+ MODEL_PCD_DYNAMIC : "Dynamic",
+ MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
+ MODEL_PCD_DYNAMIC_HII : "DynamicHii",
+ MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
+ MODEL_PCD_DYNAMIC_EX : "DynamicEx",
+ MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
+ MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
+ MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
+ }
+
+ # dict used to convert part of [Defines] to members of InfBuildData directly
+ _PROPERTY_ = {
+ #
+ # Required Fields
+ #
+ TAB_INF_DEFINES_BASE_NAME : "_BaseName",
+ TAB_INF_DEFINES_FILE_GUID : "_Guid",
+ TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",
+ #
+ # Optional Fields
+ #
+ # TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
+ TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",
+ TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",
+ # TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
+ TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",
+ TAB_INF_DEFINES_VERSION_NUMBER : "_Version",
+ TAB_INF_DEFINES_VERSION_STRING : "_Version",
+ TAB_INF_DEFINES_VERSION : "_Version",
+ TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",
+ TAB_INF_DEFINES_SHADOW : "_Shadow",
+
+ TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath",
+ }
+
+ # dict used to convert Component type to Module type
+ _MODULE_TYPE_ = {
+ "LIBRARY" : "BASE",
+ "SECURITY_CORE" : "SEC",
+ "PEI_CORE" : "PEI_CORE",
+ "COMBINED_PEIM_DRIVER" : "PEIM",
+ "PIC_PEIM" : "PEIM",
+ "RELOCATABLE_PEIM" : "PEIM",
+ "PE32_PEIM" : "PEIM",
+ "BS_DRIVER" : "DXE_DRIVER",
+ "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
+ "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
+ "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
+ # "SMM_DRIVER" : "DXE_SMM_DRIVER",
+ # "BS_DRIVER" : "DXE_SMM_DRIVER",
+ # "BS_DRIVER" : "UEFI_DRIVER",
+ "APPLICATION" : "UEFI_APPLICATION",
+ "LOGO" : "BASE",
+ }
+
+ # regular expression for converting XXX_FLAGS in [nmake] section to new type
+ _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)
+ # dict used to convert old tool name used in [nmake] section to new ones
+ _TOOL_CODE_ = {
+ "C" : "CC",
+ "LIB" : "SLINK",
+ "LINK" : "DLINK",
+ }
+
+
+ ## Constructor of DscBuildData
+ #
+ # Initialize object of DscBuildData
+ #
+ # @param FilePath The path of platform description file
+ # @param RawData The raw data of DSC file
+ # @param 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
+ #
+ def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):
+ self.MetaFile = FilePath
+ self._ModuleDir = FilePath.Dir
+ self._RawData = RawData
+ self._Bdb = BuildDatabase
+ self._Arch = Arch
+ self._Target = Target
+ self._Toolchain = Toolchain
+ self._Platform = 'COMMON'
+ self._SourceOverridePath = None
+ if FilePath.Key in GlobalData.gOverrideDir:
+ self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]
+ self._Clear()
+
+ ## XXX[key] = value
+ def __setitem__(self, key, value):
+ self.__dict__[self._PROPERTY_[key]] = value
+
+ ## value = XXX[key]
+ def __getitem__(self, key):
+ return self.__dict__[self._PROPERTY_[key]]
+
+ ## "in" test support
+ def __contains__(self, key):
+ return key in self._PROPERTY_
+
+ ## Set all internal used members of InfBuildData to None
+ def _Clear(self):
+ self._HeaderComments = None
+ self._TailComments = None
+ self._Header_ = None
+ self._AutoGenVersion = None
+ 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._BinaryModule = 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 = None
+ self._Binaries = None
+ self._Sources = None
+ self._LibraryClasses = None
+ self._Libraries = None
+ self._Protocols = None
+ self._ProtocolComments = None
+ self._Ppis = None
+ self._PpiComments = None
+ self._Guids = None
+ self._GuidsUsedByPcd = sdict()
+ self._GuidComments = None
+ self._Includes = None
+ self._Packages = None
+ self._Pcds = None
+ self._PcdComments = None
+ self._BuildOptions = None
+ self._Depex = None
+ self._DepexExpression = None
+ self.__Macros = None
+
+ ## Get current effective macros
+ def _GetMacros(self):
+ if self.__Macros == None:
+ self.__Macros = {}
+ # EDK_GLOBAL defined macros can be applied to EDK module
+ if self.AutoGenVersion < 0x00010005:
+ self.__Macros.update(GlobalData.gEdkGlobal)
+ self.__Macros.update(GlobalData.gGlobalDefines)
+ return self.__Macros
+
+ ## Get architecture
+ def _GetArch(self):
+ return self._Arch
+
+ ## Set architecture
+ #
+ # Changing the default ARCH to another may affect all other information
+ # because all information in a platform may be ARCH-related. That's
+ # why we need to clear all internal used members, in order to cause all
+ # information to be re-retrieved.
+ #
+ # @param Value The value of ARCH
+ #
+ def _SetArch(self, Value):
+ if self._Arch == Value:
+ return
+ self._Arch = Value
+ self._Clear()
+
+ ## Return the name of platform employing this module
+ def _GetPlatform(self):
+ return self._Platform
+
+ ## Change the name of platform employing this module
+ #
+ # Changing the default name of platform to another may affect some information
+ # because they may be PLATFORM-related. That's why we need to clear all internal
+ # used members, in order to cause all information to be re-retrieved.
+ #
+ def _SetPlatform(self, Value):
+ if self._Platform == Value:
+ return
+ self._Platform = Value
+ self._Clear()
+ def _GetHeaderComments(self):
+ if not self._HeaderComments:
+ self._HeaderComments = []
+ RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]
+ for Record in RecordList:
+ self._HeaderComments.append(Record[0])
+ return self._HeaderComments
+ def _GetTailComments(self):
+ if not self._TailComments:
+ self._TailComments = []
+ RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]
+ for Record in RecordList:
+ self._TailComments.append(Record[0])
+ return self._TailComments
+ ## Retrieve all information in [Defines] section
+ #
+ # (Retriving all [Defines] information in one-shot is just to save time.)
+ #
+ 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
+ if self._Defs == None:
+ self._Defs = sdict()
+ 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'
+ if self._Specification == None:
+ self._Specification = sdict()
+ self._Specification[Name] = GetHexVerValue(Value)
+ if self._Specification[Name] == None:
+ 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':
+ if self._LibraryClass == None:
+ 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':
+ if self._ModuleEntryPointList == None:
+ self._ModuleEntryPointList = []
+ self._ModuleEntryPointList.append(Value)
+ elif Name == 'UNLOAD_IMAGE':
+ if self._ModuleUnloadImageList == None:
+ self._ModuleUnloadImageList = []
+ if not Value:
+ continue
+ self._ModuleUnloadImageList.append(Value)
+ elif Name == 'CONSTRUCTOR':
+ if self._ConstructorList == None:
+ self._ConstructorList = []
+ if not Value:
+ continue
+ self._ConstructorList.append(Value)
+ elif Name == 'DESTRUCTOR':
+ if self._DestructorList == None:
+ self._DestructorList = []
+ if not Value:
+ continue
+ self._DestructorList.append(Value)
+ elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:
+ TokenList = GetSplitValueList(Value)
+ if self._CustomMakefile == None:
+ self._CustomMakefile = {}
+ if len(TokenList) < 2:
+ self._CustomMakefile['MSFT'] = TokenList[0]
+ self._CustomMakefile['GCC'] = TokenList[0]
+ else:
+ if TokenList[0] not in ['MSFT', 'GCC']:
+ 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:
+ if self._Defs == None:
+ self._Defs = sdict()
+ self._Defs[Name] = Value
+ self._Macros[Name] = Value
+
+ #
+ # Retrieve information in sections specific to Edk.x modules
+ #
+ if self.AutoGenVersion >= 0x00010005:
+ 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 == 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 == 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 self._Defs and '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)
+
+ elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \
+ and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
+ self._BuildType = 'UEFI_HII'
+ else:
+ self._BuildType = self._ModuleType.upper()
+
+ 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 self.Sources == None:
+ self._Sources = []
+ self._Sources.append(File)
+ else:
+ if not self._ComponentType:
+ EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
+ "COMPONENT_TYPE is not given", File=self.MetaFile)
+ self._BuildType = self._ComponentType.upper()
+ if self._ComponentType in self._MODULE_TYPE_:
+ self._ModuleType = self._MODULE_TYPE_[self._ComponentType]
+ if self._ComponentType == 'LIBRARY':
+ self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]
+ # make use some [nmake] section macros
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ Macros['PROCESSOR'] = self._Arch
+ RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]
+ for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:
+ Value = ReplaceMacro(Value, Macros, True)
+ if Name == "IMAGE_ENTRY_POINT":
+ if self._ModuleEntryPointList == None:
+ self._ModuleEntryPointList = []
+ self._ModuleEntryPointList.append(Value)
+ elif Name == "DPX_SOURCE":
+ File = PathClass(NormPath(Value), 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 self.Sources == None:
+ self._Sources = []
+ self._Sources.append(File)
+ else:
+ ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)
+ if len(ToolList) == 0 or len(ToolList) != 1:
+ pass
+# EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
+# File=self.MetaFile, Line=LineNo)
+ else:
+ if self._BuildOptions == None:
+ self._BuildOptions = sdict()
+
+ if ToolList[0] in self._TOOL_CODE_:
+ Tool = self._TOOL_CODE_[ToolList[0]]
+ else:
+ Tool = ToolList[0]
+ ToolChain = "*_*_*_%s_FLAGS" % Tool
+ ToolChainFamily = 'MSFT' # Edk.x only support MSFT tool chain
+ # ignore not replaced macros in value
+ ValueList = GetSplitList(' ' + Value, '/D')
+ Dummy = ValueList[0]
+ for Index in range(1, len(ValueList)):
+ if ValueList[Index][-1] == '=' or ValueList[Index] == '':
+ continue
+ Dummy = Dummy + ' /D ' + ValueList[Index]
+ Value = Dummy.strip()
+ if (ToolChainFamily, ToolChain) not in self._BuildOptions:
+ self._BuildOptions[ToolChainFamily, ToolChain] = Value
+ else:
+ OptionString = self._BuildOptions[ToolChainFamily, ToolChain]
+ self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value
+ # set _Header to non-None in order to avoid database re-querying
+ self._Header_ = 'DUMMY'
+
+ ## Retrieve file version
+ def _GetInfVersion(self):
+ if self._AutoGenVersion == None:
+ 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)
+ self._AutoGenVersion = int('0x' + Major + Minor, 0)
+ else:
+ self._AutoGenVersion = int(Record[2], 0)
+ break
+ if self._AutoGenVersion == None:
+ self._AutoGenVersion = 0x00010000
+ return self._AutoGenVersion
+
+ ## Retrieve BASE_NAME
+ def _GetBaseName(self):
+ if self._BaseName == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._BaseName == None:
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)
+ return self._BaseName
+
+ ## Retrieve DxsFile
+ def _GetDxsFile(self):
+ if self._DxsFile == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._DxsFile == None:
+ self._DxsFile = ''
+ return self._DxsFile
+
+ ## Retrieve MODULE_TYPE
+ def _GetModuleType(self):
+ if self._ModuleType == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._ModuleType == None:
+ self._ModuleType = 'BASE'
+ if self._ModuleType not in SUP_MODULE_LIST:
+ self._ModuleType = "USER_DEFINED"
+ return self._ModuleType
+
+ ## Retrieve COMPONENT_TYPE
+ def _GetComponentType(self):
+ if self._ComponentType == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._ComponentType == None:
+ self._ComponentType = 'USER_DEFINED'
+ return self._ComponentType
+
+ ## Retrieve "BUILD_TYPE"
+ def _GetBuildType(self):
+ if self._BuildType == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if not self._BuildType:
+ self._BuildType = "BASE"
+ return self._BuildType
+
+ ## Retrieve file guid
+ def _GetFileGuid(self):
+ if self._Guid == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._Guid == None:
+ self._Guid = '00000000-0000-0000-0000-000000000000'
+ return self._Guid
+
+ ## Retrieve module version
+ def _GetVersion(self):
+ if self._Version == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._Version == None:
+ self._Version = '0.0'
+ return self._Version
+
+ ## Retrieve PCD_IS_DRIVER
+ def _GetPcdIsDriver(self):
+ if self._PcdIsDriver == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._PcdIsDriver == None:
+ self._PcdIsDriver = ''
+ return self._PcdIsDriver
+
+ ## Retrieve SHADOW
+ def _GetShadow(self):
+ if self._Shadow == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._Shadow != None and self._Shadow.upper() == 'TRUE':
+ self._Shadow = True
+ else:
+ self._Shadow = False
+ return self._Shadow
+
+ ## Retrieve CUSTOM_MAKEFILE
+ def _GetMakefile(self):
+ if self._CustomMakefile == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._CustomMakefile == None:
+ self._CustomMakefile = {}
+ return self._CustomMakefile
+
+ ## Retrieve EFI_SPECIFICATION_VERSION
+ def _GetSpec(self):
+ if self._Specification == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._Specification == None:
+ self._Specification = {}
+ return self._Specification
+
+ ## Retrieve LIBRARY_CLASS
+ def _GetLibraryClass(self):
+ if self._LibraryClass == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._LibraryClass == None:
+ self._LibraryClass = []
+ return self._LibraryClass
+
+ ## Retrieve ENTRY_POINT
+ def _GetEntryPoint(self):
+ if self._ModuleEntryPointList == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._ModuleEntryPointList == None:
+ self._ModuleEntryPointList = []
+ return self._ModuleEntryPointList
+
+ ## Retrieve UNLOAD_IMAGE
+ def _GetUnloadImage(self):
+ if self._ModuleUnloadImageList == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._ModuleUnloadImageList == None:
+ self._ModuleUnloadImageList = []
+ return self._ModuleUnloadImageList
+
+ ## Retrieve CONSTRUCTOR
+ def _GetConstructor(self):
+ if self._ConstructorList == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._ConstructorList == None:
+ self._ConstructorList = []
+ return self._ConstructorList
+
+ ## Retrieve DESTRUCTOR
+ def _GetDestructor(self):
+ if self._DestructorList == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._DestructorList == None:
+ self._DestructorList = []
+ return self._DestructorList
+
+ ## Retrieve definies other than above ones
+ def _GetDefines(self):
+ if self._Defs == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._Defs == None:
+ self._Defs = sdict()
+ return self._Defs
+
+ ## Retrieve binary files
+ def _GetBinaries(self):
+ if self._Binaries == None:
+ self._Binaries = []
+ RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ Macros['PROCESSOR'] = self._Arch
+ for Record in RecordList:
+ FileType = Record[0]
+ LineNo = Record[-1]
+ Target = 'COMMON'
+ FeatureFlag = []
+ if Record[2]:
+ TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
+ if TokenList:
+ Target = TokenList[0]
+ if len(TokenList) > 1:
+ FeatureFlag = Record[1:]
+
+ 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)
+ self._Binaries.append(File)
+ return self._Binaries
+
+ ## Retrieve binary files with error check.
+ def _GetBinaryFiles(self):
+ Binaries = self._GetBinaries()
+ if GlobalData.gIgnoreSource and Binaries == []:
+ ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)
+
+ return Binaries
+ ## Check whether it exists the binaries with current ARCH in AsBuild INF
+ def _IsSupportedArch(self):
+ if self._GetBinaries() and not self._GetSourceFiles():
+ return True
+ else:
+ return False
+ ## Retrieve source files
+ def _GetSourceFiles(self):
+ # Ignore all source files in a binary build mode
+ if GlobalData.gIgnoreSource:
+ self._Sources = []
+ return self._Sources
+
+ if self._Sources == None:
+ self._Sources = []
+ RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]
+ Macros = self._Macros
+ for Record in RecordList:
+ LineNo = Record[-1]
+ ToolChainFamily = Record[1]
+ TagName = Record[2]
+ ToolCode = Record[3]
+ FeatureFlag = Record[4]
+ if self.AutoGenVersion < 0x00010005:
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ Macros['PROCESSOR'] = self._Arch
+ SourceFile = NormPath(Record[0], Macros)
+ if SourceFile[0] == os.path.sep:
+ SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])
+ # old module source files (Edk)
+ File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,
+ '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)
+ if ErrorCode != 0:
+ if File.Ext.lower() == '.h':
+ EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,
+ File=self.MetaFile, Line=LineNo)
+ continue
+ else:
+ EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)
+ else:
+ File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',
+ '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate()
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
+
+ self._Sources.append(File)
+ return self._Sources
+
+ ## Retrieve library classes employed by this module
+ def _GetLibraryClassUses(self):
+ if self._LibraryClasses == None:
+ self._LibraryClasses = sdict()
+ 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)
+ self._LibraryClasses[Lib] = Instance
+ return self._LibraryClasses
+
+ ## Retrieve library names (for Edk.x style of modules)
+ def _GetLibraryNames(self):
+ if self._Libraries == None:
+ self._Libraries = []
+ 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 self._Libraries:
+ self._Libraries.append(LibraryName)
+ return self._Libraries
+
+ def _GetProtocolComments(self):
+ self._GetProtocols()
+ return self._ProtocolComments
+ ## Retrieve protocols consumed/produced by this module
+ def _GetProtocols(self):
+ if self._Protocols == None:
+ self._Protocols = sdict()
+ self._ProtocolComments = sdict()
+ RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]
+ for Record in RecordList:
+ CName = Record[0]
+ Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)
+ if Value == 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])
+ self._Protocols[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._ProtocolComments[CName] = Comments
+ return self._Protocols
+
+ def _GetPpiComments(self):
+ self._GetPpis()
+ return self._PpiComments
+ ## Retrieve PPIs consumed/produced by this module
+ def _GetPpis(self):
+ if self._Ppis == None:
+ self._Ppis = sdict()
+ self._PpiComments = sdict()
+ RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]
+ for Record in RecordList:
+ CName = Record[0]
+ Value = PpiValue(CName, self.Packages, self.MetaFile.Path)
+ if Value == 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])
+ self._Ppis[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._PpiComments[CName] = Comments
+ return self._Ppis
+
+ def _GetGuidComments(self):
+ self._GetGuids()
+ return self._GuidComments
+ ## Retrieve GUIDs consumed/produced by this module
+ def _GetGuids(self):
+ if self._Guids == None:
+ self._Guids = sdict()
+ self._GuidComments = sdict()
+ RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]
+ for Record in RecordList:
+ CName = Record[0]
+ Value = GuidValue(CName, self.Packages, self.MetaFile.Path)
+ if Value == 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])
+ self._Guids[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._GuidComments[CName] = Comments
+ return self._Guids
+
+ ## Retrieve include paths necessary for this module (for Edk.x style of modules)
+ def _GetIncludes(self):
+ if self._Includes == None:
+ self._Includes = []
+ if self._SourceOverridePath:
+ self._Includes.append(self._SourceOverridePath)
+
+ Macros = self._Macros
+ if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():
+ Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']
+ else:
+ Macros['PROCESSOR'] = self._Arch
+ RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]
+ for Record in RecordList:
+ if Record[0].find('EDK_SOURCE') > -1:
+ Macros['EDK_SOURCE'] = GlobalData.gEcpSource
+ File = NormPath(Record[0], self._Macros)
+ if File[0] == '.':
+ File = os.path.join(self._ModuleDir, File)
+ else:
+ File = os.path.join(GlobalData.gWorkspace, File)
+ File = RealPath(os.path.normpath(File))
+ if File:
+ self._Includes.append(File)
+
+ # TRICK: let compiler to choose correct header file
+ Macros['EDK_SOURCE'] = GlobalData.gEdkSource
+ File = NormPath(Record[0], self._Macros)
+ if File[0] == '.':
+ File = os.path.join(self._ModuleDir, File)
+ else:
+ File = os.path.join(GlobalData.gWorkspace, File)
+ File = RealPath(os.path.normpath(File))
+ if File:
+ self._Includes.append(File)
+ else:
+ File = NormPath(Record[0], Macros)
+ if File[0] == '.':
+ File = os.path.join(self._ModuleDir, File)
+ else:
+ File = mws.join(GlobalData.gWorkspace, File)
+ File = RealPath(os.path.normpath(File))
+ if File:
+ self._Includes.append(File)
+ if not File and Record[0].find('EFI_SOURCE') > -1:
+ # tricky to regard WorkSpace as EFI_SOURCE
+ Macros['EFI_SOURCE'] = GlobalData.gWorkspace
+ File = NormPath(Record[0], Macros)
+ if File[0] == '.':
+ File = os.path.join(self._ModuleDir, File)
+ else:
+ File = os.path.join(GlobalData.gWorkspace, File)
+ File = RealPath(os.path.normpath(File))
+ if File:
+ self._Includes.append(File)
+ return self._Includes
+
+ ## Retrieve packages this module depends on
+ def _GetPackages(self):
+ if self._Packages == None:
+ self._Packages = []
+ RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]
+ Macros = self._Macros
+ Macros['EDK_SOURCE'] = GlobalData.gEcpSource
+ for Record in RecordList:
+ File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
+ LineNo = Record[-1]
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate('.dec')
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
+ # parse this package now. we need it to get protocol/ppi/guid value
+ Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
+ self._Packages.append(Package)
+ return self._Packages
+
+ ## Retrieve PCD comments
+ def _GetPcdComments(self):
+ self._GetPcds()
+ return self._PcdComments
+ ## Retrieve PCDs used in this module
+ def _GetPcds(self):
+ if self._Pcds == None:
+ self._Pcds = sdict()
+ self._PcdComments = sdict()
+ 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
+
+ ## Retrieve build options specific to this module
+ def _GetBuildOptions(self):
+ if self._BuildOptions == None:
+ self._BuildOptions = sdict()
+ 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
+ def _GetDepex(self):
+ if self._Depex == None:
+ self._Depex = tdict(False, 2)
+ RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
+
+ # If the module has only Binaries and no Sources, then ignore [Depex]
+ if self.Sources == None or self.Sources == []:
+ if self.Binaries != None and self.Binaries != []:
+ return self._Depex
+
+ # PEIM and DXE drivers must have a valid [Depex] section
+ if len(self.LibraryClass) == 0 and len(RecordList) == 0:
+ if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \
+ self.ModuleType == 'DXE_SAL_DRIVER' or self.ModuleType == 'DXE_RUNTIME_DRIVER':
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
+ % self.ModuleType, File=self.MetaFile)
+
+ if len(RecordList) != 0 and self.ModuleType == 'USER_DEFINED':
+ for Record in RecordList:
+ if Record[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
+ EdkLogger.error('build', FORMAT_INVALID,
+ "'%s' module must specify the type of [Depex] section" % self.ModuleType,
+ File=self.MetaFile)
+
+ Depex = sdict()
+ 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 Depex:
+ Depex[Arch, ModuleType] = []
+ DepexList = Depex[Arch, ModuleType]
+ for Token in TokenList:
+ if Token in DEPEX_SUPPORTED_OPCODE:
+ DepexList.append(Token)
+ elif Token.endswith(".inf"): # module file name
+ ModuleFile = os.path.normpath(Token)
+ Module = self.BuildDatabase[ModuleFile]
+ if Module == 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:
+ # get the GUID value now
+ Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)
+ if Value == None:
+ Value = PpiValue(Token, self.Packages, self.MetaFile.Path)
+ if Value == None:
+ Value = GuidValue(Token, self.Packages, self.MetaFile.Path)
+ if Value == 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 Depex:
+ self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]
+ return self._Depex
+
+ ## Retrieve depedency expression
+ def _GetDepexExpression(self):
+ if self._DepexExpression == None:
+ self._DepexExpression = tdict(False, 2)
+ RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
+ DepexExpression = sdict()
+ 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 DepexExpression:
+ DepexExpression[Arch, ModuleType] = ''
+ for Token in TokenList:
+ DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '
+ for Arch, ModuleType in DepexExpression:
+ self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]
+ return self._DepexExpression
+
+ def GetGuidsUsedByPcd(self):
+ return self._GuidsUsedByPcd
+ ## Retrieve PCD for given type
+ def _GetPcd(self, Type):
+ Pcds = sdict()
+ 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))
+ # get the guid value
+ if TokenSpaceGuid not in self.Guids:
+ Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)
+ if Value == 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)
+ self.Guids[TokenSpaceGuid] = Value
+ self._GuidsUsedByPcd[TokenSpaceGuid] = Value
+ 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
+ for PcdCName, TokenSpaceGuid in PcdList:
+ PcdRealName = PcdCName
+ Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]
+ if Setting == None:
+ 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
+ #
+ # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
+ #
+ PcdType = self._PCD_TYPE_STRING_[Type]
+ if Type == MODEL_PCD_DYNAMIC:
+ Pcd.Pending = True
+ for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
+ 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.
+ #
+ if Pcd.TokenValue == None or Pcd.TokenValue == "":
+ 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"):
+ if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:
+ 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
+ if Pcd.DefaultValue in [None, '']:
+ Pcd.DefaultValue = PcdInPackage.DefaultValue
+ 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,
+ ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])
+ )
+ Pcds[PcdCName, TokenSpaceGuid] = Pcd
+
+ return Pcds
+
+ ## check whether current module is binary module
+ def _IsBinaryModule(self):
+ if self.Binaries and not self.Sources:
+ return True
+ elif GlobalData.gIgnoreSource:
+ return True
+ else:
+ return False
+
+ _Macros = property(_GetMacros)
+ Arch = property(_GetArch, _SetArch)
+ Platform = property(_GetPlatform, _SetPlatform)
+
+ HeaderComments = property(_GetHeaderComments)
+ TailComments = property(_GetTailComments)
+ AutoGenVersion = property(_GetInfVersion)
+ BaseName = property(_GetBaseName)
+ ModuleType = property(_GetModuleType)
+ ComponentType = property(_GetComponentType)
+ BuildType = property(_GetBuildType)
+ Guid = property(_GetFileGuid)
+ Version = property(_GetVersion)
+ PcdIsDriver = property(_GetPcdIsDriver)
+ Shadow = property(_GetShadow)
+ CustomMakefile = property(_GetMakefile)
+ Specification = property(_GetSpec)
+ LibraryClass = property(_GetLibraryClass)
+ ModuleEntryPointList = property(_GetEntryPoint)
+ ModuleUnloadImageList = property(_GetUnloadImage)
+ ConstructorList = property(_GetConstructor)
+ DestructorList = property(_GetDestructor)
+ Defines = property(_GetDefines)
+ DxsFile = property(_GetDxsFile)
+
+ Binaries = property(_GetBinaryFiles)
+ Sources = property(_GetSourceFiles)
+ LibraryClasses = property(_GetLibraryClassUses)
+ Libraries = property(_GetLibraryNames)
+ Protocols = property(_GetProtocols)
+ ProtocolComments = property(_GetProtocolComments)
+ Ppis = property(_GetPpis)
+ PpiComments = property(_GetPpiComments)
+ Guids = property(_GetGuids)
+ GuidComments = property(_GetGuidComments)
+ Includes = property(_GetIncludes)
+ Packages = property(_GetPackages)
+ Pcds = property(_GetPcds)
+ PcdComments = property(_GetPcdComments)
+ BuildOptions = property(_GetBuildOptions)
+ Depex = property(_GetDepex)
+ DepexExpression = property(_GetDepexExpression)
+ IsBinaryModule = property(_IsBinaryModule)
+ IsSupportedArch = property(_IsSupportedArch)
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index b756361afd..6a30d45b3d 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -19,6 +19,7 @@ import Common.LongFilePathOs as os
import re
import time
import copy
+import md5
import Common.EdkLogger as EdkLogger
import Common.GlobalData as GlobalData
@@ -1116,6 +1117,11 @@ class DscParser(MetaFileParser):
def _PcdParser(self):
TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
+ PcdNameTockens = GetSplitValueList(TokenList[0], TAB_SPLIT)
+ if len(PcdNameTockens) == 2:
+ self._ValueList[0], self._ValueList[1] = PcdNameTockens[0], PcdNameTockens[1]
+ elif len(PcdNameTockens) == 3:
+ self._ValueList[0], self._ValueList[1] = ".".join((PcdNameTockens[0], PcdNameTockens[1])), PcdNameTockens[2]
if len(TokenList) == 2:
self._ValueList[2] = TokenList[1]
if self._ValueList[0] == '' or self._ValueList[1] == '':
@@ -1134,7 +1140,7 @@ class DscParser(MetaFileParser):
# Validate the datum type of Dynamic Defaul PCD and DynamicEx Default PCD
ValueList = GetSplitValueList(self._ValueList[2])
- if len(ValueList) > 1 and ValueList[1] != TAB_VOID \
+ if len(ValueList) > 1 and ValueList[1] in [TAB_UINT8 , TAB_UINT16, TAB_UINT32 , TAB_UINT64] \
and self._ItemType in [MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT]:
EdkLogger.error('Parser', FORMAT_INVALID, "The datum type '%s' of PCD is wrong" % ValueList[1],
ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
@@ -1560,7 +1566,7 @@ class DscParser(MetaFileParser):
EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self._FileWithError, Line=self._LineIndex + 1,
ExtraData="%s.%s|%s" % (self._ValueList[0], self._ValueList[1], self._ValueList[2]))
PcdValue = ValList[Index]
- if PcdValue:
+ if PcdValue and "." not in self._ValueList[0]:
try:
ValList[Index] = ValueExpression(PcdValue, self._Macros)(True)
except WrnExpression, Value:
@@ -1574,7 +1580,10 @@ class DscParser(MetaFileParser):
if (not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack):
GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue
self._Symbols[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue
- self._ValueList[2] = '|'.join(ValList)
+ try:
+ self._ValueList[2] = '|'.join(ValList)
+ except Exception:
+ print ValList
def __ProcessComponent(self):
self._ValueList[0] = ReplaceMacro(self._ValueList[0], self._Macros)
@@ -1655,6 +1664,10 @@ class DecParser(MetaFileParser):
self._AllPCDs = [] # Only for check duplicate PCD
self._AllPcdDict = {}
+ self._CurrentStructurePcdName = ""
+ self._include_flag = False
+ self._package_flag = False
+
## Parser starter
def Start(self):
Content = ''
@@ -1847,105 +1860,143 @@ class DecParser(MetaFileParser):
#
@ParseMacro
def _PcdParser(self):
- TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
- self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
- ValueRe = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*')
- # check PCD information
- if self._ValueList[0] == '' or self._ValueList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
- ExtraData=self._CurrentLine + \
- " (.|||)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check format of token space GUID CName
- if not ValueRe.match(self._ValueList[0]):
- EdkLogger.error('Parser', FORMAT_INVALID, "The format of the token space GUID CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
- ExtraData=self._CurrentLine + \
- " (.|||)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check format of PCD CName
- if not ValueRe.match(self._ValueList[1]):
- EdkLogger.error('Parser', FORMAT_INVALID, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
- ExtraData=self._CurrentLine + \
- " (.|||)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check PCD datum information
- if len(TokenList) < 2 or TokenList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",
- ExtraData=self._CurrentLine + \
- " (.|||)",
- File=self.MetaFile, Line=self._LineIndex + 1)
+ if self._CurrentStructurePcdName:
+ self._ValueList[0] = self._CurrentStructurePcdName
+
+ if "|" not in self._CurrentLine:
+ if "" == self._CurrentLine:
+ self._include_flag = True
+ self._ValueList = None
+ return
+ if "" == self._CurrentLine:
+ self._package_flag = True
+ self._ValueList = None
+ return
+
+ if self._include_flag:
+ self._ValueList[1] = "_" + md5.new(self._CurrentLine).hexdigest()
+ self._ValueList[2] = self._CurrentLine
+ self._include_flag = False
+ if self._package_flag and "}" != self._CurrentLine:
+ self._ValueList[1] = "_" + md5.new(self._CurrentLine).hexdigest()
+ self._ValueList[2] = self._CurrentLine
+ if self._CurrentLine == "}":
+ self._package_flag = False
+ self._ValueList = None
+ return
+ else:
+ PcdTockens = self._CurrentLine.split(TAB_VALUE_SPLIT)
+ PcdNames = PcdTockens[0].split(TAB_SPLIT)
+ if len(PcdNames) == 2:
+ self._CurrentStructurePcdName = ""
+ else:
+ self._ValueList[1] = PcdNames[2]
+ self._ValueList[2] = PcdTockens[1]
+ if not self._CurrentStructurePcdName:
+ TokenList = GetSplitValueList(self._CurrentLine, TAB_VALUE_SPLIT, 1)
+ self._ValueList[0:1] = GetSplitValueList(TokenList[0], TAB_SPLIT)
+ ValueRe = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*')
+ # check PCD information
+ if self._ValueList[0] == '' or self._ValueList[1] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "No token space GUID or PCD name specified",
+ ExtraData=self._CurrentLine + \
+ " (.|||)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check format of token space GUID CName
+ if not ValueRe.match(self._ValueList[0]):
+ EdkLogger.error('Parser', FORMAT_INVALID, "The format of the token space GUID CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
+ ExtraData=self._CurrentLine + \
+ " (.|||)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check format of PCD CName
+ if not ValueRe.match(self._ValueList[1]):
+ EdkLogger.error('Parser', FORMAT_INVALID, "The format of the PCD CName is invalid. The correct format is '(a-zA-Z_)[a-zA-Z0-9_]*'",
+ ExtraData=self._CurrentLine + \
+ " (.|||)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check PCD datum information
+ if len(TokenList) < 2 or TokenList[1] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "No PCD Datum information given",
+ ExtraData=self._CurrentLine + \
+ " (.|||)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
- ValueRe = re.compile(r'^\s*L?\".*\|.*\"')
- PtrValue = ValueRe.findall(TokenList[1])
+ ValueRe = re.compile(r'^\s*L?\".*\|.*\"')
+ PtrValue = ValueRe.findall(TokenList[1])
- # Has VOID* type string, may contain "|" character in the string.
- if len(PtrValue) != 0:
- ptrValueList = re.sub(ValueRe, '', TokenList[1])
- ValueList = AnalyzePcdExpression(ptrValueList)
- ValueList[0] = PtrValue[0]
- else:
- ValueList = AnalyzePcdExpression(TokenList[1])
+ # Has VOID* type string, may contain "|" character in the string.
+ if len(PtrValue) != 0:
+ ptrValueList = re.sub(ValueRe, '', TokenList[1])
+ ValueList = AnalyzePcdExpression(ptrValueList)
+ ValueList[0] = PtrValue[0]
+ else:
+ ValueList = AnalyzePcdExpression(TokenList[1])
- # check if there's enough datum information given
- if len(ValueList) != 3:
- EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given",
- ExtraData=self._CurrentLine + \
- " (.|||)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check default value
- if ValueList[0] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information",
- ExtraData=self._CurrentLine + \
- " (.|||)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check datum type
- if ValueList[1] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information",
- ExtraData=self._CurrentLine + \
- " (.|||)",
- File=self.MetaFile, Line=self._LineIndex + 1)
- # check token of the PCD
- if ValueList[2] == '':
- EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information",
- ExtraData=self._CurrentLine + \
- " (.|||)",
- File=self.MetaFile, Line=self._LineIndex + 1)
+ # check if there's enough datum information given
+ if len(ValueList) != 3:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid PCD Datum information given",
+ ExtraData=self._CurrentLine + \
+ " (.|||)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check default value
+ if ValueList[0] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "Missing DefaultValue in PCD Datum information",
+ ExtraData=self._CurrentLine + \
+ " (.|||)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check datum type
+ if ValueList[1] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "Missing DatumType in PCD Datum information",
+ ExtraData=self._CurrentLine + \
+ " (.|||)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
+ # check token of the PCD
+ if ValueList[2] == '':
+ EdkLogger.error('Parser', FORMAT_INVALID, "Missing Token in PCD Datum information",
+ ExtraData=self._CurrentLine + \
+ " (.|||)",
+ File=self.MetaFile, Line=self._LineIndex + 1)
- PcdValue = ValueList[0]
- if PcdValue:
- try:
- ValueList[0] = ValueExpression(PcdValue, self._AllPcdDict)(True)
- except WrnExpression, Value:
- ValueList[0] = Value.result
+ PcdValue = ValueList[0]
+ if PcdValue:
+ try:
+ ValueList[0] = ValueExpression(PcdValue, self._AllPcdDict)(True)
+ except WrnExpression, Value:
+ ValueList[0] = Value.result
- if ValueList[0] == 'True':
- ValueList[0] = '1'
- if ValueList[0] == 'False':
- ValueList[0] = '0'
+ if ValueList[0] == 'True':
+ ValueList[0] = '1'
+ if ValueList[0] == 'False':
+ ValueList[0] = '0'
- # check format of default value against the datum type
- IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])
- if not IsValid:
- EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,
- File=self.MetaFile, Line=self._LineIndex + 1)
+ # check format of default value against the datum type
+ IsValid, Cause = CheckPcdDatum(ValueList[1], ValueList[0])
+ if not IsValid:
+ EdkLogger.error('Parser', FORMAT_INVALID, Cause, ExtraData=self._CurrentLine,
+ File=self.MetaFile, Line=self._LineIndex + 1)
- if ValueList[0] in ['True', 'true', 'TRUE']:
- ValueList[0] = '1'
- elif ValueList[0] in ['False', 'false', 'FALSE']:
- ValueList[0] = '0'
+ if Cause == "StructurePcd":
+ self._CurrentStructurePcdName = TAB_SPLIT.join(self._ValueList[0:2])
+ self._ValueList[0] = self._CurrentStructurePcdName
+ self._ValueList[1] = ValueList[1].strip()
- # check for duplicate PCD definition
- if (self._Scope[0], self._ValueList[0], self._ValueList[1]) in self._AllPCDs:
- EdkLogger.error('Parser', FORMAT_INVALID,
- "The same PCD name and GUID have been already defined",
- ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
- else:
- self._AllPCDs.append((self._Scope[0], self._ValueList[0], self._ValueList[1]))
- self._AllPcdDict[TAB_SPLIT.join(self._ValueList[0:2])] = ValueList[0]
+ if ValueList[0] in ['True', 'true', 'TRUE']:
+ ValueList[0] = '1'
+ elif ValueList[0] in ['False', 'false', 'FALSE']:
+ ValueList[0] = '0'
- self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip()
+ # check for duplicate PCD definition
+ if (self._Scope[0], self._ValueList[0], self._ValueList[1]) in self._AllPCDs:
+ EdkLogger.error('Parser', FORMAT_INVALID,
+ "The same PCD name and GUID have been already defined",
+ ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
+ else:
+ self._AllPCDs.append((self._Scope[0], self._ValueList[0], self._ValueList[1]))
+ self._AllPcdDict[TAB_SPLIT.join(self._ValueList[0:2])] = ValueList[0]
+
+ self._ValueList[2] = ValueList[0].strip() + '|' + ValueList[1].strip() + '|' + ValueList[2].strip()
_SectionParser = {
MODEL_META_DATA_HEADER : MetaFileParser._DefineParser,
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
index c224b8e0e6..67aa530526 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceCommon.py
@@ -15,6 +15,7 @@ from Common.Misc import sdict
from Common.DataType import SUP_MODULE_USER_DEFINED
from BuildClassObject import LibraryClassObject
import Common.GlobalData as GlobalData
+from Workspace.BuildClassObject import StructurePcd
## Get all packages from platform for specified arch, target and toolchain
#
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
index 2c4b973901..a3407d113e 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
@@ -16,2845 +16,18 @@
# Import Modules
#
import sqlite3
-import Common.LongFilePathOs as os
-import pickle
-import uuid
-
-import Common.EdkLogger as EdkLogger
-import Common.GlobalData as GlobalData
-from Common.MultipleWorkspace import MultipleWorkspace as mws
-
from Common.String import *
from Common.DataType import *
from Common.Misc import *
from types import *
-from CommonDataClass.CommonClass import SkuInfoClass
-
from MetaDataTable import *
from MetaFileTable import *
from MetaFileParser import *
-from BuildClassObject import *
-from WorkspaceCommon import GetDeclaredPcd
-from Common.Misc import AnalyzeDscPcd
-from Common.Misc import ProcessDuplicatedInf
-import re
-from Common.Parsing import IsValidWord
-from Common.VariableAttributes import VariableAttributes
-import Common.GlobalData as GlobalData
-## Platform build information from DSC file
-#
-# This class is used to retrieve information stored in database and convert them
-# into PlatformBuildClassObject form for easier use for AutoGen.
-#
-class DscBuildData(PlatformBuildClassObject):
- # dict used to convert PCD type in database to string used by build tool
- _PCD_TYPE_STRING_ = {
- MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
- MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
- MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
- MODEL_PCD_DYNAMIC : "Dynamic",
- MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
- MODEL_PCD_DYNAMIC_HII : "DynamicHii",
- MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
- MODEL_PCD_DYNAMIC_EX : "DynamicEx",
- MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
- MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
- MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
- }
-
- # dict used to convert part of [Defines] to members of DscBuildData directly
- _PROPERTY_ = {
- #
- # Required Fields
- #
- TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",
- TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",
- TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",
- TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",
- #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
- #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
- #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
- TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
- #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
- TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",
- TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",
- TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",
- TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",
- #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
- #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
- }
-
- # used to compose dummy library class name for those forced library instances
- _NullLibraryNumber = 0
-
- ## Constructor of DscBuildData
- #
- # Initialize object of DscBuildData
- #
- # @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 (not used for DscBuildData)
- # @param Macros Macros used for replacement in DSC file
- #
- def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):
- self.MetaFile = FilePath
- self._RawData = RawData
- self._Bdb = BuildDataBase
- self._Arch = Arch
- self._Target = Target
- self._Toolchain = Toolchain
- self._Clear()
- self._HandleOverridePath()
-
- ## 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 DscBuildData to None
- def _Clear(self):
- self._Header = None
- self._PlatformName = None
- self._Guid = None
- self._Version = None
- self._DscSpecification = None
- self._OutputDirectory = None
- self._SupArchList = None
- self._BuildTargets = None
- self._SkuName = None
- self._SkuIdentifier = None
- self._AvilableSkuIds = None
- self._PcdInfoFlag = None
- self._VarCheckFlag = None
- self._FlashDefinition = None
- self._Prebuild = None
- self._Postbuild = None
- self._BuildNumber = None
- self._MakefileName = None
- self._BsBaseAddress = None
- self._RtBaseAddress = None
- self._SkuIds = None
- self._Modules = None
- self._LibraryInstances = None
- self._LibraryClasses = None
- self._Pcds = None
- self._DecPcds = None
- self._BuildOptions = None
- self._ModuleTypeOptions = None
- self._LoadFixAddress = None
- self._RFCLanguages = None
- self._ISOLanguages = None
- self._VpdToolGuid = None
- self.__Macros = None
-
-
- ## handle Override Path of Module
- def _HandleOverridePath(self):
- RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
- Macros = self._Macros
- Macros["EDK_SOURCE"] = GlobalData.gEcpSource
- for Record in RecordList:
- ModuleId = Record[5]
- LineNo = Record[6]
- ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)
- RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]
- if RecordList != []:
- SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))
-
- # Check if the source override path exists
- if not os.path.isdir(SourceOverridePath):
- EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)
-
- #Add to GlobalData Variables
- GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath
-
- ## Get current effective macros
- def _GetMacros(self):
- if self.__Macros == None:
- self.__Macros = {}
- self.__Macros.update(GlobalData.gPlatformDefines)
- self.__Macros.update(GlobalData.gGlobalDefines)
- self.__Macros.update(GlobalData.gCommandLineDefines)
- return self.__Macros
-
- ## Get architecture
- def _GetArch(self):
- return self._Arch
-
- ## Set architecture
- #
- # Changing the default ARCH to another may affect all other information
- # because all information in a platform may be ARCH-related. That's
- # why we need to clear all internal used members, in order to cause all
- # information to be re-retrieved.
- #
- # @param Value The value of ARCH
- #
- def _SetArch(self, Value):
- if self._Arch == Value:
- return
- self._Arch = Value
- self._Clear()
-
- ## Retrieve all information in [Defines] section
- #
- # (Retriving 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]
- # items defined _PROPERTY_ don't need additional processing
-
- # some special items in [Defines] section need special treatment
- if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
- self._OutputDirectory = NormPath(Record[2], self._Macros)
- if ' ' in self._OutputDirectory:
- EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",
- File=self.MetaFile, Line=Record[-1],
- ExtraData=self._OutputDirectory)
- elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:
- self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
- ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],
- ExtraData=ErrorInfo)
- elif Name == TAB_DSC_PREBUILD:
- PrebuildValue = Record[2]
- if Record[2][0] == '"':
- if Record[2][-1] != '"':
- EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,
- File=self.MetaFile, Line=Record[-1])
- PrebuildValue = Record[2][1:-1]
- self._Prebuild = PrebuildValue
- elif Name == TAB_DSC_POSTBUILD:
- PostbuildValue = Record[2]
- if Record[2][0] == '"':
- if Record[2][-1] != '"':
- EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,
- File=self.MetaFile, Line=Record[-1])
- PostbuildValue = Record[2][1:-1]
- self._Postbuild = PostbuildValue
- elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:
- self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
- elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
- self._BuildTargets = GetSplitValueList(Record[2])
- elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
- if self._SkuName == None:
- self._SkuName = Record[2]
- self._SkuIdentifier = Record[2]
- self._AvilableSkuIds = Record[2]
- elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:
- self._PcdInfoFlag = Record[2]
- elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:
- self._VarCheckFlag = Record[2]
- elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
- try:
- self._LoadFixAddress = int (Record[2], 0)
- except:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))
- elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:
- if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
- File=self.MetaFile, Line=Record[-1])
- LanguageCodes = Record[2][1:-1]
- if not LanguageCodes:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
- File=self.MetaFile, Line=Record[-1])
- LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)
- # check whether there is empty entries in the list
- if None in LanguageList:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',
- File=self.MetaFile, Line=Record[-1])
- self._RFCLanguages = LanguageList
- elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:
- if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
- File=self.MetaFile, Line=Record[-1])
- LanguageCodes = Record[2][1:-1]
- if not LanguageCodes:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
- File=self.MetaFile, Line=Record[-1])
- if len(LanguageCodes)%3:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',
- File=self.MetaFile, Line=Record[-1])
- LanguageList = []
- for i in range(0, len(LanguageCodes), 3):
- LanguageList.append(LanguageCodes[i:i+3])
- self._ISOLanguages = LanguageList
- elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:
- #
- # try to convert GUID to a real UUID value to see whether the GUID is format
- # for VPD_TOOL_GUID is correct.
- #
- try:
- uuid.UUID(Record[2])
- except:
- EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
- self._VpdToolGuid = Record[2]
- elif Name in self:
- self[Name] = Record[2]
- # set _Header to non-None in order to avoid database re-querying
- self._Header = 'DUMMY'
-
- ## Retrieve platform name
- def _GetPlatformName(self):
- if self._PlatformName == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._PlatformName == None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)
- return self._PlatformName
-
- ## Retrieve file guid
- def _GetFileGuid(self):
- if self._Guid == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._Guid == None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)
- return self._Guid
-
- ## Retrieve platform version
- def _GetVersion(self):
- if self._Version == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._Version == None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)
- return self._Version
-
- ## Retrieve platform description file version
- def _GetDscSpec(self):
- if self._DscSpecification == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._DscSpecification == None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)
- return self._DscSpecification
-
- ## Retrieve OUTPUT_DIRECTORY
- def _GetOutpuDir(self):
- if self._OutputDirectory == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._OutputDirectory == None:
- self._OutputDirectory = os.path.join("Build", self._PlatformName)
- return self._OutputDirectory
-
- ## Retrieve SUPPORTED_ARCHITECTURES
- def _GetSupArch(self):
- if self._SupArchList == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._SupArchList == None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)
- return self._SupArchList
-
- ## Retrieve BUILD_TARGETS
- def _GetBuildTarget(self):
- if self._BuildTargets == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._BuildTargets == None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)
- return self._BuildTargets
-
- def _GetPcdInfoFlag(self):
- if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE':
- return False
- elif self._PcdInfoFlag.upper() == 'TRUE':
- return True
- else:
- return False
- def _GetVarCheckFlag(self):
- if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE':
- return False
- elif self._VarCheckFlag.upper() == 'TRUE':
- return True
- else:
- return False
- def _GetAviableSkuIds(self):
- if self._AvilableSkuIds:
- return self._AvilableSkuIds
- return self.SkuIdentifier
- def _GetSkuIdentifier(self):
- if self._SkuName:
- return self._SkuName
- if self._SkuIdentifier == None:
- if self._Header == None:
- self._GetHeaderInfo()
- return self._SkuIdentifier
- ## Retrieve SKUID_IDENTIFIER
- def _GetSkuName(self):
- if self._SkuName == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if (self._SkuName == None or self._SkuName not in self.SkuIds):
- self._SkuName = 'DEFAULT'
- return self._SkuName
-
- ## Override SKUID_IDENTIFIER
- def _SetSkuName(self, Value):
- self._SkuName = Value
- self._Pcds = None
-
- def _GetFdfFile(self):
- if self._FlashDefinition == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._FlashDefinition == None:
- self._FlashDefinition = ''
- return self._FlashDefinition
-
- def _GetPrebuild(self):
- if self._Prebuild == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._Prebuild == None:
- self._Prebuild = ''
- return self._Prebuild
-
- def _GetPostbuild(self):
- if self._Postbuild == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._Postbuild == None:
- self._Postbuild = ''
- return self._Postbuild
-
- ## Retrieve FLASH_DEFINITION
- def _GetBuildNumber(self):
- if self._BuildNumber == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._BuildNumber == None:
- self._BuildNumber = ''
- return self._BuildNumber
-
- ## Retrieve MAKEFILE_NAME
- def _GetMakefileName(self):
- if self._MakefileName == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._MakefileName == None:
- self._MakefileName = ''
- return self._MakefileName
-
- ## Retrieve BsBaseAddress
- def _GetBsBaseAddress(self):
- if self._BsBaseAddress == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._BsBaseAddress == None:
- self._BsBaseAddress = ''
- return self._BsBaseAddress
-
- ## Retrieve RtBaseAddress
- def _GetRtBaseAddress(self):
- if self._RtBaseAddress == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._RtBaseAddress == None:
- self._RtBaseAddress = ''
- return self._RtBaseAddress
-
- ## Retrieve the top address for the load fix address
- def _GetLoadFixAddress(self):
- if self._LoadFixAddress == None:
- if self._Header == None:
- self._GetHeaderInfo()
-
- if self._LoadFixAddress == None:
- self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')
-
- try:
- self._LoadFixAddress = int (self._LoadFixAddress, 0)
- except:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))
-
- #
- # If command line defined, should override the value in DSC file.
- #
- if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():
- try:
- self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
- except:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))
-
- if self._LoadFixAddress < 0:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))
- if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:
- EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))
-
- return self._LoadFixAddress
-
- ## Retrieve RFCLanguage filter
- def _GetRFCLanguages(self):
- if self._RFCLanguages == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._RFCLanguages == None:
- self._RFCLanguages = []
- return self._RFCLanguages
-
- ## Retrieve ISOLanguage filter
- def _GetISOLanguages(self):
- if self._ISOLanguages == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._ISOLanguages == None:
- self._ISOLanguages = []
- return self._ISOLanguages
- ## Retrieve the GUID string for VPD tool
- def _GetVpdToolGuid(self):
- if self._VpdToolGuid == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._VpdToolGuid == None:
- self._VpdToolGuid = ''
- return self._VpdToolGuid
-
- ## Retrieve [SkuIds] section information
- def _GetSkuIds(self):
- if self._SkuIds == None:
- self._SkuIds = sdict()
- RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]
- for Record in RecordList:
- if Record[0] in [None, '']:
- EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',
- File=self.MetaFile, Line=Record[-1])
- if Record[1] in [None, '']:
- EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',
- File=self.MetaFile, Line=Record[-1])
- self._SkuIds[Record[1]] = Record[0]
- if 'DEFAULT' not in self._SkuIds:
- self._SkuIds['DEFAULT'] = '0'
- if 'COMMON' not in self._SkuIds:
- self._SkuIds['COMMON'] = '0'
- return self._SkuIds
-
- ## Retrieve [Components] section information
- def _GetModules(self):
- if self._Modules != None:
- return self._Modules
-
- self._Modules = sdict()
- RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
- Macros = self._Macros
- Macros["EDK_SOURCE"] = GlobalData.gEcpSource
- for Record in RecordList:
- DuplicatedFile = False
-
- ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
- ModuleId = Record[5]
- LineNo = Record[6]
-
- # check the file validation
- ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
- ExtraData=ErrorInfo)
- # Check duplication
- # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
- if self._Arch != 'COMMON' and ModuleFile in self._Modules:
- DuplicatedFile = True
-
- Module = ModuleBuildClassObject()
- Module.MetaFile = ModuleFile
-
- # get module private library instance
- RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
- for Record in RecordList:
- LibraryClass = Record[0]
- LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)
- LineNo = Record[-1]
-
- # check the file validation
- ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
- ExtraData=ErrorInfo)
-
- if LibraryClass == '' or LibraryClass == 'NULL':
- self._NullLibraryNumber += 1
- LibraryClass = 'NULL%d' % self._NullLibraryNumber
- EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
- Module.LibraryClasses[LibraryClass] = LibraryPath
- if LibraryPath not in self.LibraryInstances:
- self.LibraryInstances.append(LibraryPath)
-
- # get module private PCD setting
- 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, None, ModuleId]
- for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
- TokenList = GetSplitValueList(Setting)
- DefaultValue = TokenList[0]
- if len(TokenList) > 1:
- MaxDatumSize = TokenList[1]
- else:
- MaxDatumSize = ''
- TypeString = self._PCD_TYPE_STRING_[Type]
- Pcd = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- TypeString,
- '',
- DefaultValue,
- '',
- MaxDatumSize,
- {},
- False,
- None
- )
- Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
-
- # get module private build options
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]
- for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
- if (ToolChainFamily, ToolChain) not in Module.BuildOptions:
- Module.BuildOptions[ToolChainFamily, ToolChain] = Option
- else:
- OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]
- Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
-
- RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
- if DuplicatedFile and not RecordList:
- EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
- if RecordList:
- if len(RecordList) != 1:
- EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in section.',
- File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
- ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
- ModuleFile.Arch = self._Arch
-
- self._Modules[ModuleFile] = Module
- return self._Modules
-
- ## Retrieve all possible library instances used in this platform
- def _GetLibraryInstances(self):
- if self._LibraryInstances == None:
- self._GetLibraryClasses()
- return self._LibraryInstances
-
- ## Retrieve [LibraryClasses] information
- def _GetLibraryClasses(self):
- if self._LibraryClasses == None:
- self._LibraryInstances = []
- #
- # tdict is a special dict kind of type, used for selecting correct
- # library instance for given library class and module type
- #
- LibraryClassDict = tdict(True, 3)
- # track all library class names
- LibraryClassSet = set()
- RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
- Macros = self._Macros
- for Record in RecordList:
- LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record
- if LibraryClass == '' or LibraryClass == 'NULL':
- self._NullLibraryNumber += 1
- LibraryClass = 'NULL%d' % self._NullLibraryNumber
- EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))
- LibraryClassSet.add(LibraryClass)
- LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)
- # check the file validation
- ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
- ExtraData=ErrorInfo)
-
- if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:
- EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,
- File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)
- LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance
- if LibraryInstance not in self._LibraryInstances:
- self._LibraryInstances.append(LibraryInstance)
-
- # resolve the specific library instance for each class and each module type
- self._LibraryClasses = tdict(True)
- for LibraryClass in LibraryClassSet:
- # try all possible module types
- for ModuleType in SUP_MODULE_LIST:
- LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]
- if LibraryInstance == None:
- continue
- self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
-
- # for Edk style library instances, which are listed in different section
- Macros["EDK_SOURCE"] = GlobalData.gEcpSource
- RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
- for Record in RecordList:
- File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
- LineNo = Record[-1]
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate('.inf')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
- ExtraData=ErrorInfo)
- if File not in self._LibraryInstances:
- self._LibraryInstances.append(File)
- #
- # we need the module name as the library class name, so we have
- # to parse it here. (self._Bdb[] will trigger a file parse if it
- # hasn't been parsed)
- #
- Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
- self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
- return self._LibraryClasses
-
- def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
- if self._DecPcds == None:
- self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain)
- FdfInfList = []
- if GlobalData.gFdfParser:
- FdfInfList = GlobalData.gFdfParser.Profile.InfList
-
- PkgSet = set()
- for Inf in FdfInfList:
- ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
- if ModuleFile in self._Modules:
- continue
- ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
- PkgSet.update(ModuleData.Packages)
- DecPcds = {}
- for Pkg in PkgSet:
- for Pcd in Pkg.Pcds:
- DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]
- self._DecPcds.update(DecPcds)
-
- if (PcdCName, TokenSpaceGuid) not in self._DecPcds:
- EdkLogger.error('build', PARSER_ERROR,
- "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
- File=self.MetaFile, Line=LineNo)
- ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)
- if not IsValid and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
- EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
- ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
- if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
- try:
- ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)
- except WrnExpression, Value:
- ValueList[Index] = Value.result
- except EvaluationException, Excpt:
- if hasattr(Excpt, 'Pcd'):
- if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
- EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
- " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
- " of the DSC file" % Excpt.Pcd,
- File=self.MetaFile, Line=LineNo)
- else:
- EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
- File=self.MetaFile, Line=LineNo)
- else:
- EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
- File=self.MetaFile, Line=LineNo)
- if ValueList[Index] == 'True':
- ValueList[Index] = '1'
- elif ValueList[Index] == 'False':
- ValueList[Index] = '0'
- if ValueList[Index]:
- Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
- if not Valid:
- EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
- ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
- return ValueList
-
- ## Retrieve all PCD settings in platform
- def _GetPcds(self):
- if self._Pcds == None:
- self._Pcds = sdict()
- 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._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
- self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
- self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
- self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
- self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
- self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
- return self._Pcds
-
- ## Retrieve [BuildOptions]
- def _GetBuildOptions(self):
- if self._BuildOptions == None:
- self._BuildOptions = sdict()
- #
- # Retrieve build option for EDKII and EDK style module
- #
- for CodeBase in (EDKII_NAME, EDK_NAME):
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
- for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
- CurKey = (ToolChainFamily, ToolChain, CodeBase)
- #
- # Only flags can be appended
- #
- if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
- self._BuildOptions[CurKey] = Option
- else:
- self._BuildOptions[CurKey] += ' ' + Option
- return self._BuildOptions
-
- def GetBuildOptionsByModuleType(self, Edk, ModuleType):
- if self._ModuleTypeOptions == None:
- self._ModuleTypeOptions = sdict()
- if (Edk, ModuleType) not in self._ModuleTypeOptions:
- options = sdict()
- self._ModuleTypeOptions[Edk, ModuleType] = options
- DriverType = '%s.%s' % (Edk, ModuleType)
- CommonDriverType = '%s.%s' % ('COMMON', ModuleType)
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]
- for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList:
- if Type == DriverType or Type == CommonDriverType:
- Key = (ToolChainFamily, ToolChain, Edk)
- if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
- options[Key] = Option
- else:
- options[Key] += ' ' + Option
- return self._ModuleTypeOptions[Edk, ModuleType]
-
- ## Retrieve non-dynamic PCD settings
- #
- # @param Type PCD type
- #
- # @retval a dict object contains settings of given PCD type
- #
- def _GetPcd(self, Type):
- Pcds = sdict()
- #
- # tdict is a special dict kind of type, used for selecting correct
- # PCD settings for certain ARCH
- #
-
- SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
-
- PcdDict = tdict(True, 3)
- PcdSet = set()
- # Find out all possible PCD candidates for self._Arch
- RecordList = self._RawData[Type, self._Arch]
- PcdValueDict = sdict()
- for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- if SkuName in (SkuObj.SystemSkuId,'DEFAULT','COMMON'):
- PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))
- PcdDict[Arch, PcdCName, TokenSpaceGuid,SkuName] = Setting
-
- #handle pcd value override
- for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdSet:
- Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid,SkuName]
- if Setting == None:
- continue
- PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
- if (PcdCName, TokenSpaceGuid) in PcdValueDict:
- PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue,DatumType,MaxDatumSize)
- else:
- PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue,DatumType,MaxDatumSize)}
-
- PcdsKeys = PcdValueDict.keys()
- for PcdCName,TokenSpaceGuid in PcdsKeys:
-
- PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]
- PcdValue = None
- DatumType = None
- MaxDatumSize = None
- if 'COMMON' in PcdSetting:
- PcdValue,DatumType,MaxDatumSize = PcdSetting['COMMON']
- if 'DEFAULT' in PcdSetting:
- PcdValue,DatumType,MaxDatumSize = PcdSetting['DEFAULT']
- if SkuObj.SystemSkuId in PcdSetting:
- PcdValue,DatumType,MaxDatumSize = PcdSetting[SkuObj.SystemSkuId]
-
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- DatumType,
- PcdValue,
- '',
- MaxDatumSize,
- {},
- False,
- None,
- IsDsc=True)
- return Pcds
-
- ## Retrieve dynamic PCD settings
- #
- # @param Type PCD type
- #
- # @retval a dict object contains settings of given PCD type
- #
- def _GetDynamicPcd(self, Type):
-
- SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
-
- Pcds = sdict()
- #
- # tdict is a special dict kind of type, used for selecting correct
- # PCD settings for certain ARCH and SKU
- #
- PcdDict = tdict(True, 4)
- PcdList = []
- # Find out all possible PCD candidates for self._Arch
- RecordList = self._RawData[Type, self._Arch]
- AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
-
- AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})
- for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- if SkuName not in AvailableSkuIdSet:
- continue
-
- PcdList.append((PcdCName, TokenSpaceGuid, SkuName,Dummy4))
- PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
- # Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
-
- Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
- if Setting == None:
- continue
-
- PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
- SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue)
- if (PcdCName,TokenSpaceGuid) in Pcds.keys():
- pcdObject = Pcds[PcdCName,TokenSpaceGuid]
- pcdObject.SkuInfoList[SkuName] = SkuInfo
- if MaxDatumSize.strip():
- CurrentMaxSize = int(MaxDatumSize.strip(),0)
- else:
- CurrentMaxSize = 0
- if pcdObject.MaxDatumSize:
- PcdMaxSize = int(pcdObject.MaxDatumSize,0)
- else:
- PcdMaxSize = 0
- if CurrentMaxSize > PcdMaxSize:
- pcdObject.MaxDatumSize = str(CurrentMaxSize)
- else:
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- DatumType,
- PcdValue,
- '',
- MaxDatumSize,
- {SkuName : SkuInfo},
- False,
- None,
- IsDsc=True)
-
- for pcd in Pcds.values():
- pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]
- if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
- valuefromDec = pcdDecObject.DefaultValue
- SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)
- pcd.SkuInfoList['DEFAULT'] = SkuInfo
- elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
- pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
- del(pcd.SkuInfoList['COMMON'])
- elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
- del(pcd.SkuInfoList['COMMON'])
- if SkuObj.SkuUsageType == SkuObj.SINGLE:
- if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
- pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
- del(pcd.SkuInfoList['DEFAULT'])
-
- return Pcds
-
- def CompareVarAttr(self, Attr1, Attr2):
- if not Attr1 or not Attr2: # for empty string
- return True
- Attr1s = [attr.strip() for attr in Attr1.split(",")]
- Attr1Set = set(Attr1s)
- Attr2s = [attr.strip() for attr in Attr2.split(",")]
- Attr2Set = set(Attr2s)
- if Attr2Set == Attr1Set:
- return True
- else:
- return False
- ## Retrieve dynamic HII PCD settings
- #
- # @param Type PCD type
- #
- # @retval a dict object contains settings of given PCD type
- #
- def _GetDynamicHiiPcd(self, Type):
-
- SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
- VariableAttrs = {}
-
- Pcds = sdict()
- #
- # tdict is a special dict kind of type, used for selecting correct
- # PCD settings for certain ARCH and SKU
- #
- PcdDict = tdict(True, 4)
- PcdSet = set()
- RecordList = self._RawData[Type, self._Arch]
- # Find out all possible PCD candidates for self._Arch
- AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
-
- AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})
- for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- if SkuName not in AvailableSkuIdSet:
- continue
- PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))
- PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
- # Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid,SkuName, Dummy4 in PcdSet:
-
- Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
- if Setting == None:
- continue
- VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
-
- rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
- if not rt:
- EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
- ExtraData = "[%s]" % VarAttribute)
- ExceedMax = False
- FormatCorrect = True
- if VariableOffset.isdigit():
- if int(VariableOffset,10) > 0xFFFF:
- ExceedMax = True
- elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset):
- if int(VariableOffset,16) > 0xFFFF:
- ExceedMax = True
- # For Offset written in "A.B"
- elif VariableOffset.find('.') > -1:
- VariableOffsetList = VariableOffset.split(".")
- if not (len(VariableOffsetList) == 2
- and IsValidWord(VariableOffsetList[0])
- and IsValidWord(VariableOffsetList[1])):
- FormatCorrect = False
- else:
- FormatCorrect = False
- if not FormatCorrect:
- EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid,PcdCName)))
-
- if ExceedMax:
- EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid,PcdCName)))
- if (VariableName, VariableGuid) not in VariableAttrs:
- VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
- else:
- if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
- EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))
-
- SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute = VarAttribute)
- pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
- if (PcdCName,TokenSpaceGuid) in Pcds.keys():
- pcdObject = Pcds[PcdCName,TokenSpaceGuid]
- pcdObject.SkuInfoList[SkuName] = SkuInfo
- else:
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- '',
- DefaultValue,
- '',
- '',
- {SkuName : SkuInfo},
- False,
- None,
- pcdDecObject.validateranges,
- pcdDecObject.validlists,
- pcdDecObject.expressions,
- IsDsc=True)
-
- for pcd in Pcds.values():
- SkuInfoObj = pcd.SkuInfoList.values()[0]
- pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]
- # Only fix the value while no value provided in DSC file.
- for sku in pcd.SkuInfoList.values():
- if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue==None):
- sku.HiiDefaultValue = pcdDecObject.DefaultValue
- if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
- valuefromDec = pcdDecObject.DefaultValue
- SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)
- pcd.SkuInfoList['DEFAULT'] = SkuInfo
- elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
- pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
- del(pcd.SkuInfoList['COMMON'])
- elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
- del(pcd.SkuInfoList['COMMON'])
-
- if SkuObj.SkuUsageType == SkuObj.SINGLE:
- if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
- pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
- del(pcd.SkuInfoList['DEFAULT'])
-
-
- if pcd.MaxDatumSize.strip():
- MaxSize = int(pcd.MaxDatumSize,0)
- else:
- MaxSize = 0
- if pcdDecObject.DatumType == 'VOID*':
- for (skuname,skuobj) in pcd.SkuInfoList.items():
- datalen = 0
- if skuobj.HiiDefaultValue.startswith("L"):
- datalen = (len(skuobj.HiiDefaultValue)- 3 + 1) * 2
- elif skuobj.HiiDefaultValue.startswith("{"):
- datalen = len(skuobj.HiiDefaultValue.split(","))
- else:
- datalen = len(skuobj.HiiDefaultValue) -2 + 1
- if datalen>MaxSize:
- MaxSize = datalen
- pcd.MaxDatumSize = str(MaxSize)
- return Pcds
-
- ## Retrieve dynamic VPD PCD settings
- #
- # @param Type PCD type
- #
- # @retval a dict object contains settings of given PCD type
- #
- def _GetDynamicVpdPcd(self, Type):
-
- SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
-
- Pcds = sdict()
- #
- # tdict is a special dict kind of type, used for selecting correct
- # PCD settings for certain ARCH and SKU
- #
- PcdDict = tdict(True, 4)
- PcdList = []
- # Find out all possible PCD candidates for self._Arch
- RecordList = self._RawData[Type, self._Arch]
- AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
-
- AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})
- for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- if SkuName not in AvailableSkuIdSet:
- continue
-
- PcdList.append((PcdCName, TokenSpaceGuid,SkuName, Dummy4))
- PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
- # Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdList:
- Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
- if Setting == None:
- continue
- #
- # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
- # For the Integer & Boolean type, the optional data can only be InitialValue.
- # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
- # until the DEC parser has been called.
- #
- VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
- SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue)
- if (PcdCName,TokenSpaceGuid) in Pcds.keys():
- pcdObject = Pcds[PcdCName,TokenSpaceGuid]
- pcdObject.SkuInfoList[SkuName] = SkuInfo
- if MaxDatumSize.strip():
- CurrentMaxSize = int(MaxDatumSize.strip(),0)
- else:
- CurrentMaxSize = 0
- if pcdObject.MaxDatumSize:
- PcdMaxSize = int(pcdObject.MaxDatumSize,0)
- else:
- PcdMaxSize = 0
- if CurrentMaxSize > PcdMaxSize:
- pcdObject.MaxDatumSize = str(CurrentMaxSize)
- else:
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- '',
- InitialValue,
- '',
- MaxDatumSize,
- {SkuName : SkuInfo},
- False,
- None,
- IsDsc=True)
- for pcd in Pcds.values():
- SkuInfoObj = pcd.SkuInfoList.values()[0]
- pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]
- if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
- valuefromDec = pcdDecObject.DefaultValue
- SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj.VpdOffset, valuefromDec)
- pcd.SkuInfoList['DEFAULT'] = SkuInfo
- elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
- pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
- del(pcd.SkuInfoList['COMMON'])
- elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
- del(pcd.SkuInfoList['COMMON'])
- if SkuObj.SkuUsageType == SkuObj.SINGLE:
- if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
- pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
- del(pcd.SkuInfoList['DEFAULT'])
-
- return Pcds
-
- ## Add external modules
- #
- # The external modules are mostly those listed in FDF file, which don't
- # need "build".
- #
- # @param FilePath The path of module description file
- #
- def AddModule(self, FilePath):
- FilePath = NormPath(FilePath)
- if FilePath not in self.Modules:
- Module = ModuleBuildClassObject()
- Module.MetaFile = FilePath
- self.Modules.append(Module)
-
- ## Add external PCDs
- #
- # The external PCDs are mostly those listed in FDF file to specify address
- # or offset information.
- #
- # @param Name Name of the PCD
- # @param Guid Token space guid of the PCD
- # @param Value Value of the PCD
- #
- def AddPcd(self, Name, Guid, Value):
- if (Name, Guid) not in self.Pcds:
- self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
- self.Pcds[Name, Guid].DefaultValue = Value
-
- _Macros = property(_GetMacros)
- Arch = property(_GetArch, _SetArch)
- Platform = property(_GetPlatformName)
- PlatformName = property(_GetPlatformName)
- Guid = property(_GetFileGuid)
- Version = property(_GetVersion)
- DscSpecification = property(_GetDscSpec)
- OutputDirectory = property(_GetOutpuDir)
- SupArchList = property(_GetSupArch)
- BuildTargets = property(_GetBuildTarget)
- SkuName = property(_GetSkuName, _SetSkuName)
- SkuIdentifier = property(_GetSkuIdentifier)
- AvilableSkuIds = property(_GetAviableSkuIds)
- PcdInfoFlag = property(_GetPcdInfoFlag)
- VarCheckFlag = property(_GetVarCheckFlag)
- FlashDefinition = property(_GetFdfFile)
- Prebuild = property(_GetPrebuild)
- Postbuild = property(_GetPostbuild)
- BuildNumber = property(_GetBuildNumber)
- MakefileName = property(_GetMakefileName)
- BsBaseAddress = property(_GetBsBaseAddress)
- RtBaseAddress = property(_GetRtBaseAddress)
- LoadFixAddress = property(_GetLoadFixAddress)
- RFCLanguages = property(_GetRFCLanguages)
- ISOLanguages = property(_GetISOLanguages)
- VpdToolGuid = property(_GetVpdToolGuid)
- SkuIds = property(_GetSkuIds)
- Modules = property(_GetModules)
- LibraryInstances = property(_GetLibraryInstances)
- LibraryClasses = property(_GetLibraryClasses)
- Pcds = property(_GetPcds)
- BuildOptions = property(_GetBuildOptions)
-
-## Platform build information from DEC file
-#
-# This class is used to retrieve information stored in database and convert them
-# into PackageBuildClassObject form for easier use for AutoGen.
-#
-class DecBuildData(PackageBuildClassObject):
- # dict used to convert PCD type in database to string used by build tool
- _PCD_TYPE_STRING_ = {
- MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
- MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
- MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
- MODEL_PCD_DYNAMIC : "Dynamic",
- MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
- MODEL_PCD_DYNAMIC_HII : "DynamicHii",
- MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
- MODEL_PCD_DYNAMIC_EX : "DynamicEx",
- MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
- MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
- MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
- }
-
- # dict used to convert part of [Defines] to members of DecBuildData directly
- _PROPERTY_ = {
- #
- # Required Fields
- #
- TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName",
- TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid",
- TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version",
- TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile",
- }
-
-
- ## Constructor of DecBuildData
- #
- # Initialize object of DecBuildData
- #
- # @param FilePath The path of package description file
- # @param RawData The raw data of DEC file
- # @param BuildDataBase Database used to retrieve module information
- # @param Arch The target architecture
- # @param Platform (not used for DecBuildData)
- # @param Macros Macros used for replacement in DSC file
- #
- def __init__(self, File, RawData, BuildDataBase, 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()
-
- ## 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._LibraryClasses = None
- self._Pcds = None
- self.__Macros = None
- self._PrivateProtocols = None
- self._PrivatePpis = None
- self._PrivateGuids = None
- self._PrivateIncludes = None
-
- ## Get current effective macros
- def _GetMacros(self):
- if self.__Macros == None:
- self.__Macros = {}
- self.__Macros.update(GlobalData.gGlobalDefines)
- return self.__Macros
-
- ## Get architecture
- def _GetArch(self):
- return self._Arch
-
- ## Set architecture
- #
- # Changing the default ARCH to another may affect all other information
- # because all information in a platform may be ARCH-related. That's
- # why we need to clear all internal used members, in order to cause all
- # information to be re-retrieved.
- #
- # @param Value The value of ARCH
- #
- def _SetArch(self, Value):
- if self._Arch == Value:
- return
- self._Arch = Value
- self._Clear()
-
- ## Retrieve all information in [Defines] section
- #
- # (Retriving 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
- def _GetPackageName(self):
- if self._PackageName == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._PackageName == None:
- EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)
- return self._PackageName
-
- ## Retrieve file guid
- def _GetFileGuid(self):
- if self._Guid == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._Guid == None:
- EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)
- return self._Guid
-
- ## Retrieve package version
- def _GetVersion(self):
- if self._Version == None:
- if self._Header == None:
- self._GetHeaderInfo()
- if self._Version == None:
- self._Version = ''
- return self._Version
-
- ## Retrieve protocol definitions (name/value pairs)
- def _GetProtocol(self):
- if self._Protocols == None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # protocol defition 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 sdict to keep the order
- self._Protocols = sdict()
- self._PrivateProtocols = sdict()
- 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)
- def _GetPpi(self):
- if self._Ppis == None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # PPI defition 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 sdict to keep the order
- self._Ppis = sdict()
- self._PrivatePpis = sdict()
- 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)
- def _GetGuid(self):
- if self._Guids == None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # GUID defition 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 sdict to keep the order
- self._Guids = sdict()
- self._PrivateGuids = sdict()
- 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
- def _GetInclude(self):
- if self._Includes == None:
- self._Includes = []
- self._PrivateIncludes = []
- PublicInclues = []
- RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]
- Macros = self._Macros
- Macros["EDK_SOURCE"] = GlobalData.gEcpSource
- 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)
-
- return self._Includes
-
- ## Retrieve library class declarations (not used in build at present)
- def _GetLibraryClass(self):
- if self._LibraryClasses == None:
- #
- # tdict is a special kind of dict, used for selecting correct
- # library class declaration for given ARCH
- #
- 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 = sdict()
- for LibraryClass in LibraryClassSet:
- self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]
- return self._LibraryClasses
-
- ## Retrieve PCD declarations
- def _GetPcds(self):
- if self._Pcds == None:
- self._Pcds = sdict()
- 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
-
- ## Retrieve PCD declarations for given type
- def _GetPcd(self, Type):
- Pcds = sdict()
- #
- # tdict is a special kind of dict, used for selecting correct
- # PCD declaration for given ARCH
- #
- PcdDict = tdict(True, 3)
- # for summarizing PCD
- PcdSet = set()
- # find out all PCDs of the 'type'
- RecordList = self._RawData[Type, self._Arch]
- for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:
- PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting
- PcdSet.add((PcdCName, TokenSpaceGuid))
-
- 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 = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
- if Setting == None:
- continue
-
- DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)
-
- validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)
- Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- DatumType,
- DefaultValue,
- TokenNumber,
- '',
- {},
- False,
- None,
- list(validateranges),
- list(validlists),
- list(expressions)
- )
- return Pcds
-
-
- _Macros = property(_GetMacros)
- Arch = property(_GetArch, _SetArch)
- PackageName = property(_GetPackageName)
- Guid = property(_GetFileGuid)
- Version = property(_GetVersion)
-
- Protocols = property(_GetProtocol)
- Ppis = property(_GetPpi)
- Guids = property(_GetGuid)
- Includes = property(_GetInclude)
- LibraryClasses = property(_GetLibraryClass)
- Pcds = property(_GetPcds)
-
-## Module build information from INF file
-#
-# This class is used to retrieve information stored in database and convert them
-# into ModuleBuildClassObject form for easier use for AutoGen.
-#
-class InfBuildData(ModuleBuildClassObject):
- # dict used to convert PCD type in database to string used by build tool
- _PCD_TYPE_STRING_ = {
- MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",
- MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",
- MODEL_PCD_FEATURE_FLAG : "FeatureFlag",
- MODEL_PCD_DYNAMIC : "Dynamic",
- MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",
- MODEL_PCD_DYNAMIC_HII : "DynamicHii",
- MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",
- MODEL_PCD_DYNAMIC_EX : "DynamicEx",
- MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",
- MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",
- MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",
- }
-
- # dict used to convert part of [Defines] to members of InfBuildData directly
- _PROPERTY_ = {
- #
- # Required Fields
- #
- TAB_INF_DEFINES_BASE_NAME : "_BaseName",
- TAB_INF_DEFINES_FILE_GUID : "_Guid",
- TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",
- #
- # Optional Fields
- #
- #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
- TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",
- TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",
- #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
- TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",
- TAB_INF_DEFINES_VERSION_NUMBER : "_Version",
- TAB_INF_DEFINES_VERSION_STRING : "_Version",
- TAB_INF_DEFINES_VERSION : "_Version",
- TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",
- TAB_INF_DEFINES_SHADOW : "_Shadow",
-
- TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath",
- }
-
- # dict used to convert Component type to Module type
- _MODULE_TYPE_ = {
- "LIBRARY" : "BASE",
- "SECURITY_CORE" : "SEC",
- "PEI_CORE" : "PEI_CORE",
- "COMBINED_PEIM_DRIVER" : "PEIM",
- "PIC_PEIM" : "PEIM",
- "RELOCATABLE_PEIM" : "PEIM",
- "PE32_PEIM" : "PEIM",
- "BS_DRIVER" : "DXE_DRIVER",
- "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
- "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
- "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
- # "SMM_DRIVER" : "DXE_SMM_DRIVER",
- # "BS_DRIVER" : "DXE_SMM_DRIVER",
- # "BS_DRIVER" : "UEFI_DRIVER",
- "APPLICATION" : "UEFI_APPLICATION",
- "LOGO" : "BASE",
- }
-
- # regular expression for converting XXX_FLAGS in [nmake] section to new type
- _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)
- # dict used to convert old tool name used in [nmake] section to new ones
- _TOOL_CODE_ = {
- "C" : "CC",
- "LIB" : "SLINK",
- "LINK" : "DLINK",
- }
-
-
- ## Constructor of DscBuildData
- #
- # Initialize object of DscBuildData
- #
- # @param FilePath The path of platform description file
- # @param RawData The raw data of DSC file
- # @param 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
- #
- def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):
- self.MetaFile = FilePath
- self._ModuleDir = FilePath.Dir
- self._RawData = RawData
- self._Bdb = BuildDatabase
- self._Arch = Arch
- self._Target = Target
- self._Toolchain = Toolchain
- self._Platform = 'COMMON'
- self._SourceOverridePath = None
- if FilePath.Key in GlobalData.gOverrideDir:
- self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]
- self._Clear()
-
- ## XXX[key] = value
- def __setitem__(self, key, value):
- self.__dict__[self._PROPERTY_[key]] = value
-
- ## value = XXX[key]
- def __getitem__(self, key):
- return self.__dict__[self._PROPERTY_[key]]
-
- ## "in" test support
- def __contains__(self, key):
- return key in self._PROPERTY_
-
- ## Set all internal used members of InfBuildData to None
- def _Clear(self):
- self._HeaderComments = None
- self._TailComments = None
- self._Header_ = None
- self._AutoGenVersion = None
- 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._BinaryModule = 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 = None
- self._Binaries = None
- self._Sources = None
- self._LibraryClasses = None
- self._Libraries = None
- self._Protocols = None
- self._ProtocolComments = None
- self._Ppis = None
- self._PpiComments = None
- self._Guids = None
- self._GuidsUsedByPcd = sdict()
- self._GuidComments = None
- self._Includes = None
- self._Packages = None
- self._Pcds = None
- self._PcdComments = None
- self._BuildOptions = None
- self._Depex = None
- self._DepexExpression = None
- self.__Macros = None
-
- ## Get current effective macros
- def _GetMacros(self):
- if self.__Macros == None:
- self.__Macros = {}
- # EDK_GLOBAL defined macros can be applied to EDK module
- if self.AutoGenVersion < 0x00010005:
- self.__Macros.update(GlobalData.gEdkGlobal)
- self.__Macros.update(GlobalData.gGlobalDefines)
- return self.__Macros
-
- ## Get architecture
- def _GetArch(self):
- return self._Arch
-
- ## Set architecture
- #
- # Changing the default ARCH to another may affect all other information
- # because all information in a platform may be ARCH-related. That's
- # why we need to clear all internal used members, in order to cause all
- # information to be re-retrieved.
- #
- # @param Value The value of ARCH
- #
- def _SetArch(self, Value):
- if self._Arch == Value:
- return
- self._Arch = Value
- self._Clear()
-
- ## Return the name of platform employing this module
- def _GetPlatform(self):
- return self._Platform
-
- ## Change the name of platform employing this module
- #
- # Changing the default name of platform to another may affect some information
- # because they may be PLATFORM-related. That's why we need to clear all internal
- # used members, in order to cause all information to be re-retrieved.
- #
- def _SetPlatform(self, Value):
- if self._Platform == Value:
- return
- self._Platform = Value
- self._Clear()
- def _GetHeaderComments(self):
- if not self._HeaderComments:
- self._HeaderComments = []
- RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]
- for Record in RecordList:
- self._HeaderComments.append(Record[0])
- return self._HeaderComments
- def _GetTailComments(self):
- if not self._TailComments:
- self._TailComments = []
- RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]
- for Record in RecordList:
- self._TailComments.append(Record[0])
- return self._TailComments
- ## Retrieve all information in [Defines] section
- #
- # (Retriving all [Defines] information in one-shot is just to save time.)
- #
- 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
- if self._Defs == None:
- self._Defs = sdict()
- 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'
- if self._Specification == None:
- self._Specification = sdict()
- self._Specification[Name] = GetHexVerValue(Value)
- if self._Specification[Name] == None:
- 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':
- if self._LibraryClass == None:
- 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':
- if self._ModuleEntryPointList == None:
- self._ModuleEntryPointList = []
- self._ModuleEntryPointList.append(Value)
- elif Name == 'UNLOAD_IMAGE':
- if self._ModuleUnloadImageList == None:
- self._ModuleUnloadImageList = []
- if not Value:
- continue
- self._ModuleUnloadImageList.append(Value)
- elif Name == 'CONSTRUCTOR':
- if self._ConstructorList == None:
- self._ConstructorList = []
- if not Value:
- continue
- self._ConstructorList.append(Value)
- elif Name == 'DESTRUCTOR':
- if self._DestructorList == None:
- self._DestructorList = []
- if not Value:
- continue
- self._DestructorList.append(Value)
- elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:
- TokenList = GetSplitValueList(Value)
- if self._CustomMakefile == None:
- self._CustomMakefile = {}
- if len(TokenList) < 2:
- self._CustomMakefile['MSFT'] = TokenList[0]
- self._CustomMakefile['GCC'] = TokenList[0]
- else:
- if TokenList[0] not in ['MSFT', 'GCC']:
- 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:
- if self._Defs == None:
- self._Defs = sdict()
- self._Defs[Name] = Value
- self._Macros[Name] = Value
-
- #
- # Retrieve information in sections specific to Edk.x modules
- #
- if self.AutoGenVersion >= 0x00010005:
- 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 == 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 == 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 self._Defs and '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)
-
- elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \
- and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
- self._BuildType = 'UEFI_HII'
- else:
- self._BuildType = self._ModuleType.upper()
-
- 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 self.Sources == None:
- self._Sources = []
- self._Sources.append(File)
- else:
- if not self._ComponentType:
- EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
- "COMPONENT_TYPE is not given", File=self.MetaFile)
- self._BuildType = self._ComponentType.upper()
- if self._ComponentType in self._MODULE_TYPE_:
- self._ModuleType = self._MODULE_TYPE_[self._ComponentType]
- if self._ComponentType == 'LIBRARY':
- self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]
- # make use some [nmake] section macros
- Macros = self._Macros
- Macros["EDK_SOURCE"] = GlobalData.gEcpSource
- Macros['PROCESSOR'] = self._Arch
- RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]
- for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:
- Value = ReplaceMacro(Value, Macros, True)
- if Name == "IMAGE_ENTRY_POINT":
- if self._ModuleEntryPointList == None:
- self._ModuleEntryPointList = []
- self._ModuleEntryPointList.append(Value)
- elif Name == "DPX_SOURCE":
- File = PathClass(NormPath(Value), 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 self.Sources == None:
- self._Sources = []
- self._Sources.append(File)
- else:
- ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)
- if len(ToolList) == 0 or len(ToolList) != 1:
- pass
-# EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
-# File=self.MetaFile, Line=LineNo)
- else:
- if self._BuildOptions == None:
- self._BuildOptions = sdict()
-
- if ToolList[0] in self._TOOL_CODE_:
- Tool = self._TOOL_CODE_[ToolList[0]]
- else:
- Tool = ToolList[0]
- ToolChain = "*_*_*_%s_FLAGS" % Tool
- ToolChainFamily = 'MSFT' # Edk.x only support MSFT tool chain
- #ignore not replaced macros in value
- ValueList = GetSplitList(' ' + Value, '/D')
- Dummy = ValueList[0]
- for Index in range(1, len(ValueList)):
- if ValueList[Index][-1] == '=' or ValueList[Index] == '':
- continue
- Dummy = Dummy + ' /D ' + ValueList[Index]
- Value = Dummy.strip()
- if (ToolChainFamily, ToolChain) not in self._BuildOptions:
- self._BuildOptions[ToolChainFamily, ToolChain] = Value
- else:
- OptionString = self._BuildOptions[ToolChainFamily, ToolChain]
- self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value
- # set _Header to non-None in order to avoid database re-querying
- self._Header_ = 'DUMMY'
-
- ## Retrieve file version
- def _GetInfVersion(self):
- if self._AutoGenVersion == None:
- 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)
- self._AutoGenVersion = int('0x' + Major + Minor, 0)
- else:
- self._AutoGenVersion = int(Record[2], 0)
- break
- if self._AutoGenVersion == None:
- self._AutoGenVersion = 0x00010000
- return self._AutoGenVersion
-
- ## Retrieve BASE_NAME
- def _GetBaseName(self):
- if self._BaseName == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._BaseName == None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)
- return self._BaseName
-
- ## Retrieve DxsFile
- def _GetDxsFile(self):
- if self._DxsFile == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._DxsFile == None:
- self._DxsFile = ''
- return self._DxsFile
-
- ## Retrieve MODULE_TYPE
- def _GetModuleType(self):
- if self._ModuleType == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._ModuleType == None:
- self._ModuleType = 'BASE'
- if self._ModuleType not in SUP_MODULE_LIST:
- self._ModuleType = "USER_DEFINED"
- return self._ModuleType
-
- ## Retrieve COMPONENT_TYPE
- def _GetComponentType(self):
- if self._ComponentType == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._ComponentType == None:
- self._ComponentType = 'USER_DEFINED'
- return self._ComponentType
-
- ## Retrieve "BUILD_TYPE"
- def _GetBuildType(self):
- if self._BuildType == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if not self._BuildType:
- self._BuildType = "BASE"
- return self._BuildType
-
- ## Retrieve file guid
- def _GetFileGuid(self):
- if self._Guid == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._Guid == None:
- self._Guid = '00000000-0000-0000-0000-000000000000'
- return self._Guid
-
- ## Retrieve module version
- def _GetVersion(self):
- if self._Version == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._Version == None:
- self._Version = '0.0'
- return self._Version
-
- ## Retrieve PCD_IS_DRIVER
- def _GetPcdIsDriver(self):
- if self._PcdIsDriver == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._PcdIsDriver == None:
- self._PcdIsDriver = ''
- return self._PcdIsDriver
-
- ## Retrieve SHADOW
- def _GetShadow(self):
- if self._Shadow == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._Shadow != None and self._Shadow.upper() == 'TRUE':
- self._Shadow = True
- else:
- self._Shadow = False
- return self._Shadow
-
- ## Retrieve CUSTOM_MAKEFILE
- def _GetMakefile(self):
- if self._CustomMakefile == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._CustomMakefile == None:
- self._CustomMakefile = {}
- return self._CustomMakefile
-
- ## Retrieve EFI_SPECIFICATION_VERSION
- def _GetSpec(self):
- if self._Specification == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._Specification == None:
- self._Specification = {}
- return self._Specification
-
- ## Retrieve LIBRARY_CLASS
- def _GetLibraryClass(self):
- if self._LibraryClass == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._LibraryClass == None:
- self._LibraryClass = []
- return self._LibraryClass
-
- ## Retrieve ENTRY_POINT
- def _GetEntryPoint(self):
- if self._ModuleEntryPointList == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._ModuleEntryPointList == None:
- self._ModuleEntryPointList = []
- return self._ModuleEntryPointList
-
- ## Retrieve UNLOAD_IMAGE
- def _GetUnloadImage(self):
- if self._ModuleUnloadImageList == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._ModuleUnloadImageList == None:
- self._ModuleUnloadImageList = []
- return self._ModuleUnloadImageList
-
- ## Retrieve CONSTRUCTOR
- def _GetConstructor(self):
- if self._ConstructorList == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._ConstructorList == None:
- self._ConstructorList = []
- return self._ConstructorList
-
- ## Retrieve DESTRUCTOR
- def _GetDestructor(self):
- if self._DestructorList == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._DestructorList == None:
- self._DestructorList = []
- return self._DestructorList
-
- ## Retrieve definies other than above ones
- def _GetDefines(self):
- if self._Defs == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
- if self._Defs == None:
- self._Defs = sdict()
- return self._Defs
-
- ## Retrieve binary files
- def _GetBinaries(self):
- if self._Binaries == None:
- self._Binaries = []
- RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]
- Macros = self._Macros
- Macros["EDK_SOURCE"] = GlobalData.gEcpSource
- Macros['PROCESSOR'] = self._Arch
- for Record in RecordList:
- FileType = Record[0]
- LineNo = Record[-1]
- Target = 'COMMON'
- FeatureFlag = []
- if Record[2]:
- TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
- if TokenList:
- Target = TokenList[0]
- if len(TokenList) > 1:
- FeatureFlag = Record[1:]
-
- 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)
- self._Binaries.append(File)
- return self._Binaries
-
- ## Retrieve binary files with error check.
- def _GetBinaryFiles(self):
- Binaries = self._GetBinaries()
- if GlobalData.gIgnoreSource and Binaries == []:
- ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)
-
- return Binaries
- ## Check whether it exists the binaries with current ARCH in AsBuild INF
- def _IsSupportedArch(self):
- if self._GetBinaries() and not self._GetSourceFiles():
- return True
- else:
- return False
- ## Retrieve source files
- def _GetSourceFiles(self):
- #Ignore all source files in a binary build mode
- if GlobalData.gIgnoreSource:
- self._Sources = []
- return self._Sources
-
- if self._Sources == None:
- self._Sources = []
- RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]
- Macros = self._Macros
- for Record in RecordList:
- LineNo = Record[-1]
- ToolChainFamily = Record[1]
- TagName = Record[2]
- ToolCode = Record[3]
- FeatureFlag = Record[4]
- if self.AutoGenVersion < 0x00010005:
- Macros["EDK_SOURCE"] = GlobalData.gEcpSource
- Macros['PROCESSOR'] = self._Arch
- SourceFile = NormPath(Record[0], Macros)
- if SourceFile[0] == os.path.sep:
- SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])
- # old module source files (Edk)
- File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,
- '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)
- if ErrorCode != 0:
- if File.Ext.lower() == '.h':
- EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,
- File=self.MetaFile, Line=LineNo)
- continue
- else:
- EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)
- else:
- File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',
- '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate()
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
-
- self._Sources.append(File)
- return self._Sources
-
- ## Retrieve library classes employed by this module
- def _GetLibraryClassUses(self):
- if self._LibraryClasses == None:
- self._LibraryClasses = sdict()
- 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)
- self._LibraryClasses[Lib] = Instance
- return self._LibraryClasses
-
- ## Retrieve library names (for Edk.x style of modules)
- def _GetLibraryNames(self):
- if self._Libraries == None:
- self._Libraries = []
- 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 self._Libraries:
- self._Libraries.append(LibraryName)
- return self._Libraries
-
- def _GetProtocolComments(self):
- self._GetProtocols()
- return self._ProtocolComments
- ## Retrieve protocols consumed/produced by this module
- def _GetProtocols(self):
- if self._Protocols == None:
- self._Protocols = sdict()
- self._ProtocolComments = sdict()
- RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]
- for Record in RecordList:
- CName = Record[0]
- Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)
- if Value == 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])
- self._Protocols[CName] = Value
- CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
- Comments = []
- for CmtRec in CommentRecords:
- Comments.append(CmtRec[0])
- self._ProtocolComments[CName] = Comments
- return self._Protocols
-
- def _GetPpiComments(self):
- self._GetPpis()
- return self._PpiComments
- ## Retrieve PPIs consumed/produced by this module
- def _GetPpis(self):
- if self._Ppis == None:
- self._Ppis = sdict()
- self._PpiComments = sdict()
- RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]
- for Record in RecordList:
- CName = Record[0]
- Value = PpiValue(CName, self.Packages, self.MetaFile.Path)
- if Value == 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])
- self._Ppis[CName] = Value
- CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
- Comments = []
- for CmtRec in CommentRecords:
- Comments.append(CmtRec[0])
- self._PpiComments[CName] = Comments
- return self._Ppis
-
- def _GetGuidComments(self):
- self._GetGuids()
- return self._GuidComments
- ## Retrieve GUIDs consumed/produced by this module
- def _GetGuids(self):
- if self._Guids == None:
- self._Guids = sdict()
- self._GuidComments = sdict()
- RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]
- for Record in RecordList:
- CName = Record[0]
- Value = GuidValue(CName, self.Packages, self.MetaFile.Path)
- if Value == 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])
- self._Guids[CName] = Value
- CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
- Comments = []
- for CmtRec in CommentRecords:
- Comments.append(CmtRec[0])
- self._GuidComments[CName] = Comments
- return self._Guids
-
- ## Retrieve include paths necessary for this module (for Edk.x style of modules)
- def _GetIncludes(self):
- if self._Includes == None:
- self._Includes = []
- if self._SourceOverridePath:
- self._Includes.append(self._SourceOverridePath)
-
- Macros = self._Macros
- if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():
- Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']
- else:
- Macros['PROCESSOR'] = self._Arch
- RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]
- for Record in RecordList:
- if Record[0].find('EDK_SOURCE') > -1:
- Macros['EDK_SOURCE'] = GlobalData.gEcpSource
- File = NormPath(Record[0], self._Macros)
- if File[0] == '.':
- File = os.path.join(self._ModuleDir, File)
- else:
- File = os.path.join(GlobalData.gWorkspace, File)
- File = RealPath(os.path.normpath(File))
- if File:
- self._Includes.append(File)
-
- #TRICK: let compiler to choose correct header file
- Macros['EDK_SOURCE'] = GlobalData.gEdkSource
- File = NormPath(Record[0], self._Macros)
- if File[0] == '.':
- File = os.path.join(self._ModuleDir, File)
- else:
- File = os.path.join(GlobalData.gWorkspace, File)
- File = RealPath(os.path.normpath(File))
- if File:
- self._Includes.append(File)
- else:
- File = NormPath(Record[0], Macros)
- if File[0] == '.':
- File = os.path.join(self._ModuleDir, File)
- else:
- File = mws.join(GlobalData.gWorkspace, File)
- File = RealPath(os.path.normpath(File))
- if File:
- self._Includes.append(File)
- if not File and Record[0].find('EFI_SOURCE') > -1:
- # tricky to regard WorkSpace as EFI_SOURCE
- Macros['EFI_SOURCE'] = GlobalData.gWorkspace
- File = NormPath(Record[0], Macros)
- if File[0] == '.':
- File = os.path.join(self._ModuleDir, File)
- else:
- File = os.path.join(GlobalData.gWorkspace, File)
- File = RealPath(os.path.normpath(File))
- if File:
- self._Includes.append(File)
- return self._Includes
-
- ## Retrieve packages this module depends on
- def _GetPackages(self):
- if self._Packages == None:
- self._Packages = []
- RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]
- Macros = self._Macros
- Macros['EDK_SOURCE'] = GlobalData.gEcpSource
- for Record in RecordList:
- File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
- LineNo = Record[-1]
- # check the file validation
- ErrorCode, ErrorInfo = File.Validate('.dec')
- if ErrorCode != 0:
- EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
- # parse this package now. we need it to get protocol/ppi/guid value
- Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
- self._Packages.append(Package)
- return self._Packages
-
- ## Retrieve PCD comments
- def _GetPcdComments(self):
- self._GetPcds()
- return self._PcdComments
- ## Retrieve PCDs used in this module
- def _GetPcds(self):
- if self._Pcds == None:
- self._Pcds = sdict()
- self._PcdComments = sdict()
- 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
-
- ## Retrieve build options specific to this module
- def _GetBuildOptions(self):
- if self._BuildOptions == None:
- self._BuildOptions = sdict()
- 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
- def _GetDepex(self):
- if self._Depex == None:
- self._Depex = tdict(False, 2)
- RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
-
- # If the module has only Binaries and no Sources, then ignore [Depex]
- if self.Sources == None or self.Sources == []:
- if self.Binaries != None and self.Binaries != []:
- return self._Depex
-
- # PEIM and DXE drivers must have a valid [Depex] section
- if len(self.LibraryClass) == 0 and len(RecordList) == 0:
- if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \
- self.ModuleType == 'DXE_SAL_DRIVER' or self.ModuleType == 'DXE_RUNTIME_DRIVER':
- EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
- % self.ModuleType, File=self.MetaFile)
-
- if len(RecordList) != 0 and self.ModuleType == 'USER_DEFINED':
- for Record in RecordList:
- if Record[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
- EdkLogger.error('build', FORMAT_INVALID,
- "'%s' module must specify the type of [Depex] section" % self.ModuleType,
- File=self.MetaFile)
-
- Depex = sdict()
- 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 Depex:
- Depex[Arch, ModuleType] = []
- DepexList = Depex[Arch, ModuleType]
- for Token in TokenList:
- if Token in DEPEX_SUPPORTED_OPCODE:
- DepexList.append(Token)
- elif Token.endswith(".inf"): # module file name
- ModuleFile = os.path.normpath(Token)
- Module = self.BuildDatabase[ModuleFile]
- if Module == 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:
- # get the GUID value now
- Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)
- if Value == None:
- Value = PpiValue(Token, self.Packages, self.MetaFile.Path)
- if Value == None:
- Value = GuidValue(Token, self.Packages, self.MetaFile.Path)
- if Value == 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 Depex:
- self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]
- return self._Depex
-
- ## Retrieve depedency expression
- def _GetDepexExpression(self):
- if self._DepexExpression == None:
- self._DepexExpression = tdict(False, 2)
- RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
- DepexExpression = sdict()
- 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 DepexExpression:
- DepexExpression[Arch, ModuleType] = ''
- for Token in TokenList:
- DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '
- for Arch, ModuleType in DepexExpression:
- self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]
- return self._DepexExpression
-
- def GetGuidsUsedByPcd(self):
- return self._GuidsUsedByPcd
- ## Retrieve PCD for given type
- def _GetPcd(self, Type):
- Pcds = sdict()
- 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))
- # get the guid value
- if TokenSpaceGuid not in self.Guids:
- Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)
- if Value == 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)
- self.Guids[TokenSpaceGuid] = Value
- self._GuidsUsedByPcd[TokenSpaceGuid] = Value
- 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
- for PcdCName, TokenSpaceGuid in PcdList:
- PcdRealName = PcdCName
- Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]
- if Setting == None:
- 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
- #
- # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
- #
- PcdType = self._PCD_TYPE_STRING_[Type]
- if Type == MODEL_PCD_DYNAMIC:
- Pcd.Pending = True
- for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
- 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.
- #
- if Pcd.TokenValue == None or Pcd.TokenValue == "":
- 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"):
- if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:
- 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
- if Pcd.DefaultValue in [None, '']:
- Pcd.DefaultValue = PcdInPackage.DefaultValue
- 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,
- ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])
- )
- Pcds[PcdCName, TokenSpaceGuid] = Pcd
-
- return Pcds
-
- ## check whether current module is binary module
- def _IsBinaryModule(self):
- if self.Binaries and not self.Sources:
- return True
- elif GlobalData.gIgnoreSource:
- return True
- else:
- return False
-
- _Macros = property(_GetMacros)
- Arch = property(_GetArch, _SetArch)
- Platform = property(_GetPlatform, _SetPlatform)
-
- HeaderComments = property(_GetHeaderComments)
- TailComments = property(_GetTailComments)
- AutoGenVersion = property(_GetInfVersion)
- BaseName = property(_GetBaseName)
- ModuleType = property(_GetModuleType)
- ComponentType = property(_GetComponentType)
- BuildType = property(_GetBuildType)
- Guid = property(_GetFileGuid)
- Version = property(_GetVersion)
- PcdIsDriver = property(_GetPcdIsDriver)
- Shadow = property(_GetShadow)
- CustomMakefile = property(_GetMakefile)
- Specification = property(_GetSpec)
- LibraryClass = property(_GetLibraryClass)
- ModuleEntryPointList = property(_GetEntryPoint)
- ModuleUnloadImageList = property(_GetUnloadImage)
- ConstructorList = property(_GetConstructor)
- DestructorList = property(_GetDestructor)
- Defines = property(_GetDefines)
- DxsFile = property(_GetDxsFile)
-
- Binaries = property(_GetBinaryFiles)
- Sources = property(_GetSourceFiles)
- LibraryClasses = property(_GetLibraryClassUses)
- Libraries = property(_GetLibraryNames)
- Protocols = property(_GetProtocols)
- ProtocolComments = property(_GetProtocolComments)
- Ppis = property(_GetPpis)
- PpiComments = property(_GetPpiComments)
- Guids = property(_GetGuids)
- GuidComments = property(_GetGuidComments)
- Includes = property(_GetIncludes)
- Packages = property(_GetPackages)
- Pcds = property(_GetPcds)
- PcdComments = property(_GetPcdComments)
- BuildOptions = property(_GetBuildOptions)
- Depex = property(_GetDepex)
- DepexExpression = property(_GetDepexExpression)
- IsBinaryModule = property(_IsBinaryModule)
- IsSupportedArch = property(_IsSupportedArch)
+from Workspace.DecBuildData import DecBuildData
+from Workspace.DscBuildData import DscBuildData
+from Workspace.InfBuildData import InfBuildData
## Database
#
@@ -2868,7 +41,6 @@ class InfBuildData(ModuleBuildClassObject):
#
class WorkspaceDatabase(object):
-
#
# internal class used for call corresponding file parser and caching the result
# to avoid unnecessary re-parsing