]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/InfBuildData.py
BaseTools: Replace the sqlite database with list
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / InfBuildData.py
CommitLineData
ae7b6df8
LG
1## @file\r
2# This file is used to create a database used by build tool\r
3#\r
a0767bae 4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
ae7b6df8
LG
5# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
6# This program and the accompanying materials\r
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
1ccc4d89 15from __future__ import absolute_import\r
ae7b6df8
LG
16from Common.DataType import *\r
17from Common.Misc import *\r
719fd85c 18from Common.caching import cached_property, cached_class_function\r
ae7b6df8 19from types import *\r
1100bc5a 20from .MetaFileParser import *\r
a0767bae 21from collections import OrderedDict\r
ae7b6df8 22from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClassObject, PcdClassObject\r
719fd85c 23\r
ae7b6df8
LG
24## Module build information from INF file\r
25#\r
26# This class is used to retrieve information stored in database and convert them\r
27# into ModuleBuildClassObject form for easier use for AutoGen.\r
28#\r
29class InfBuildData(ModuleBuildClassObject):\r
30 # dict used to convert PCD type in database to string used by build tool\r
31 _PCD_TYPE_STRING_ = {\r
be409b67
CJ
32 MODEL_PCD_FIXED_AT_BUILD : TAB_PCDS_FIXED_AT_BUILD,\r
33 MODEL_PCD_PATCHABLE_IN_MODULE : TAB_PCDS_PATCHABLE_IN_MODULE,\r
34 MODEL_PCD_FEATURE_FLAG : TAB_PCDS_FEATURE_FLAG,\r
35 MODEL_PCD_DYNAMIC : TAB_PCDS_DYNAMIC,\r
36 MODEL_PCD_DYNAMIC_DEFAULT : TAB_PCDS_DYNAMIC,\r
37 MODEL_PCD_DYNAMIC_HII : TAB_PCDS_DYNAMIC_HII,\r
38 MODEL_PCD_DYNAMIC_VPD : TAB_PCDS_DYNAMIC_VPD,\r
39 MODEL_PCD_DYNAMIC_EX : TAB_PCDS_DYNAMIC_EX,\r
40 MODEL_PCD_DYNAMIC_EX_DEFAULT : TAB_PCDS_DYNAMIC_EX,\r
41 MODEL_PCD_DYNAMIC_EX_HII : TAB_PCDS_DYNAMIC_EX_HII,\r
42 MODEL_PCD_DYNAMIC_EX_VPD : TAB_PCDS_DYNAMIC_EX_VPD,\r
ae7b6df8
LG
43 }\r
44\r
45 # dict used to convert part of [Defines] to members of InfBuildData directly\r
46 _PROPERTY_ = {\r
47 #\r
48 # Required Fields\r
49 #\r
50 TAB_INF_DEFINES_BASE_NAME : "_BaseName",\r
51 TAB_INF_DEFINES_FILE_GUID : "_Guid",\r
52 TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",\r
53 #\r
54 # Optional Fields\r
55 #\r
56 # TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",\r
57 TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",\r
58 TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",\r
59 # TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",\r
60 TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",\r
61 TAB_INF_DEFINES_VERSION_NUMBER : "_Version",\r
62 TAB_INF_DEFINES_VERSION_STRING : "_Version",\r
63 TAB_INF_DEFINES_VERSION : "_Version",\r
64 TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",\r
65 TAB_INF_DEFINES_SHADOW : "_Shadow",\r
66\r
67 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath",\r
68 }\r
69\r
ae7b6df8
LG
70 # regular expression for converting XXX_FLAGS in [nmake] section to new type\r
71 _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)\r
72 # dict used to convert old tool name used in [nmake] section to new ones\r
73 _TOOL_CODE_ = {\r
74 "C" : "CC",\r
91fa33ee 75 BINARY_FILE_TYPE_LIB : "SLINK",\r
ae7b6df8
LG
76 "LINK" : "DLINK",\r
77 }\r
78\r
79\r
719fd85c 80 ## Constructor of InfBuildData\r
ae7b6df8 81 #\r
719fd85c 82 # Initialize object of InfBuildData\r
ae7b6df8
LG
83 #\r
84 # @param FilePath The path of platform description file\r
85 # @param RawData The raw data of DSC file\r
86 # @param BuildDataBase Database used to retrieve module/package information\r
87 # @param Arch The target architecture\r
88 # @param Platform The name of platform employing this module\r
89 # @param Macros Macros used for replacement in DSC file\r
90 #\r
55c84777 91 def __init__(self, FilePath, RawData, BuildDatabase, Arch=TAB_ARCH_COMMON, Target=None, Toolchain=None):\r
ae7b6df8
LG
92 self.MetaFile = FilePath\r
93 self._ModuleDir = FilePath.Dir\r
94 self._RawData = RawData\r
95 self._Bdb = BuildDatabase\r
96 self._Arch = Arch\r
97 self._Target = Target\r
98 self._Toolchain = Toolchain\r
55c84777 99 self._Platform = TAB_COMMON\r
ae7b6df8
LG
100 if FilePath.Key in GlobalData.gOverrideDir:\r
101 self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]\r
719fd85c
CJ
102 else:\r
103 self._SourceOverridePath = None\r
104 self._TailComments = None\r
105 self._BaseName = None\r
106 self._DxsFile = None\r
107 self._ModuleType = None\r
108 self._ComponentType = None\r
109 self._BuildType = None\r
110 self._Guid = None\r
111 self._Version = None\r
112 self._PcdIsDriver = None\r
113 self._BinaryModule = None\r
114 self._Shadow = None\r
115 self._MakefileName = None\r
116 self._CustomMakefile = None\r
117 self._Specification = None\r
118 self._LibraryClass = None\r
119 self._ModuleEntryPointList = None\r
120 self._ModuleUnloadImageList = None\r
121 self._ConstructorList = None\r
122 self._DestructorList = None\r
123 self._Defs = OrderedDict()\r
124 self._ProtocolComments = None\r
125 self._PpiComments = None\r
126 self._GuidsUsedByPcd = OrderedDict()\r
127 self._GuidComments = None\r
128 self._PcdComments = None\r
129 self._BuildOptions = None\r
130 self._DependencyFileList = None\r
ae7b6df8
LG
131\r
132 ## XXX[key] = value\r
133 def __setitem__(self, key, value):\r
134 self.__dict__[self._PROPERTY_[key]] = value\r
135\r
136 ## value = XXX[key]\r
137 def __getitem__(self, key):\r
138 return self.__dict__[self._PROPERTY_[key]]\r
139\r
140 ## "in" test support\r
141 def __contains__(self, key):\r
142 return key in self._PROPERTY_\r
143\r
ae7b6df8 144 ## Get current effective macros\r
719fd85c 145 @cached_property\r
71cac3f7 146 def _Macros(self):\r
719fd85c
CJ
147 RetVal = {}\r
148 # EDK_GLOBAL defined macros can be applied to EDK module\r
149 if self.AutoGenVersion < 0x00010005:\r
150 RetVal.update(GlobalData.gEdkGlobal)\r
151 RetVal.update(GlobalData.gGlobalDefines)\r
152 return RetVal\r
ae7b6df8
LG
153\r
154 ## Get architecture\r
719fd85c 155 @cached_property\r
71cac3f7 156 def Arch(self):\r
ae7b6df8
LG
157 return self._Arch\r
158\r
ae7b6df8 159 ## Return the name of platform employing this module\r
719fd85c 160 @cached_property\r
71cac3f7 161 def Platform(self):\r
ae7b6df8
LG
162 return self._Platform\r
163\r
719fd85c 164 @cached_property\r
71cac3f7 165 def HeaderComments(self):\r
719fd85c 166 return [a[0] for a in self._RawData[MODEL_META_DATA_HEADER_COMMENT]]\r
71cac3f7 167\r
719fd85c 168 @cached_property\r
71cac3f7 169 def TailComments(self):\r
719fd85c 170 return [a[0] for a in self._RawData[MODEL_META_DATA_TAIL_COMMENT]]\r
71cac3f7 171\r
ae7b6df8
LG
172 ## Retrieve all information in [Defines] section\r
173 #\r
174 # (Retriving all [Defines] information in one-shot is just to save time.)\r
175 #\r
719fd85c 176 @cached_class_function\r
ae7b6df8
LG
177 def _GetHeaderInfo(self):\r
178 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
179 for Record in RecordList:\r
180 Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)\r
181 # items defined _PROPERTY_ don't need additional processing\r
182 if Name in self:\r
183 self[Name] = Value\r
ae7b6df8
LG
184 self._Defs[Name] = Value\r
185 self._Macros[Name] = Value\r
186 # some special items in [Defines] section need special treatment\r
187 elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):\r
188 if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):\r
189 Name = 'UEFI_SPECIFICATION_VERSION'\r
4231a819 190 if self._Specification is None:\r
a0767bae 191 self._Specification = OrderedDict()\r
ae7b6df8 192 self._Specification[Name] = GetHexVerValue(Value)\r
4231a819 193 if self._Specification[Name] is None:\r
ae7b6df8
LG
194 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
195 "'%s' format is not supported for %s" % (Value, Name),\r
196 File=self.MetaFile, Line=Record[-1])\r
197 elif Name == 'LIBRARY_CLASS':\r
4231a819 198 if self._LibraryClass is None:\r
ae7b6df8
LG
199 self._LibraryClass = []\r
200 ValueList = GetSplitValueList(Value)\r
201 LibraryClass = ValueList[0]\r
202 if len(ValueList) > 1:\r
203 SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
204 else:\r
205 SupModuleList = SUP_MODULE_LIST\r
206 self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))\r
207 elif Name == 'ENTRY_POINT':\r
4231a819 208 if self._ModuleEntryPointList is None:\r
ae7b6df8
LG
209 self._ModuleEntryPointList = []\r
210 self._ModuleEntryPointList.append(Value)\r
211 elif Name == 'UNLOAD_IMAGE':\r
4231a819 212 if self._ModuleUnloadImageList is None:\r
ae7b6df8
LG
213 self._ModuleUnloadImageList = []\r
214 if not Value:\r
215 continue\r
216 self._ModuleUnloadImageList.append(Value)\r
217 elif Name == 'CONSTRUCTOR':\r
4231a819 218 if self._ConstructorList is None:\r
ae7b6df8
LG
219 self._ConstructorList = []\r
220 if not Value:\r
221 continue\r
222 self._ConstructorList.append(Value)\r
223 elif Name == 'DESTRUCTOR':\r
4231a819 224 if self._DestructorList is None:\r
ae7b6df8
LG
225 self._DestructorList = []\r
226 if not Value:\r
227 continue\r
228 self._DestructorList.append(Value)\r
229 elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:\r
230 TokenList = GetSplitValueList(Value)\r
4231a819 231 if self._CustomMakefile is None:\r
ae7b6df8
LG
232 self._CustomMakefile = {}\r
233 if len(TokenList) < 2:\r
94c04559 234 self._CustomMakefile[TAB_COMPILER_MSFT] = TokenList[0]\r
ae7b6df8
LG
235 self._CustomMakefile['GCC'] = TokenList[0]\r
236 else:\r
94c04559 237 if TokenList[0] not in [TAB_COMPILER_MSFT, 'GCC']:\r
ae7b6df8
LG
238 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
239 "No supported family [%s]" % TokenList[0],\r
240 File=self.MetaFile, Line=Record[-1])\r
241 self._CustomMakefile[TokenList[0]] = TokenList[1]\r
242 else:\r
ae7b6df8
LG
243 self._Defs[Name] = Value\r
244 self._Macros[Name] = Value\r
245\r
246 #\r
247 # Retrieve information in sections specific to Edk.x modules\r
248 #\r
249 if self.AutoGenVersion >= 0x00010005:\r
250 if not self._ModuleType:\r
251 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
252 "MODULE_TYPE is not given", File=self.MetaFile)\r
253 if self._ModuleType not in SUP_MODULE_LIST:\r
254 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
255 for Record in RecordList:\r
256 Name = Record[1]\r
257 if Name == "MODULE_TYPE":\r
258 LineNo = Record[6]\r
259 break\r
260 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
261 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType, ' '.join(l for l in SUP_MODULE_LIST)),\r
262 File=self.MetaFile, Line=LineNo)\r
4231a819 263 if (self._Specification is None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):\r
ae7b6df8
LG
264 if self._ModuleType == SUP_MODULE_SMM_CORE:\r
265 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)\r
4231a819 266 if (self._Specification is None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x00010032):\r
ae7b6df8
LG
267 if self._ModuleType == SUP_MODULE_MM_CORE_STANDALONE:\r
268 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)\r
269 if self._ModuleType == SUP_MODULE_MM_STANDALONE:\r
270 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)\r
a0767bae 271 if 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
ae7b6df8
LG
272 and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:\r
273 self._BuildType = 'UEFI_OPTIONROM'\r
274 if 'PCI_COMPRESS' in self._Defs:\r
275 if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):\r
276 EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" % self.MetaFile)\r
277\r
a0767bae 278 elif 'UEFI_HII_RESOURCE_SECTION' in self._Defs \\r
ae7b6df8
LG
279 and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':\r
280 self._BuildType = 'UEFI_HII'\r
281 else:\r
282 self._BuildType = self._ModuleType.upper()\r
283\r
284 if self._DxsFile:\r
285 File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
286 # check the file validation\r
287 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
288 if ErrorCode != 0:\r
289 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
290 File=self.MetaFile, Line=LineNo)\r
719fd85c
CJ
291 if not self._DependencyFileList:\r
292 self._DependencyFileList = []\r
293 self._DependencyFileList.append(File)\r
ae7b6df8
LG
294 else:\r
295 if not self._ComponentType:\r
296 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
297 "COMPONENT_TYPE is not given", File=self.MetaFile)\r
298 self._BuildType = self._ComponentType.upper()\r
ee1ca53d
CJ
299 if self._ComponentType in COMPONENT_TO_MODULE_MAP_DICT:\r
300 self._ModuleType = COMPONENT_TO_MODULE_MAP_DICT[self._ComponentType]\r
0c60e60b 301 if self._ComponentType == EDK_COMPONENT_TYPE_LIBRARY:\r
ae7b6df8
LG
302 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
303 # make use some [nmake] section macros\r
304 Macros = self._Macros\r
305 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
306 Macros['PROCESSOR'] = self._Arch\r
307 RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
308 for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:\r
309 Value = ReplaceMacro(Value, Macros, True)\r
310 if Name == "IMAGE_ENTRY_POINT":\r
4231a819 311 if self._ModuleEntryPointList is None:\r
ae7b6df8
LG
312 self._ModuleEntryPointList = []\r
313 self._ModuleEntryPointList.append(Value)\r
314 elif Name == "DPX_SOURCE":\r
315 File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)\r
316 # check the file validation\r
317 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
318 if ErrorCode != 0:\r
319 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
320 File=self.MetaFile, Line=LineNo)\r
719fd85c
CJ
321 if not self._DependencyFileList:\r
322 self._DependencyFileList = []\r
323 self._DependencyFileList.append(File)\r
ae7b6df8
LG
324 else:\r
325 ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
fe6fdfe2 326 if len(ToolList) == 1:\r
4231a819 327 if self._BuildOptions is None:\r
a0767bae 328 self._BuildOptions = OrderedDict()\r
ae7b6df8
LG
329\r
330 if ToolList[0] in self._TOOL_CODE_:\r
331 Tool = self._TOOL_CODE_[ToolList[0]]\r
332 else:\r
333 Tool = ToolList[0]\r
334 ToolChain = "*_*_*_%s_FLAGS" % Tool\r
94c04559 335 # Edk.x only support MSFT tool chain\r
ae7b6df8
LG
336 # ignore not replaced macros in value\r
337 ValueList = GetSplitList(' ' + Value, '/D')\r
338 Dummy = ValueList[0]\r
339 for Index in range(1, len(ValueList)):\r
340 if ValueList[Index][-1] == '=' or ValueList[Index] == '':\r
341 continue\r
342 Dummy = Dummy + ' /D ' + ValueList[Index]\r
343 Value = Dummy.strip()\r
94c04559
CJ
344 if (TAB_COMPILER_MSFT, ToolChain) not in self._BuildOptions:\r
345 self._BuildOptions[TAB_COMPILER_MSFT, ToolChain] = Value\r
ae7b6df8 346 else:\r
94c04559
CJ
347 OptionString = self._BuildOptions[TAB_COMPILER_MSFT, ToolChain]\r
348 self._BuildOptions[TAB_COMPILER_MSFT, ToolChain] = OptionString + " " + Value\r
ae7b6df8
LG
349\r
350 ## Retrieve file version\r
719fd85c 351 @cached_property\r
71cac3f7 352 def AutoGenVersion(self):\r
719fd85c
CJ
353 RetVal = 0x00010000\r
354 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
355 for Record in RecordList:\r
356 if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
357 if '.' in Record[2]:\r
358 ValueList = Record[2].split('.')\r
359 Major = '%04o' % int(ValueList[0], 0)\r
360 Minor = '%04o' % int(ValueList[1], 0)\r
361 RetVal = int('0x' + Major + Minor, 0)\r
362 else:\r
363 RetVal = int(Record[2], 0)\r
364 break\r
365 return RetVal\r
ae7b6df8
LG
366\r
367 ## Retrieve BASE_NAME\r
719fd85c 368 @cached_property\r
71cac3f7 369 def BaseName(self):\r
4231a819 370 if self._BaseName is None:\r
719fd85c 371 self._GetHeaderInfo()\r
4231a819 372 if self._BaseName is None:\r
ae7b6df8
LG
373 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)\r
374 return self._BaseName\r
375\r
376 ## Retrieve DxsFile\r
719fd85c 377 @cached_property\r
71cac3f7 378 def DxsFile(self):\r
4231a819 379 if self._DxsFile is None:\r
719fd85c 380 self._GetHeaderInfo()\r
4231a819 381 if self._DxsFile is None:\r
ae7b6df8
LG
382 self._DxsFile = ''\r
383 return self._DxsFile\r
384\r
385 ## Retrieve MODULE_TYPE\r
719fd85c 386 @cached_property\r
71cac3f7 387 def ModuleType(self):\r
4231a819 388 if self._ModuleType is None:\r
719fd85c 389 self._GetHeaderInfo()\r
4231a819 390 if self._ModuleType is None:\r
8bb63e37 391 self._ModuleType = SUP_MODULE_BASE\r
ae7b6df8 392 if self._ModuleType not in SUP_MODULE_LIST:\r
8bb63e37 393 self._ModuleType = SUP_MODULE_USER_DEFINED\r
ae7b6df8
LG
394 return self._ModuleType\r
395\r
396 ## Retrieve COMPONENT_TYPE\r
719fd85c 397 @cached_property\r
71cac3f7 398 def ComponentType(self):\r
4231a819 399 if self._ComponentType is None:\r
719fd85c 400 self._GetHeaderInfo()\r
4231a819 401 if self._ComponentType is None:\r
8bb63e37 402 self._ComponentType = SUP_MODULE_USER_DEFINED\r
ae7b6df8
LG
403 return self._ComponentType\r
404\r
405 ## Retrieve "BUILD_TYPE"\r
719fd85c 406 @cached_property\r
71cac3f7 407 def BuildType(self):\r
4231a819 408 if self._BuildType is None:\r
719fd85c 409 self._GetHeaderInfo()\r
ae7b6df8 410 if not self._BuildType:\r
8bb63e37 411 self._BuildType = SUP_MODULE_BASE\r
ae7b6df8
LG
412 return self._BuildType\r
413\r
414 ## Retrieve file guid\r
719fd85c 415 @cached_property\r
71cac3f7 416 def Guid(self):\r
4231a819 417 if self._Guid is None:\r
719fd85c 418 self._GetHeaderInfo()\r
4231a819 419 if self._Guid is None:\r
ae7b6df8
LG
420 self._Guid = '00000000-0000-0000-0000-000000000000'\r
421 return self._Guid\r
422\r
423 ## Retrieve module version\r
719fd85c 424 @cached_property\r
71cac3f7 425 def Version(self):\r
4231a819 426 if self._Version is None:\r
719fd85c 427 self._GetHeaderInfo()\r
4231a819 428 if self._Version is None:\r
ae7b6df8
LG
429 self._Version = '0.0'\r
430 return self._Version\r
431\r
432 ## Retrieve PCD_IS_DRIVER\r
719fd85c 433 @cached_property\r
71cac3f7 434 def PcdIsDriver(self):\r
4231a819 435 if self._PcdIsDriver is None:\r
719fd85c 436 self._GetHeaderInfo()\r
4231a819 437 if self._PcdIsDriver is None:\r
ae7b6df8
LG
438 self._PcdIsDriver = ''\r
439 return self._PcdIsDriver\r
440\r
441 ## Retrieve SHADOW\r
719fd85c 442 @cached_property\r
71cac3f7 443 def Shadow(self):\r
4231a819 444 if self._Shadow is None:\r
719fd85c
CJ
445 self._GetHeaderInfo()\r
446 if self._Shadow and self._Shadow.upper() == 'TRUE':\r
ae7b6df8
LG
447 self._Shadow = True\r
448 else:\r
449 self._Shadow = False\r
450 return self._Shadow\r
451\r
452 ## Retrieve CUSTOM_MAKEFILE\r
719fd85c 453 @cached_property\r
71cac3f7 454 def CustomMakefile(self):\r
4231a819 455 if self._CustomMakefile is None:\r
719fd85c 456 self._GetHeaderInfo()\r
4231a819 457 if self._CustomMakefile is None:\r
ae7b6df8
LG
458 self._CustomMakefile = {}\r
459 return self._CustomMakefile\r
460\r
461 ## Retrieve EFI_SPECIFICATION_VERSION\r
719fd85c 462 @cached_property\r
71cac3f7 463 def Specification(self):\r
4231a819 464 if self._Specification is None:\r
719fd85c 465 self._GetHeaderInfo()\r
4231a819 466 if self._Specification is None:\r
ae7b6df8
LG
467 self._Specification = {}\r
468 return self._Specification\r
469\r
470 ## Retrieve LIBRARY_CLASS\r
719fd85c 471 @cached_property\r
71cac3f7 472 def LibraryClass(self):\r
4231a819 473 if self._LibraryClass is None:\r
719fd85c 474 self._GetHeaderInfo()\r
4231a819 475 if self._LibraryClass is None:\r
ae7b6df8
LG
476 self._LibraryClass = []\r
477 return self._LibraryClass\r
478\r
479 ## Retrieve ENTRY_POINT\r
719fd85c 480 @cached_property\r
71cac3f7 481 def ModuleEntryPointList(self):\r
4231a819 482 if self._ModuleEntryPointList is None:\r
719fd85c 483 self._GetHeaderInfo()\r
4231a819 484 if self._ModuleEntryPointList is None:\r
ae7b6df8
LG
485 self._ModuleEntryPointList = []\r
486 return self._ModuleEntryPointList\r
487\r
488 ## Retrieve UNLOAD_IMAGE\r
719fd85c 489 @cached_property\r
71cac3f7 490 def ModuleUnloadImageList(self):\r
4231a819 491 if self._ModuleUnloadImageList is None:\r
719fd85c 492 self._GetHeaderInfo()\r
4231a819 493 if self._ModuleUnloadImageList is None:\r
ae7b6df8
LG
494 self._ModuleUnloadImageList = []\r
495 return self._ModuleUnloadImageList\r
496\r
497 ## Retrieve CONSTRUCTOR\r
719fd85c 498 @cached_property\r
71cac3f7 499 def ConstructorList(self):\r
4231a819 500 if self._ConstructorList is None:\r
719fd85c 501 self._GetHeaderInfo()\r
4231a819 502 if self._ConstructorList is None:\r
ae7b6df8
LG
503 self._ConstructorList = []\r
504 return self._ConstructorList\r
505\r
506 ## Retrieve DESTRUCTOR\r
719fd85c 507 @cached_property\r
71cac3f7 508 def DestructorList(self):\r
4231a819 509 if self._DestructorList is None:\r
719fd85c 510 self._GetHeaderInfo()\r
4231a819 511 if self._DestructorList is None:\r
ae7b6df8
LG
512 self._DestructorList = []\r
513 return self._DestructorList\r
514\r
515 ## Retrieve definies other than above ones\r
719fd85c 516 @cached_property\r
71cac3f7 517 def Defines(self):\r
719fd85c 518 self._GetHeaderInfo()\r
ae7b6df8
LG
519 return self._Defs\r
520\r
521 ## Retrieve binary files\r
719fd85c 522 @cached_class_function\r
ae7b6df8 523 def _GetBinaries(self):\r
719fd85c
CJ
524 RetVal = []\r
525 RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
526 Macros = self._Macros\r
527 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
528 Macros['PROCESSOR'] = self._Arch\r
529 for Record in RecordList:\r
530 FileType = Record[0]\r
531 LineNo = Record[-1]\r
532 Target = TAB_COMMON\r
533 FeatureFlag = []\r
534 if Record[2]:\r
535 TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
536 if TokenList:\r
537 Target = TokenList[0]\r
538 if len(TokenList) > 1:\r
539 FeatureFlag = Record[1:]\r
540\r
541 File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)\r
542 # check the file validation\r
543 ErrorCode, ErrorInfo = File.Validate()\r
544 if ErrorCode != 0:\r
545 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
546 RetVal.append(File)\r
547 return RetVal\r
ae7b6df8
LG
548\r
549 ## Retrieve binary files with error check.\r
719fd85c 550 @cached_property\r
71cac3f7 551 def Binaries(self):\r
719fd85c
CJ
552 RetVal = self._GetBinaries()\r
553 if GlobalData.gIgnoreSource and not RetVal:\r
554 ErrorInfo = "The INF file does not contain any RetVal to use in creating the image\n"\r
ae7b6df8
LG
555 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)\r
556\r
719fd85c 557 return RetVal\r
f5f4667d 558\r
ae7b6df8 559 ## Retrieve source files\r
719fd85c 560 @cached_property\r
71cac3f7 561 def Sources(self):\r
719fd85c 562 self._GetHeaderInfo()\r
ae7b6df8
LG
563 # Ignore all source files in a binary build mode\r
564 if GlobalData.gIgnoreSource:\r
719fd85c 565 return []\r
ae7b6df8 566\r
719fd85c
CJ
567 RetVal = []\r
568 RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
569 Macros = self._Macros\r
570 for Record in RecordList:\r
571 LineNo = Record[-1]\r
572 ToolChainFamily = Record[1]\r
573 TagName = Record[2]\r
574 ToolCode = Record[3]\r
575 if self.AutoGenVersion < 0x00010005:\r
576 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
577 Macros['PROCESSOR'] = self._Arch\r
578 SourceFile = NormPath(Record[0], Macros)\r
579 if SourceFile[0] == os.path.sep:\r
580 SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])\r
581 # old module source files (Edk)\r
582 File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,\r
583 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
584 # check the file validation\r
585 ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
586 if ErrorCode != 0:\r
587 if File.Ext.lower() == '.h':\r
588 EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,\r
589 File=self.MetaFile, Line=LineNo)\r
590 continue\r
591 else:\r
592 EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)\r
593 else:\r
594 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',\r
595 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
596 # check the file validation\r
597 ErrorCode, ErrorInfo = File.Validate()\r
598 if ErrorCode != 0:\r
599 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
ae7b6df8 600\r
719fd85c
CJ
601 RetVal.append(File)\r
602 # add any previously found dependency files to the source list\r
603 if self._DependencyFileList:\r
604 RetVal.extend(self._DependencyFileList)\r
605 return RetVal\r
ae7b6df8
LG
606\r
607 ## Retrieve library classes employed by this module\r
719fd85c 608 @cached_property\r
71cac3f7 609 def LibraryClasses(self):\r
719fd85c
CJ
610 RetVal = OrderedDict()\r
611 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
612 for Record in RecordList:\r
613 Lib = Record[0]\r
614 Instance = Record[1]\r
615 if Instance:\r
616 Instance = NormPath(Instance, self._Macros)\r
617 RetVal[Lib] = Instance\r
618 return RetVal\r
ae7b6df8
LG
619\r
620 ## Retrieve library names (for Edk.x style of modules)\r
719fd85c 621 @cached_property\r
71cac3f7 622 def Libraries(self):\r
719fd85c
CJ
623 RetVal = []\r
624 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
625 for Record in RecordList:\r
626 LibraryName = ReplaceMacro(Record[0], self._Macros, False)\r
627 # in case of name with '.lib' extension, which is unusual in Edk.x inf\r
628 LibraryName = os.path.splitext(LibraryName)[0]\r
629 if LibraryName not in RetVal:\r
630 RetVal.append(LibraryName)\r
631 return RetVal\r
632\r
633 @cached_property\r
71cac3f7
CJ
634 def ProtocolComments(self):\r
635 self.Protocols\r
ae7b6df8 636 return self._ProtocolComments\r
71cac3f7 637\r
ae7b6df8 638 ## Retrieve protocols consumed/produced by this module\r
719fd85c 639 @cached_property\r
71cac3f7 640 def Protocols(self):\r
719fd85c
CJ
641 RetVal = OrderedDict()\r
642 self._ProtocolComments = OrderedDict()\r
643 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
644 for Record in RecordList:\r
645 CName = Record[0]\r
646 Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)\r
647 if Value is None:\r
648 PackageList = "\n\t".join(str(P) for P in self.Packages)\r
649 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
650 "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
651 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
652 RetVal[CName] = Value\r
653 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
654 self._ProtocolComments[CName] = [a[0] for a in CommentRecords]\r
655 return RetVal\r
656\r
657 @cached_property\r
71cac3f7
CJ
658 def PpiComments(self):\r
659 self.Ppis\r
ae7b6df8 660 return self._PpiComments\r
71cac3f7 661\r
ae7b6df8 662 ## Retrieve PPIs consumed/produced by this module\r
719fd85c 663 @cached_property\r
71cac3f7 664 def Ppis(self):\r
719fd85c
CJ
665 RetVal = OrderedDict()\r
666 self._PpiComments = OrderedDict()\r
667 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
668 for Record in RecordList:\r
669 CName = Record[0]\r
670 Value = PpiValue(CName, self.Packages, self.MetaFile.Path)\r
671 if Value is None:\r
672 PackageList = "\n\t".join(str(P) for P in self.Packages)\r
673 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
674 "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
675 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
676 RetVal[CName] = Value\r
677 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
678 self._PpiComments[CName] = [a[0] for a in CommentRecords]\r
679 return RetVal\r
680\r
681 @cached_property\r
71cac3f7
CJ
682 def GuidComments(self):\r
683 self.Guids\r
ae7b6df8 684 return self._GuidComments\r
71cac3f7 685\r
ae7b6df8 686 ## Retrieve GUIDs consumed/produced by this module\r
719fd85c 687 @cached_property\r
71cac3f7 688 def Guids(self):\r
719fd85c
CJ
689 RetVal = OrderedDict()\r
690 self._GuidComments = OrderedDict()\r
691 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
692 for Record in RecordList:\r
693 CName = Record[0]\r
694 Value = GuidValue(CName, self.Packages, self.MetaFile.Path)\r
695 if Value is None:\r
696 PackageList = "\n\t".join(str(P) for P in self.Packages)\r
697 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
698 "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
699 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
700 RetVal[CName] = Value\r
701 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
702 self._GuidComments[CName] = [a[0] for a in CommentRecords]\r
703 return RetVal\r
ae7b6df8
LG
704\r
705 ## Retrieve include paths necessary for this module (for Edk.x style of modules)\r
719fd85c 706 @cached_property\r
71cac3f7 707 def Includes(self):\r
719fd85c
CJ
708 RetVal = []\r
709 if self._SourceOverridePath:\r
710 RetVal.append(self._SourceOverridePath)\r
ae7b6df8 711\r
719fd85c
CJ
712 Macros = self._Macros\r
713 Macros['PROCESSOR'] = GlobalData.gEdkGlobal.get('PROCESSOR', self._Arch)\r
714 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
715 for Record in RecordList:\r
716 if Record[0].find('EDK_SOURCE') > -1:\r
717 Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
718 File = NormPath(Record[0], self._Macros)\r
719 if File[0] == '.':\r
720 File = os.path.join(self._ModuleDir, File)\r
ae7b6df8 721 else:\r
719fd85c
CJ
722 File = os.path.join(GlobalData.gWorkspace, File)\r
723 File = RealPath(os.path.normpath(File))\r
724 if File:\r
725 RetVal.append(File)\r
726\r
727 # TRICK: let compiler to choose correct header file\r
728 Macros['EDK_SOURCE'] = GlobalData.gEdkSource\r
729 File = NormPath(Record[0], self._Macros)\r
730 if File[0] == '.':\r
731 File = os.path.join(self._ModuleDir, File)\r
732 else:\r
733 File = os.path.join(GlobalData.gWorkspace, File)\r
734 File = RealPath(os.path.normpath(File))\r
735 if File:\r
736 RetVal.append(File)\r
737 else:\r
738 File = NormPath(Record[0], Macros)\r
739 if File[0] == '.':\r
740 File = os.path.join(self._ModuleDir, File)\r
741 else:\r
742 File = mws.join(GlobalData.gWorkspace, File)\r
743 File = RealPath(os.path.normpath(File))\r
744 if File:\r
745 RetVal.append(File)\r
746 if not File and Record[0].find('EFI_SOURCE') > -1:\r
747 # tricky to regard WorkSpace as EFI_SOURCE\r
748 Macros['EFI_SOURCE'] = GlobalData.gWorkspace\r
ae7b6df8
LG
749 File = NormPath(Record[0], Macros)\r
750 if File[0] == '.':\r
751 File = os.path.join(self._ModuleDir, File)\r
752 else:\r
719fd85c 753 File = os.path.join(GlobalData.gWorkspace, File)\r
ae7b6df8
LG
754 File = RealPath(os.path.normpath(File))\r
755 if File:\r
719fd85c
CJ
756 RetVal.append(File)\r
757 return RetVal\r
ae7b6df8
LG
758\r
759 ## Retrieve packages this module depends on\r
719fd85c 760 @cached_property\r
71cac3f7 761 def Packages(self):\r
719fd85c
CJ
762 RetVal = []\r
763 RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
764 Macros = self._Macros\r
765 Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
766 for Record in RecordList:\r
767 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
768 # check the file validation\r
769 ErrorCode, ErrorInfo = File.Validate('.dec')\r
770 if ErrorCode != 0:\r
ae7b6df8 771 LineNo = Record[-1]\r
719fd85c
CJ
772 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
773 # parse this package now. we need it to get protocol/ppi/guid value\r
774 RetVal.append(self._Bdb[File, self._Arch, self._Target, self._Toolchain])\r
775 return RetVal\r
ae7b6df8
LG
776\r
777 ## Retrieve PCD comments\r
719fd85c 778 @cached_property\r
71cac3f7
CJ
779 def PcdComments(self):\r
780 self.Pcds\r
ae7b6df8 781 return self._PcdComments\r
71cac3f7 782\r
ae7b6df8 783 ## Retrieve PCDs used in this module\r
719fd85c 784 @cached_property\r
71cac3f7 785 def Pcds(self):\r
719fd85c
CJ
786 self._PcdComments = OrderedDict()\r
787 RetVal = OrderedDict()\r
788 RetVal.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
789 RetVal.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
790 RetVal.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
791 RetVal.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
792 RetVal.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
793 return RetVal\r
ae7b6df8 794\r
34e733f2
FB
795 @cached_property\r
796 def PcdsName(self):\r
797 PcdsName = set()\r
798 for Type in (MODEL_PCD_FIXED_AT_BUILD,MODEL_PCD_PATCHABLE_IN_MODULE,MODEL_PCD_FEATURE_FLAG,MODEL_PCD_DYNAMIC,MODEL_PCD_DYNAMIC_EX):\r
799 RecordList = self._RawData[Type, self._Arch, self._Platform]\r
800 for TokenSpaceGuid, PcdCName, _, _, _, _, _ in RecordList:\r
801 PcdsName.add((PcdCName, TokenSpaceGuid))\r
802 return PcdsName\r
803\r
ae7b6df8 804 ## Retrieve build options specific to this module\r
719fd85c 805 @cached_property\r
71cac3f7 806 def BuildOptions(self):\r
4231a819 807 if self._BuildOptions is None:\r
a0767bae 808 self._BuildOptions = OrderedDict()\r
ae7b6df8
LG
809 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]\r
810 for Record in RecordList:\r
811 ToolChainFamily = Record[0]\r
812 ToolChain = Record[1]\r
813 Option = Record[2]\r
814 if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):\r
815 self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
816 else:\r
817 # concatenate the option string if they're for the same tool\r
818 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
819 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
820 return self._BuildOptions\r
821\r
822 ## Retrieve dependency expression\r
719fd85c 823 @cached_property\r
71cac3f7 824 def Depex(self):\r
719fd85c 825 RetVal = tdict(False, 2)\r
ae7b6df8 826\r
719fd85c
CJ
827 # If the module has only Binaries and no Sources, then ignore [Depex]\r
828 if not self.Sources and self.Binaries:\r
829 return RetVal\r
830\r
831 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
832 # PEIM and DXE drivers must have a valid [Depex] section\r
833 if len(self.LibraryClass) == 0 and len(RecordList) == 0:\r
834 if self.ModuleType == SUP_MODULE_DXE_DRIVER or self.ModuleType == SUP_MODULE_PEIM or self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER or \\r
835 self.ModuleType == SUP_MODULE_DXE_SAL_DRIVER or self.ModuleType == SUP_MODULE_DXE_RUNTIME_DRIVER:\r
836 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
837 % self.ModuleType, File=self.MetaFile)\r
838\r
839 if len(RecordList) != 0 and self.ModuleType == SUP_MODULE_USER_DEFINED:\r
ae7b6df8 840 for Record in RecordList:\r
719fd85c
CJ
841 if Record[4] not in [SUP_MODULE_PEIM, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SMM_DRIVER]:\r
842 EdkLogger.error('build', FORMAT_INVALID,\r
843 "'%s' module must specify the type of [Depex] section" % self.ModuleType,\r
844 File=self.MetaFile)\r
a10def91 845\r
719fd85c
CJ
846 TemporaryDictionary = OrderedDict()\r
847 for Record in RecordList:\r
848 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
849 Arch = Record[3]\r
850 ModuleType = Record[4]\r
851 TokenList = DepexStr.split()\r
852 if (Arch, ModuleType) not in TemporaryDictionary:\r
853 TemporaryDictionary[Arch, ModuleType] = []\r
854 DepexList = TemporaryDictionary[Arch, ModuleType]\r
855 for Token in TokenList:\r
856 if Token in DEPEX_SUPPORTED_OPCODE_SET:\r
857 DepexList.append(Token)\r
858 elif Token.endswith(".inf"): # module file name\r
859 ModuleFile = os.path.normpath(Token)\r
860 Module = self.BuildDatabase[ModuleFile]\r
861 if Module is None:\r
862 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",\r
863 ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
864 DepexList.append(Module.Guid)\r
865 else:\r
866 # it use the Fixed PCD format\r
867 if '.' in Token:\r
868 if tuple(Token.split('.')[::-1]) not in self.Pcds:\r
869 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "PCD [{}] used in [Depex] section should be listed in module PCD section".format(Token), File=self.MetaFile, Line=Record[-1])\r
870 else:\r
871 if self.Pcds[tuple(Token.split('.')[::-1])].DatumType != TAB_VOID:\r
872 EdkLogger.error('build', FORMAT_INVALID, "PCD [{}] used in [Depex] section should be VOID* datum type".format(Token), File=self.MetaFile, Line=Record[-1])\r
873 Value = Token\r
874 else:\r
875 # get the GUID value now\r
876 Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)\r
4231a819 877 if Value is None:\r
719fd85c
CJ
878 Value = PpiValue(Token, self.Packages, self.MetaFile.Path)\r
879 if Value is None:\r
880 Value = GuidValue(Token, self.Packages, self.MetaFile.Path)\r
881\r
882 if Value is None:\r
883 PackageList = "\n\t".join(str(P) for P in self.Packages)\r
884 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
885 "Value of [%s] is not found in" % Token,\r
886 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
887 DepexList.append(Value)\r
888 for Arch, ModuleType in TemporaryDictionary:\r
889 RetVal[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType]\r
890 return RetVal\r
ae7b6df8
LG
891\r
892 ## Retrieve depedency expression\r
719fd85c 893 @cached_property\r
71cac3f7 894 def DepexExpression(self):\r
719fd85c
CJ
895 RetVal = tdict(False, 2)\r
896 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
897 TemporaryDictionary = OrderedDict()\r
898 for Record in RecordList:\r
899 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
900 Arch = Record[3]\r
901 ModuleType = Record[4]\r
902 TokenList = DepexStr.split()\r
903 if (Arch, ModuleType) not in TemporaryDictionary:\r
904 TemporaryDictionary[Arch, ModuleType] = ''\r
905 for Token in TokenList:\r
906 TemporaryDictionary[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType] + Token.strip() + ' '\r
907 for Arch, ModuleType in TemporaryDictionary:\r
908 RetVal[Arch, ModuleType] = TemporaryDictionary[Arch, ModuleType]\r
909 return RetVal\r
910\r
911 @cached_class_function\r
ae7b6df8 912 def GetGuidsUsedByPcd(self):\r
719fd85c 913 self.Pcds\r
ae7b6df8 914 return self._GuidsUsedByPcd\r
71cac3f7 915\r
ae7b6df8
LG
916 ## Retrieve PCD for given type\r
917 def _GetPcd(self, Type):\r
a0767bae 918 Pcds = OrderedDict()\r
ae7b6df8
LG
919 PcdDict = tdict(True, 4)\r
920 PcdList = []\r
921 RecordList = self._RawData[Type, self._Arch, self._Platform]\r
922 for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:\r
923 PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)\r
924 PcdList.append((PcdCName, TokenSpaceGuid))\r
925 # get the guid value\r
926 if TokenSpaceGuid not in self.Guids:\r
927 Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)\r
4231a819 928 if Value is None:\r
8252e6bf 929 PackageList = "\n\t".join(str(P) for P in self.Packages)\r
ae7b6df8
LG
930 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
931 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,\r
932 ExtraData=PackageList, File=self.MetaFile, Line=LineNo)\r
933 self.Guids[TokenSpaceGuid] = Value\r
934 self._GuidsUsedByPcd[TokenSpaceGuid] = Value\r
935 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]\r
936 Comments = []\r
937 for CmtRec in CommentRecords:\r
938 Comments.append(CmtRec[0])\r
939 self._PcdComments[TokenSpaceGuid, PcdCName] = Comments\r
940\r
941 # resolve PCD type, value, datum info, etc. by getting its definition from package\r
e7df35b2 942 _GuidDict = self.Guids.copy()\r
ae7b6df8
LG
943 for PcdCName, TokenSpaceGuid in PcdList:\r
944 PcdRealName = PcdCName\r
945 Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
4231a819 946 if Setting is None:\r
ae7b6df8
LG
947 continue\r
948 ValueList = AnalyzePcdData(Setting)\r
949 DefaultValue = ValueList[0]\r
950 Pcd = PcdClassObject(\r
951 PcdCName,\r
952 TokenSpaceGuid,\r
953 '',\r
954 '',\r
955 DefaultValue,\r
956 '',\r
957 '',\r
958 {},\r
959 False,\r
960 self.Guids[TokenSpaceGuid]\r
961 )\r
962 if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:\r
963 # Patch PCD: TokenSpace.PcdCName|Value|Offset\r
964 Pcd.Offset = ValueList[1]\r
965\r
966 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
967 for Package in self.Packages:\r
968 for key in Package.Pcds:\r
969 if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):\r
970 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
971 Pcd_Type = item[0].split('_')[-1]\r
972 if Pcd_Type == Package.Pcds[key].Type:\r
973 Value = Package.Pcds[key]\r
974 Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type\r
975 if len(key) == 2:\r
976 newkey = (Value.TokenCName, key[1])\r
977 elif len(key) == 3:\r
978 newkey = (Value.TokenCName, key[1], key[2])\r
979 del Package.Pcds[key]\r
980 Package.Pcds[newkey] = Value\r
981 break\r
982 else:\r
983 pass\r
984 else:\r
985 pass\r
986\r
987 # get necessary info from package declaring this PCD\r
988 for Package in self.Packages:\r
989 #\r
990 # 'dynamic' in INF means its type is determined by platform;\r
991 # if platform doesn't give its type, use 'lowest' one in the\r
992 # following order, if any\r
993 #\r
be409b67 994 # TAB_PCDS_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE, TAB_PCDS_FEATURE_FLAG, TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_EX\r
ae7b6df8 995 #\r
e7df35b2 996 _GuidDict.update(Package.Guids)\r
ae7b6df8
LG
997 PcdType = self._PCD_TYPE_STRING_[Type]\r
998 if Type == MODEL_PCD_DYNAMIC:\r
999 Pcd.Pending = True\r
be409b67 1000 for T in PCD_TYPE_LIST:\r
ae7b6df8
LG
1001 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
1002 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
1003 if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:\r
1004 PcdType = T\r
1005 PcdCName = item[0]\r
1006 break\r
1007 else:\r
1008 pass\r
1009 break\r
1010 else:\r
1011 if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:\r
1012 PcdType = T\r
1013 break\r
1014\r
1015 else:\r
1016 Pcd.Pending = False\r
1017 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
1018 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
1019 Pcd_Type = item[0].split('_')[-1]\r
1020 if Pcd_Type == PcdType:\r
1021 PcdCName = item[0]\r
1022 break\r
1023 else:\r
1024 pass\r
1025 else:\r
1026 pass\r
1027\r
1028 if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
1029 PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]\r
1030 Pcd.Type = PcdType\r
1031 Pcd.TokenValue = PcdInPackage.TokenValue\r
1032\r
1033 #\r
1034 # Check whether the token value exist or not.\r
1035 #\r
4231a819 1036 if Pcd.TokenValue is None or Pcd.TokenValue == "":\r
ae7b6df8
LG
1037 EdkLogger.error(\r
1038 'build',\r
1039 FORMAT_INVALID,\r
1040 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdRealName, str(Package)),\r
1041 File=self.MetaFile, Line=LineNo,\r
1042 ExtraData=None\r
1043 )\r
1044 #\r
1045 # Check hexadecimal token value length and format.\r
1046 #\r
1047 ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)\r
1048 if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):\r
4231a819 1049 if ReIsValidPcdTokenValue.match(Pcd.TokenValue) is None:\r
ae7b6df8
LG
1050 EdkLogger.error(\r
1051 'build',\r
1052 FORMAT_INVALID,\r
1053 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),\r
1054 File=self.MetaFile, Line=LineNo,\r
1055 ExtraData=None\r
1056 )\r
1057\r
1058 #\r
1059 # Check decimal token value length and format.\r
1060 #\r
1061 else:\r
1062 try:\r
1063 TokenValueInt = int (Pcd.TokenValue, 10)\r
1064 if (TokenValueInt < 0 or TokenValueInt > 4294967295):\r
1065 EdkLogger.error(\r
1066 'build',\r
1067 FORMAT_INVALID,\r
1068 "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)),\r
1069 File=self.MetaFile, Line=LineNo,\r
1070 ExtraData=None\r
1071 )\r
1072 except:\r
1073 EdkLogger.error(\r
1074 'build',\r
1075 FORMAT_INVALID,\r
1076 "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)),\r
1077 File=self.MetaFile, Line=LineNo,\r
1078 ExtraData=None\r
1079 )\r
1080\r
1081 Pcd.DatumType = PcdInPackage.DatumType\r
1082 Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
1083 Pcd.InfDefaultValue = Pcd.DefaultValue\r
c93356ad 1084 if not Pcd.DefaultValue:\r
ae7b6df8 1085 Pcd.DefaultValue = PcdInPackage.DefaultValue\r
726c501c
YZ
1086 else:\r
1087 try:\r
e7df35b2 1088 Pcd.DefaultValue = ValueExpressionEx(Pcd.DefaultValue, Pcd.DatumType, _GuidDict)(True)\r
5b0671c1 1089 except BadExpression as Value:\r
726c501c
YZ
1090 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(TokenSpaceGuid, PcdRealName, Pcd.DefaultValue, Value),\r
1091 File=self.MetaFile, Line=LineNo)\r
ae7b6df8
LG
1092 break\r
1093 else:\r
1094 EdkLogger.error(\r
1095 'build',\r
1096 FORMAT_INVALID,\r
1097 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, self.MetaFile),\r
1098 File=self.MetaFile, Line=LineNo,\r
8252e6bf 1099 ExtraData="\t%s" % '\n\t'.join(str(P) for P in self.Packages)\r
ae7b6df8
LG
1100 )\r
1101 Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
1102\r
1103 return Pcds\r
1104\r
1105 ## check whether current module is binary module\r
71cac3f7
CJ
1106 @property\r
1107 def IsBinaryModule(self):\r
1108 if (self.Binaries and not self.Sources) or GlobalData.gIgnoreSource:\r
ae7b6df8 1109 return True\r
71cac3f7 1110 return False\r