BaseTools: Use absolute import in Workspace
[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
1100bc5a 15from __future__ import absolute_import\r
5a57246e 16from Common.StringUtils import *\r
ae7b6df8
LG
17from Common.DataType import *\r
18from Common.Misc import *\r
19from types import *\r
1100bc5a 20from .MetaFileParser import *\r
a0767bae 21from collections import OrderedDict\r
ae7b6df8
LG
22\r
23from Workspace.BuildClassObject import ModuleBuildClassObject, LibraryClassObject, PcdClassObject\r
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
80 ## Constructor of DscBuildData\r
81 #\r
82 # Initialize object of DscBuildData\r
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 self._SourceOverridePath = None\r
101 if FilePath.Key in GlobalData.gOverrideDir:\r
102 self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]\r
103 self._Clear()\r
104\r
105 ## XXX[key] = value\r
106 def __setitem__(self, key, value):\r
107 self.__dict__[self._PROPERTY_[key]] = value\r
108\r
109 ## value = XXX[key]\r
110 def __getitem__(self, key):\r
111 return self.__dict__[self._PROPERTY_[key]]\r
112\r
113 ## "in" test support\r
114 def __contains__(self, key):\r
115 return key in self._PROPERTY_\r
116\r
117 ## Set all internal used members of InfBuildData to None\r
118 def _Clear(self):\r
119 self._HeaderComments = None\r
120 self._TailComments = None\r
121 self._Header_ = None\r
122 self._AutoGenVersion = None\r
123 self._BaseName = None\r
124 self._DxsFile = None\r
125 self._ModuleType = None\r
126 self._ComponentType = None\r
127 self._BuildType = None\r
128 self._Guid = None\r
129 self._Version = None\r
130 self._PcdIsDriver = None\r
131 self._BinaryModule = None\r
132 self._Shadow = None\r
133 self._MakefileName = None\r
134 self._CustomMakefile = None\r
135 self._Specification = None\r
136 self._LibraryClass = None\r
137 self._ModuleEntryPointList = None\r
138 self._ModuleUnloadImageList = None\r
139 self._ConstructorList = None\r
140 self._DestructorList = None\r
a0767bae 141 self._Defs = OrderedDict()\r
ae7b6df8
LG
142 self._Binaries = None\r
143 self._Sources = None\r
144 self._LibraryClasses = None\r
145 self._Libraries = None\r
146 self._Protocols = None\r
147 self._ProtocolComments = None\r
148 self._Ppis = None\r
149 self._PpiComments = None\r
150 self._Guids = None\r
a0767bae 151 self._GuidsUsedByPcd = OrderedDict()\r
ae7b6df8
LG
152 self._GuidComments = None\r
153 self._Includes = None\r
154 self._Packages = None\r
155 self._Pcds = None\r
156 self._PcdComments = None\r
157 self._BuildOptions = None\r
158 self._Depex = None\r
159 self._DepexExpression = None\r
160 self.__Macros = None\r
161\r
162 ## Get current effective macros\r
163 def _GetMacros(self):\r
4231a819 164 if self.__Macros is None:\r
ae7b6df8
LG
165 self.__Macros = {}\r
166 # EDK_GLOBAL defined macros can be applied to EDK module\r
167 if self.AutoGenVersion < 0x00010005:\r
168 self.__Macros.update(GlobalData.gEdkGlobal)\r
169 self.__Macros.update(GlobalData.gGlobalDefines)\r
170 return self.__Macros\r
171\r
172 ## Get architecture\r
173 def _GetArch(self):\r
174 return self._Arch\r
175\r
176 ## Set architecture\r
177 #\r
178 # Changing the default ARCH to another may affect all other information\r
179 # because all information in a platform may be ARCH-related. That's\r
180 # why we need to clear all internal used members, in order to cause all\r
181 # information to be re-retrieved.\r
182 #\r
183 # @param Value The value of ARCH\r
184 #\r
185 def _SetArch(self, Value):\r
186 if self._Arch == Value:\r
187 return\r
188 self._Arch = Value\r
189 self._Clear()\r
190\r
191 ## Return the name of platform employing this module\r
192 def _GetPlatform(self):\r
193 return self._Platform\r
194\r
195 ## Change the name of platform employing this module\r
196 #\r
197 # Changing the default name of platform to another may affect some information\r
198 # because they may be PLATFORM-related. That's why we need to clear all internal\r
199 # used members, in order to cause all information to be re-retrieved.\r
200 #\r
201 def _SetPlatform(self, Value):\r
202 if self._Platform == Value:\r
203 return\r
204 self._Platform = Value\r
205 self._Clear()\r
206 def _GetHeaderComments(self):\r
207 if not self._HeaderComments:\r
208 self._HeaderComments = []\r
209 RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]\r
210 for Record in RecordList:\r
211 self._HeaderComments.append(Record[0])\r
212 return self._HeaderComments\r
213 def _GetTailComments(self):\r
214 if not self._TailComments:\r
215 self._TailComments = []\r
216 RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]\r
217 for Record in RecordList:\r
218 self._TailComments.append(Record[0])\r
219 return self._TailComments\r
220 ## Retrieve all information in [Defines] section\r
221 #\r
222 # (Retriving all [Defines] information in one-shot is just to save time.)\r
223 #\r
224 def _GetHeaderInfo(self):\r
225 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
226 for Record in RecordList:\r
227 Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)\r
228 # items defined _PROPERTY_ don't need additional processing\r
229 if Name in self:\r
230 self[Name] = Value\r
ae7b6df8
LG
231 self._Defs[Name] = Value\r
232 self._Macros[Name] = Value\r
233 # some special items in [Defines] section need special treatment\r
234 elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):\r
235 if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):\r
236 Name = 'UEFI_SPECIFICATION_VERSION'\r
4231a819 237 if self._Specification is None:\r
a0767bae 238 self._Specification = OrderedDict()\r
ae7b6df8 239 self._Specification[Name] = GetHexVerValue(Value)\r
4231a819 240 if self._Specification[Name] is None:\r
ae7b6df8
LG
241 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
242 "'%s' format is not supported for %s" % (Value, Name),\r
243 File=self.MetaFile, Line=Record[-1])\r
244 elif Name == 'LIBRARY_CLASS':\r
4231a819 245 if self._LibraryClass is None:\r
ae7b6df8
LG
246 self._LibraryClass = []\r
247 ValueList = GetSplitValueList(Value)\r
248 LibraryClass = ValueList[0]\r
249 if len(ValueList) > 1:\r
250 SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
251 else:\r
252 SupModuleList = SUP_MODULE_LIST\r
253 self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))\r
254 elif Name == 'ENTRY_POINT':\r
4231a819 255 if self._ModuleEntryPointList is None:\r
ae7b6df8
LG
256 self._ModuleEntryPointList = []\r
257 self._ModuleEntryPointList.append(Value)\r
258 elif Name == 'UNLOAD_IMAGE':\r
4231a819 259 if self._ModuleUnloadImageList is None:\r
ae7b6df8
LG
260 self._ModuleUnloadImageList = []\r
261 if not Value:\r
262 continue\r
263 self._ModuleUnloadImageList.append(Value)\r
264 elif Name == 'CONSTRUCTOR':\r
4231a819 265 if self._ConstructorList is None:\r
ae7b6df8
LG
266 self._ConstructorList = []\r
267 if not Value:\r
268 continue\r
269 self._ConstructorList.append(Value)\r
270 elif Name == 'DESTRUCTOR':\r
4231a819 271 if self._DestructorList is None:\r
ae7b6df8
LG
272 self._DestructorList = []\r
273 if not Value:\r
274 continue\r
275 self._DestructorList.append(Value)\r
276 elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:\r
277 TokenList = GetSplitValueList(Value)\r
4231a819 278 if self._CustomMakefile is None:\r
ae7b6df8
LG
279 self._CustomMakefile = {}\r
280 if len(TokenList) < 2:\r
281 self._CustomMakefile['MSFT'] = TokenList[0]\r
282 self._CustomMakefile['GCC'] = TokenList[0]\r
283 else:\r
284 if TokenList[0] not in ['MSFT', 'GCC']:\r
285 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
286 "No supported family [%s]" % TokenList[0],\r
287 File=self.MetaFile, Line=Record[-1])\r
288 self._CustomMakefile[TokenList[0]] = TokenList[1]\r
289 else:\r
ae7b6df8
LG
290 self._Defs[Name] = Value\r
291 self._Macros[Name] = Value\r
292\r
293 #\r
294 # Retrieve information in sections specific to Edk.x modules\r
295 #\r
296 if self.AutoGenVersion >= 0x00010005:\r
297 if not self._ModuleType:\r
298 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
299 "MODULE_TYPE is not given", File=self.MetaFile)\r
300 if self._ModuleType not in SUP_MODULE_LIST:\r
301 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
302 for Record in RecordList:\r
303 Name = Record[1]\r
304 if Name == "MODULE_TYPE":\r
305 LineNo = Record[6]\r
306 break\r
307 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
308 "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
309 File=self.MetaFile, Line=LineNo)\r
4231a819 310 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
311 if self._ModuleType == SUP_MODULE_SMM_CORE:\r
312 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 313 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
314 if self._ModuleType == SUP_MODULE_MM_CORE_STANDALONE:\r
315 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
316 if self._ModuleType == SUP_MODULE_MM_STANDALONE:\r
317 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 318 if 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
ae7b6df8
LG
319 and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:\r
320 self._BuildType = 'UEFI_OPTIONROM'\r
321 if 'PCI_COMPRESS' in self._Defs:\r
322 if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):\r
323 EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" % self.MetaFile)\r
324\r
a0767bae 325 elif 'UEFI_HII_RESOURCE_SECTION' in self._Defs \\r
ae7b6df8
LG
326 and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':\r
327 self._BuildType = 'UEFI_HII'\r
328 else:\r
329 self._BuildType = self._ModuleType.upper()\r
330\r
331 if self._DxsFile:\r
332 File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
333 # check the file validation\r
334 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
335 if ErrorCode != 0:\r
336 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
337 File=self.MetaFile, Line=LineNo)\r
4231a819 338 if self.Sources is None:\r
ae7b6df8
LG
339 self._Sources = []\r
340 self._Sources.append(File)\r
341 else:\r
342 if not self._ComponentType:\r
343 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
344 "COMPONENT_TYPE is not given", File=self.MetaFile)\r
345 self._BuildType = self._ComponentType.upper()\r
ee1ca53d
CJ
346 if self._ComponentType in COMPONENT_TO_MODULE_MAP_DICT:\r
347 self._ModuleType = COMPONENT_TO_MODULE_MAP_DICT[self._ComponentType]\r
0c60e60b 348 if self._ComponentType == EDK_COMPONENT_TYPE_LIBRARY:\r
ae7b6df8
LG
349 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
350 # make use some [nmake] section macros\r
351 Macros = self._Macros\r
352 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
353 Macros['PROCESSOR'] = self._Arch\r
354 RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
355 for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:\r
356 Value = ReplaceMacro(Value, Macros, True)\r
357 if Name == "IMAGE_ENTRY_POINT":\r
4231a819 358 if self._ModuleEntryPointList is None:\r
ae7b6df8
LG
359 self._ModuleEntryPointList = []\r
360 self._ModuleEntryPointList.append(Value)\r
361 elif Name == "DPX_SOURCE":\r
362 File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)\r
363 # check the file validation\r
364 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
365 if ErrorCode != 0:\r
366 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
367 File=self.MetaFile, Line=LineNo)\r
4231a819 368 if self.Sources is None:\r
ae7b6df8
LG
369 self._Sources = []\r
370 self._Sources.append(File)\r
371 else:\r
372 ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
373 if len(ToolList) == 0 or len(ToolList) != 1:\r
374 pass\r
375# EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,\r
376# File=self.MetaFile, Line=LineNo)\r
377 else:\r
4231a819 378 if self._BuildOptions is None:\r
a0767bae 379 self._BuildOptions = OrderedDict()\r
ae7b6df8
LG
380\r
381 if ToolList[0] in self._TOOL_CODE_:\r
382 Tool = self._TOOL_CODE_[ToolList[0]]\r
383 else:\r
384 Tool = ToolList[0]\r
385 ToolChain = "*_*_*_%s_FLAGS" % Tool\r
386 ToolChainFamily = 'MSFT' # Edk.x only support MSFT tool chain\r
387 # ignore not replaced macros in value\r
388 ValueList = GetSplitList(' ' + Value, '/D')\r
389 Dummy = ValueList[0]\r
390 for Index in range(1, len(ValueList)):\r
391 if ValueList[Index][-1] == '=' or ValueList[Index] == '':\r
392 continue\r
393 Dummy = Dummy + ' /D ' + ValueList[Index]\r
394 Value = Dummy.strip()\r
395 if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
396 self._BuildOptions[ToolChainFamily, ToolChain] = Value\r
397 else:\r
398 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
399 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value\r
400 # set _Header to non-None in order to avoid database re-querying\r
401 self._Header_ = 'DUMMY'\r
402\r
403 ## Retrieve file version\r
404 def _GetInfVersion(self):\r
4231a819 405 if self._AutoGenVersion is None:\r
ae7b6df8
LG
406 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
407 for Record in RecordList:\r
408 if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
409 if '.' in Record[2]:\r
410 ValueList = Record[2].split('.')\r
411 Major = '%04o' % int(ValueList[0], 0)\r
412 Minor = '%04o' % int(ValueList[1], 0)\r
413 self._AutoGenVersion = int('0x' + Major + Minor, 0)\r
414 else:\r
415 self._AutoGenVersion = int(Record[2], 0)\r
416 break\r
4231a819 417 if self._AutoGenVersion is None:\r
ae7b6df8
LG
418 self._AutoGenVersion = 0x00010000\r
419 return self._AutoGenVersion\r
420\r
421 ## Retrieve BASE_NAME\r
422 def _GetBaseName(self):\r
4231a819
CJ
423 if self._BaseName is None:\r
424 if self._Header_ is None:\r
ae7b6df8 425 self._GetHeaderInfo()\r
4231a819 426 if self._BaseName is None:\r
ae7b6df8
LG
427 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)\r
428 return self._BaseName\r
429\r
430 ## Retrieve DxsFile\r
431 def _GetDxsFile(self):\r
4231a819
CJ
432 if self._DxsFile is None:\r
433 if self._Header_ is None:\r
ae7b6df8 434 self._GetHeaderInfo()\r
4231a819 435 if self._DxsFile is None:\r
ae7b6df8
LG
436 self._DxsFile = ''\r
437 return self._DxsFile\r
438\r
439 ## Retrieve MODULE_TYPE\r
440 def _GetModuleType(self):\r
4231a819
CJ
441 if self._ModuleType is None:\r
442 if self._Header_ is None:\r
ae7b6df8 443 self._GetHeaderInfo()\r
4231a819 444 if self._ModuleType is None:\r
8bb63e37 445 self._ModuleType = SUP_MODULE_BASE\r
ae7b6df8 446 if self._ModuleType not in SUP_MODULE_LIST:\r
8bb63e37 447 self._ModuleType = SUP_MODULE_USER_DEFINED\r
ae7b6df8
LG
448 return self._ModuleType\r
449\r
450 ## Retrieve COMPONENT_TYPE\r
451 def _GetComponentType(self):\r
4231a819
CJ
452 if self._ComponentType is None:\r
453 if self._Header_ is None:\r
ae7b6df8 454 self._GetHeaderInfo()\r
4231a819 455 if self._ComponentType is None:\r
8bb63e37 456 self._ComponentType = SUP_MODULE_USER_DEFINED\r
ae7b6df8
LG
457 return self._ComponentType\r
458\r
459 ## Retrieve "BUILD_TYPE"\r
460 def _GetBuildType(self):\r
4231a819
CJ
461 if self._BuildType is None:\r
462 if self._Header_ is None:\r
ae7b6df8
LG
463 self._GetHeaderInfo()\r
464 if not self._BuildType:\r
8bb63e37 465 self._BuildType = SUP_MODULE_BASE\r
ae7b6df8
LG
466 return self._BuildType\r
467\r
468 ## Retrieve file guid\r
469 def _GetFileGuid(self):\r
4231a819
CJ
470 if self._Guid is None:\r
471 if self._Header_ is None:\r
ae7b6df8 472 self._GetHeaderInfo()\r
4231a819 473 if self._Guid is None:\r
ae7b6df8
LG
474 self._Guid = '00000000-0000-0000-0000-000000000000'\r
475 return self._Guid\r
476\r
477 ## Retrieve module version\r
478 def _GetVersion(self):\r
4231a819
CJ
479 if self._Version is None:\r
480 if self._Header_ is None:\r
ae7b6df8 481 self._GetHeaderInfo()\r
4231a819 482 if self._Version is None:\r
ae7b6df8
LG
483 self._Version = '0.0'\r
484 return self._Version\r
485\r
486 ## Retrieve PCD_IS_DRIVER\r
487 def _GetPcdIsDriver(self):\r
4231a819
CJ
488 if self._PcdIsDriver is None:\r
489 if self._Header_ is None:\r
ae7b6df8 490 self._GetHeaderInfo()\r
4231a819 491 if self._PcdIsDriver is None:\r
ae7b6df8
LG
492 self._PcdIsDriver = ''\r
493 return self._PcdIsDriver\r
494\r
495 ## Retrieve SHADOW\r
496 def _GetShadow(self):\r
4231a819
CJ
497 if self._Shadow is None:\r
498 if self._Header_ is None:\r
ae7b6df8 499 self._GetHeaderInfo()\r
4231a819 500 if self._Shadow is not None and self._Shadow.upper() == 'TRUE':\r
ae7b6df8
LG
501 self._Shadow = True\r
502 else:\r
503 self._Shadow = False\r
504 return self._Shadow\r
505\r
506 ## Retrieve CUSTOM_MAKEFILE\r
507 def _GetMakefile(self):\r
4231a819
CJ
508 if self._CustomMakefile is None:\r
509 if self._Header_ is None:\r
ae7b6df8 510 self._GetHeaderInfo()\r
4231a819 511 if self._CustomMakefile is None:\r
ae7b6df8
LG
512 self._CustomMakefile = {}\r
513 return self._CustomMakefile\r
514\r
515 ## Retrieve EFI_SPECIFICATION_VERSION\r
516 def _GetSpec(self):\r
4231a819
CJ
517 if self._Specification is None:\r
518 if self._Header_ is None:\r
ae7b6df8 519 self._GetHeaderInfo()\r
4231a819 520 if self._Specification is None:\r
ae7b6df8
LG
521 self._Specification = {}\r
522 return self._Specification\r
523\r
524 ## Retrieve LIBRARY_CLASS\r
525 def _GetLibraryClass(self):\r
4231a819
CJ
526 if self._LibraryClass is None:\r
527 if self._Header_ is None:\r
ae7b6df8 528 self._GetHeaderInfo()\r
4231a819 529 if self._LibraryClass is None:\r
ae7b6df8
LG
530 self._LibraryClass = []\r
531 return self._LibraryClass\r
532\r
533 ## Retrieve ENTRY_POINT\r
534 def _GetEntryPoint(self):\r
4231a819
CJ
535 if self._ModuleEntryPointList is None:\r
536 if self._Header_ is None:\r
ae7b6df8 537 self._GetHeaderInfo()\r
4231a819 538 if self._ModuleEntryPointList is None:\r
ae7b6df8
LG
539 self._ModuleEntryPointList = []\r
540 return self._ModuleEntryPointList\r
541\r
542 ## Retrieve UNLOAD_IMAGE\r
543 def _GetUnloadImage(self):\r
4231a819
CJ
544 if self._ModuleUnloadImageList is None:\r
545 if self._Header_ is None:\r
ae7b6df8 546 self._GetHeaderInfo()\r
4231a819 547 if self._ModuleUnloadImageList is None:\r
ae7b6df8
LG
548 self._ModuleUnloadImageList = []\r
549 return self._ModuleUnloadImageList\r
550\r
551 ## Retrieve CONSTRUCTOR\r
552 def _GetConstructor(self):\r
4231a819
CJ
553 if self._ConstructorList is None:\r
554 if self._Header_ is None:\r
ae7b6df8 555 self._GetHeaderInfo()\r
4231a819 556 if self._ConstructorList is None:\r
ae7b6df8
LG
557 self._ConstructorList = []\r
558 return self._ConstructorList\r
559\r
560 ## Retrieve DESTRUCTOR\r
561 def _GetDestructor(self):\r
4231a819
CJ
562 if self._DestructorList is None:\r
563 if self._Header_ is None:\r
ae7b6df8 564 self._GetHeaderInfo()\r
4231a819 565 if self._DestructorList is None:\r
ae7b6df8
LG
566 self._DestructorList = []\r
567 return self._DestructorList\r
568\r
569 ## Retrieve definies other than above ones\r
570 def _GetDefines(self):\r
a0767bae
CJ
571 if len(self._Defs) == 0 and self._Header_ is None:\r
572 self._GetHeaderInfo()\r
ae7b6df8
LG
573 return self._Defs\r
574\r
575 ## Retrieve binary files\r
576 def _GetBinaries(self):\r
4231a819 577 if self._Binaries is None:\r
ae7b6df8
LG
578 self._Binaries = []\r
579 RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
580 Macros = self._Macros\r
581 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
582 Macros['PROCESSOR'] = self._Arch\r
583 for Record in RecordList:\r
584 FileType = Record[0]\r
585 LineNo = Record[-1]\r
55c84777 586 Target = TAB_COMMON\r
ae7b6df8
LG
587 FeatureFlag = []\r
588 if Record[2]:\r
589 TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
590 if TokenList:\r
591 Target = TokenList[0]\r
592 if len(TokenList) > 1:\r
593 FeatureFlag = Record[1:]\r
594\r
595 File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)\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
600 self._Binaries.append(File)\r
601 return self._Binaries\r
602\r
603 ## Retrieve binary files with error check.\r
604 def _GetBinaryFiles(self):\r
605 Binaries = self._GetBinaries()\r
606 if GlobalData.gIgnoreSource and Binaries == []:\r
607 ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"\r
608 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)\r
609\r
610 return Binaries\r
611 ## Check whether it exists the binaries with current ARCH in AsBuild INF\r
612 def _IsSupportedArch(self):\r
613 if self._GetBinaries() and not self._GetSourceFiles():\r
614 return True\r
615 else:\r
616 return False\r
617 ## Retrieve source files\r
618 def _GetSourceFiles(self):\r
619 # Ignore all source files in a binary build mode\r
620 if GlobalData.gIgnoreSource:\r
621 self._Sources = []\r
622 return self._Sources\r
623\r
4231a819 624 if self._Sources is None:\r
ae7b6df8
LG
625 self._Sources = []\r
626 RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
627 Macros = self._Macros\r
628 for Record in RecordList:\r
629 LineNo = Record[-1]\r
630 ToolChainFamily = Record[1]\r
631 TagName = Record[2]\r
632 ToolCode = Record[3]\r
633 FeatureFlag = Record[4]\r
634 if self.AutoGenVersion < 0x00010005:\r
635 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
636 Macros['PROCESSOR'] = self._Arch\r
637 SourceFile = NormPath(Record[0], Macros)\r
638 if SourceFile[0] == os.path.sep:\r
639 SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])\r
640 # old module source files (Edk)\r
641 File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,\r
642 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
643 # check the file validation\r
644 ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
645 if ErrorCode != 0:\r
646 if File.Ext.lower() == '.h':\r
647 EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,\r
648 File=self.MetaFile, Line=LineNo)\r
649 continue\r
650 else:\r
651 EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)\r
652 else:\r
653 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',\r
654 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
655 # check the file validation\r
656 ErrorCode, ErrorInfo = File.Validate()\r
657 if ErrorCode != 0:\r
658 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
659\r
660 self._Sources.append(File)\r
661 return self._Sources\r
662\r
663 ## Retrieve library classes employed by this module\r
664 def _GetLibraryClassUses(self):\r
4231a819 665 if self._LibraryClasses is None:\r
a0767bae 666 self._LibraryClasses = OrderedDict()\r
ae7b6df8
LG
667 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
668 for Record in RecordList:\r
669 Lib = Record[0]\r
670 Instance = Record[1]\r
671 if Instance:\r
672 Instance = NormPath(Instance, self._Macros)\r
673 self._LibraryClasses[Lib] = Instance\r
674 return self._LibraryClasses\r
675\r
676 ## Retrieve library names (for Edk.x style of modules)\r
677 def _GetLibraryNames(self):\r
4231a819 678 if self._Libraries is None:\r
ae7b6df8
LG
679 self._Libraries = []\r
680 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
681 for Record in RecordList:\r
682 LibraryName = ReplaceMacro(Record[0], self._Macros, False)\r
683 # in case of name with '.lib' extension, which is unusual in Edk.x inf\r
684 LibraryName = os.path.splitext(LibraryName)[0]\r
685 if LibraryName not in self._Libraries:\r
686 self._Libraries.append(LibraryName)\r
687 return self._Libraries\r
688\r
689 def _GetProtocolComments(self):\r
690 self._GetProtocols()\r
691 return self._ProtocolComments\r
692 ## Retrieve protocols consumed/produced by this module\r
693 def _GetProtocols(self):\r
4231a819 694 if self._Protocols is None:\r
a0767bae
CJ
695 self._Protocols = OrderedDict()\r
696 self._ProtocolComments = OrderedDict()\r
ae7b6df8
LG
697 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
698 for Record in RecordList:\r
699 CName = Record[0]\r
700 Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)\r
4231a819 701 if Value is None:\r
8252e6bf 702 PackageList = "\n\t".join(str(P) for P in self.Packages)\r
ae7b6df8
LG
703 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
704 "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
705 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
706 self._Protocols[CName] = Value\r
707 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
708 Comments = []\r
709 for CmtRec in CommentRecords:\r
710 Comments.append(CmtRec[0])\r
711 self._ProtocolComments[CName] = Comments\r
712 return self._Protocols\r
713\r
714 def _GetPpiComments(self):\r
715 self._GetPpis()\r
716 return self._PpiComments\r
717 ## Retrieve PPIs consumed/produced by this module\r
718 def _GetPpis(self):\r
4231a819 719 if self._Ppis is None:\r
a0767bae
CJ
720 self._Ppis = OrderedDict()\r
721 self._PpiComments = OrderedDict()\r
ae7b6df8
LG
722 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
723 for Record in RecordList:\r
724 CName = Record[0]\r
725 Value = PpiValue(CName, self.Packages, self.MetaFile.Path)\r
4231a819 726 if Value is None:\r
8252e6bf 727 PackageList = "\n\t".join(str(P) for P in self.Packages)\r
ae7b6df8
LG
728 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
729 "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
730 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
731 self._Ppis[CName] = Value\r
732 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
733 Comments = []\r
734 for CmtRec in CommentRecords:\r
735 Comments.append(CmtRec[0])\r
736 self._PpiComments[CName] = Comments\r
737 return self._Ppis\r
738\r
739 def _GetGuidComments(self):\r
740 self._GetGuids()\r
741 return self._GuidComments\r
742 ## Retrieve GUIDs consumed/produced by this module\r
743 def _GetGuids(self):\r
4231a819 744 if self._Guids is None:\r
a0767bae
CJ
745 self._Guids = OrderedDict()\r
746 self._GuidComments = OrderedDict()\r
ae7b6df8
LG
747 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
748 for Record in RecordList:\r
749 CName = Record[0]\r
750 Value = GuidValue(CName, self.Packages, self.MetaFile.Path)\r
4231a819 751 if Value is None:\r
8252e6bf 752 PackageList = "\n\t".join(str(P) for P in self.Packages)\r
ae7b6df8
LG
753 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
754 "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
755 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
756 self._Guids[CName] = Value\r
757 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
758 Comments = []\r
759 for CmtRec in CommentRecords:\r
760 Comments.append(CmtRec[0])\r
761 self._GuidComments[CName] = Comments\r
762 return self._Guids\r
763\r
764 ## Retrieve include paths necessary for this module (for Edk.x style of modules)\r
765 def _GetIncludes(self):\r
4231a819 766 if self._Includes is None:\r
ae7b6df8
LG
767 self._Includes = []\r
768 if self._SourceOverridePath:\r
769 self._Includes.append(self._SourceOverridePath)\r
770\r
771 Macros = self._Macros\r
9eb87141 772 Macros['PROCESSOR'] = GlobalData.gEdkGlobal.get('PROCESSOR', self._Arch)\r
ae7b6df8
LG
773 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
774 for Record in RecordList:\r
775 if Record[0].find('EDK_SOURCE') > -1:\r
776 Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
777 File = NormPath(Record[0], self._Macros)\r
778 if File[0] == '.':\r
779 File = os.path.join(self._ModuleDir, File)\r
780 else:\r
781 File = os.path.join(GlobalData.gWorkspace, File)\r
782 File = RealPath(os.path.normpath(File))\r
783 if File:\r
784 self._Includes.append(File)\r
785\r
786 # TRICK: let compiler to choose correct header file\r
787 Macros['EDK_SOURCE'] = GlobalData.gEdkSource\r
788 File = NormPath(Record[0], self._Macros)\r
789 if File[0] == '.':\r
790 File = os.path.join(self._ModuleDir, File)\r
791 else:\r
792 File = os.path.join(GlobalData.gWorkspace, File)\r
793 File = RealPath(os.path.normpath(File))\r
794 if File:\r
795 self._Includes.append(File)\r
796 else:\r
797 File = NormPath(Record[0], Macros)\r
798 if File[0] == '.':\r
799 File = os.path.join(self._ModuleDir, File)\r
800 else:\r
801 File = mws.join(GlobalData.gWorkspace, File)\r
802 File = RealPath(os.path.normpath(File))\r
803 if File:\r
804 self._Includes.append(File)\r
805 if not File and Record[0].find('EFI_SOURCE') > -1:\r
806 # tricky to regard WorkSpace as EFI_SOURCE\r
807 Macros['EFI_SOURCE'] = GlobalData.gWorkspace\r
808 File = NormPath(Record[0], Macros)\r
809 if File[0] == '.':\r
810 File = os.path.join(self._ModuleDir, File)\r
811 else:\r
812 File = os.path.join(GlobalData.gWorkspace, File)\r
813 File = RealPath(os.path.normpath(File))\r
814 if File:\r
815 self._Includes.append(File)\r
816 return self._Includes\r
817\r
818 ## Retrieve packages this module depends on\r
819 def _GetPackages(self):\r
4231a819 820 if self._Packages is None:\r
ae7b6df8
LG
821 self._Packages = []\r
822 RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
823 Macros = self._Macros\r
824 Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
825 for Record in RecordList:\r
826 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
827 LineNo = Record[-1]\r
828 # check the file validation\r
829 ErrorCode, ErrorInfo = File.Validate('.dec')\r
830 if ErrorCode != 0:\r
831 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
832 # parse this package now. we need it to get protocol/ppi/guid value\r
833 Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
834 self._Packages.append(Package)\r
835 return self._Packages\r
836\r
837 ## Retrieve PCD comments\r
838 def _GetPcdComments(self):\r
839 self._GetPcds()\r
840 return self._PcdComments\r
841 ## Retrieve PCDs used in this module\r
842 def _GetPcds(self):\r
4231a819 843 if self._Pcds is None:\r
a0767bae
CJ
844 self._Pcds = OrderedDict()\r
845 self._PcdComments = OrderedDict()\r
ae7b6df8
LG
846 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
847 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
848 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
849 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
850 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
851 return self._Pcds\r
852\r
853 ## Retrieve build options specific to this module\r
854 def _GetBuildOptions(self):\r
4231a819 855 if self._BuildOptions is None:\r
a0767bae 856 self._BuildOptions = OrderedDict()\r
ae7b6df8
LG
857 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]\r
858 for Record in RecordList:\r
859 ToolChainFamily = Record[0]\r
860 ToolChain = Record[1]\r
861 Option = Record[2]\r
862 if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):\r
863 self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
864 else:\r
865 # concatenate the option string if they're for the same tool\r
866 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
867 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
868 return self._BuildOptions\r
869\r
870 ## Retrieve dependency expression\r
871 def _GetDepex(self):\r
4231a819 872 if self._Depex is None:\r
ae7b6df8
LG
873 self._Depex = tdict(False, 2)\r
874 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
875\r
876 # If the module has only Binaries and no Sources, then ignore [Depex]\r
4231a819
CJ
877 if self.Sources is None or self.Sources == []:\r
878 if self.Binaries is not None and self.Binaries != []:\r
ae7b6df8
LG
879 return self._Depex\r
880\r
881 # PEIM and DXE drivers must have a valid [Depex] section\r
882 if len(self.LibraryClass) == 0 and len(RecordList) == 0:\r
8bb63e37
CJ
883 if self.ModuleType == SUP_MODULE_DXE_DRIVER or self.ModuleType == SUP_MODULE_PEIM or self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER or \\r
884 self.ModuleType == SUP_MODULE_DXE_SAL_DRIVER or self.ModuleType == SUP_MODULE_DXE_RUNTIME_DRIVER:\r
ae7b6df8
LG
885 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
886 % self.ModuleType, File=self.MetaFile)\r
887\r
8bb63e37 888 if len(RecordList) != 0 and self.ModuleType == SUP_MODULE_USER_DEFINED:\r
ae7b6df8 889 for Record in RecordList:\r
8bb63e37 890 if Record[4] not in [SUP_MODULE_PEIM, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SMM_DRIVER]:\r
ae7b6df8
LG
891 EdkLogger.error('build', FORMAT_INVALID,\r
892 "'%s' module must specify the type of [Depex] section" % self.ModuleType,\r
893 File=self.MetaFile)\r
894\r
a0767bae 895 Depex = OrderedDict()\r
ae7b6df8
LG
896 for Record in RecordList:\r
897 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
898 Arch = Record[3]\r
899 ModuleType = Record[4]\r
900 TokenList = DepexStr.split()\r
901 if (Arch, ModuleType) not in Depex:\r
902 Depex[Arch, ModuleType] = []\r
903 DepexList = Depex[Arch, ModuleType]\r
904 for Token in TokenList:\r
eece4292 905 if Token in DEPEX_SUPPORTED_OPCODE_SET:\r
ae7b6df8
LG
906 DepexList.append(Token)\r
907 elif Token.endswith(".inf"): # module file name\r
908 ModuleFile = os.path.normpath(Token)\r
909 Module = self.BuildDatabase[ModuleFile]\r
4231a819 910 if Module is None:\r
ae7b6df8
LG
911 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",\r
912 ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
913 DepexList.append(Module.Guid)\r
914 else:\r
915 # get the GUID value now\r
916 Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)\r
4231a819 917 if Value is None:\r
ae7b6df8 918 Value = PpiValue(Token, self.Packages, self.MetaFile.Path)\r
4231a819 919 if Value is None:\r
ae7b6df8 920 Value = GuidValue(Token, self.Packages, self.MetaFile.Path)\r
4231a819 921 if Value is None:\r
8252e6bf 922 PackageList = "\n\t".join(str(P) for P in self.Packages)\r
ae7b6df8
LG
923 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
924 "Value of [%s] is not found in" % Token,\r
925 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
926 DepexList.append(Value)\r
927 for Arch, ModuleType in Depex:\r
928 self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]\r
929 return self._Depex\r
930\r
931 ## Retrieve depedency expression\r
932 def _GetDepexExpression(self):\r
4231a819 933 if self._DepexExpression is None:\r
ae7b6df8
LG
934 self._DepexExpression = tdict(False, 2)\r
935 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
a0767bae 936 DepexExpression = OrderedDict()\r
ae7b6df8
LG
937 for Record in RecordList:\r
938 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
939 Arch = Record[3]\r
940 ModuleType = Record[4]\r
941 TokenList = DepexStr.split()\r
942 if (Arch, ModuleType) not in DepexExpression:\r
943 DepexExpression[Arch, ModuleType] = ''\r
944 for Token in TokenList:\r
945 DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '\r
946 for Arch, ModuleType in DepexExpression:\r
947 self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]\r
948 return self._DepexExpression\r
949\r
950 def GetGuidsUsedByPcd(self):\r
951 return self._GuidsUsedByPcd\r
952 ## Retrieve PCD for given type\r
953 def _GetPcd(self, Type):\r
a0767bae 954 Pcds = OrderedDict()\r
ae7b6df8
LG
955 PcdDict = tdict(True, 4)\r
956 PcdList = []\r
957 RecordList = self._RawData[Type, self._Arch, self._Platform]\r
958 for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:\r
959 PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)\r
960 PcdList.append((PcdCName, TokenSpaceGuid))\r
961 # get the guid value\r
962 if TokenSpaceGuid not in self.Guids:\r
963 Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)\r
4231a819 964 if Value is None:\r
8252e6bf 965 PackageList = "\n\t".join(str(P) for P in self.Packages)\r
ae7b6df8
LG
966 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
967 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,\r
968 ExtraData=PackageList, File=self.MetaFile, Line=LineNo)\r
969 self.Guids[TokenSpaceGuid] = Value\r
970 self._GuidsUsedByPcd[TokenSpaceGuid] = Value\r
971 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]\r
972 Comments = []\r
973 for CmtRec in CommentRecords:\r
974 Comments.append(CmtRec[0])\r
975 self._PcdComments[TokenSpaceGuid, PcdCName] = Comments\r
976\r
977 # resolve PCD type, value, datum info, etc. by getting its definition from package\r
e7df35b2 978 _GuidDict = self.Guids.copy()\r
ae7b6df8
LG
979 for PcdCName, TokenSpaceGuid in PcdList:\r
980 PcdRealName = PcdCName\r
981 Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
4231a819 982 if Setting is None:\r
ae7b6df8
LG
983 continue\r
984 ValueList = AnalyzePcdData(Setting)\r
985 DefaultValue = ValueList[0]\r
986 Pcd = PcdClassObject(\r
987 PcdCName,\r
988 TokenSpaceGuid,\r
989 '',\r
990 '',\r
991 DefaultValue,\r
992 '',\r
993 '',\r
994 {},\r
995 False,\r
996 self.Guids[TokenSpaceGuid]\r
997 )\r
998 if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:\r
999 # Patch PCD: TokenSpace.PcdCName|Value|Offset\r
1000 Pcd.Offset = ValueList[1]\r
1001\r
1002 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
1003 for Package in self.Packages:\r
1004 for key in Package.Pcds:\r
1005 if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):\r
1006 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
1007 Pcd_Type = item[0].split('_')[-1]\r
1008 if Pcd_Type == Package.Pcds[key].Type:\r
1009 Value = Package.Pcds[key]\r
1010 Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type\r
1011 if len(key) == 2:\r
1012 newkey = (Value.TokenCName, key[1])\r
1013 elif len(key) == 3:\r
1014 newkey = (Value.TokenCName, key[1], key[2])\r
1015 del Package.Pcds[key]\r
1016 Package.Pcds[newkey] = Value\r
1017 break\r
1018 else:\r
1019 pass\r
1020 else:\r
1021 pass\r
1022\r
1023 # get necessary info from package declaring this PCD\r
1024 for Package in self.Packages:\r
1025 #\r
1026 # 'dynamic' in INF means its type is determined by platform;\r
1027 # if platform doesn't give its type, use 'lowest' one in the\r
1028 # following order, if any\r
1029 #\r
be409b67 1030 # TAB_PCDS_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE, TAB_PCDS_FEATURE_FLAG, TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_EX\r
ae7b6df8 1031 #\r
e7df35b2 1032 _GuidDict.update(Package.Guids)\r
ae7b6df8
LG
1033 PcdType = self._PCD_TYPE_STRING_[Type]\r
1034 if Type == MODEL_PCD_DYNAMIC:\r
1035 Pcd.Pending = True\r
be409b67 1036 for T in PCD_TYPE_LIST:\r
ae7b6df8
LG
1037 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
1038 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
1039 if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:\r
1040 PcdType = T\r
1041 PcdCName = item[0]\r
1042 break\r
1043 else:\r
1044 pass\r
1045 break\r
1046 else:\r
1047 if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:\r
1048 PcdType = T\r
1049 break\r
1050\r
1051 else:\r
1052 Pcd.Pending = False\r
1053 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
1054 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
1055 Pcd_Type = item[0].split('_')[-1]\r
1056 if Pcd_Type == PcdType:\r
1057 PcdCName = item[0]\r
1058 break\r
1059 else:\r
1060 pass\r
1061 else:\r
1062 pass\r
1063\r
1064 if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
1065 PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]\r
1066 Pcd.Type = PcdType\r
1067 Pcd.TokenValue = PcdInPackage.TokenValue\r
1068\r
1069 #\r
1070 # Check whether the token value exist or not.\r
1071 #\r
4231a819 1072 if Pcd.TokenValue is None or Pcd.TokenValue == "":\r
ae7b6df8
LG
1073 EdkLogger.error(\r
1074 'build',\r
1075 FORMAT_INVALID,\r
1076 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdRealName, str(Package)),\r
1077 File=self.MetaFile, Line=LineNo,\r
1078 ExtraData=None\r
1079 )\r
1080 #\r
1081 # Check hexadecimal token value length and format.\r
1082 #\r
1083 ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)\r
1084 if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):\r
4231a819 1085 if ReIsValidPcdTokenValue.match(Pcd.TokenValue) is None:\r
ae7b6df8
LG
1086 EdkLogger.error(\r
1087 'build',\r
1088 FORMAT_INVALID,\r
1089 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),\r
1090 File=self.MetaFile, Line=LineNo,\r
1091 ExtraData=None\r
1092 )\r
1093\r
1094 #\r
1095 # Check decimal token value length and format.\r
1096 #\r
1097 else:\r
1098 try:\r
1099 TokenValueInt = int (Pcd.TokenValue, 10)\r
1100 if (TokenValueInt < 0 or TokenValueInt > 4294967295):\r
1101 EdkLogger.error(\r
1102 'build',\r
1103 FORMAT_INVALID,\r
1104 "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
1105 File=self.MetaFile, Line=LineNo,\r
1106 ExtraData=None\r
1107 )\r
1108 except:\r
1109 EdkLogger.error(\r
1110 'build',\r
1111 FORMAT_INVALID,\r
1112 "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
1113 File=self.MetaFile, Line=LineNo,\r
1114 ExtraData=None\r
1115 )\r
1116\r
1117 Pcd.DatumType = PcdInPackage.DatumType\r
1118 Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
1119 Pcd.InfDefaultValue = Pcd.DefaultValue\r
c93356ad 1120 if not Pcd.DefaultValue:\r
ae7b6df8 1121 Pcd.DefaultValue = PcdInPackage.DefaultValue\r
726c501c
YZ
1122 else:\r
1123 try:\r
e7df35b2 1124 Pcd.DefaultValue = ValueExpressionEx(Pcd.DefaultValue, Pcd.DatumType, _GuidDict)(True)\r
5b0671c1 1125 except BadExpression as Value:\r
726c501c
YZ
1126 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %(TokenSpaceGuid, PcdRealName, Pcd.DefaultValue, Value),\r
1127 File=self.MetaFile, Line=LineNo)\r
ae7b6df8
LG
1128 break\r
1129 else:\r
1130 EdkLogger.error(\r
1131 'build',\r
1132 FORMAT_INVALID,\r
1133 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, self.MetaFile),\r
1134 File=self.MetaFile, Line=LineNo,\r
8252e6bf 1135 ExtraData="\t%s" % '\n\t'.join(str(P) for P in self.Packages)\r
ae7b6df8
LG
1136 )\r
1137 Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
1138\r
1139 return Pcds\r
1140\r
1141 ## check whether current module is binary module\r
1142 def _IsBinaryModule(self):\r
1143 if self.Binaries and not self.Sources:\r
1144 return True\r
1145 elif GlobalData.gIgnoreSource:\r
1146 return True\r
1147 else:\r
1148 return False\r
1149\r
1150 _Macros = property(_GetMacros)\r
1151 Arch = property(_GetArch, _SetArch)\r
1152 Platform = property(_GetPlatform, _SetPlatform)\r
1153\r
1154 HeaderComments = property(_GetHeaderComments)\r
1155 TailComments = property(_GetTailComments)\r
1156 AutoGenVersion = property(_GetInfVersion)\r
1157 BaseName = property(_GetBaseName)\r
1158 ModuleType = property(_GetModuleType)\r
1159 ComponentType = property(_GetComponentType)\r
1160 BuildType = property(_GetBuildType)\r
1161 Guid = property(_GetFileGuid)\r
1162 Version = property(_GetVersion)\r
1163 PcdIsDriver = property(_GetPcdIsDriver)\r
1164 Shadow = property(_GetShadow)\r
1165 CustomMakefile = property(_GetMakefile)\r
1166 Specification = property(_GetSpec)\r
1167 LibraryClass = property(_GetLibraryClass)\r
1168 ModuleEntryPointList = property(_GetEntryPoint)\r
1169 ModuleUnloadImageList = property(_GetUnloadImage)\r
1170 ConstructorList = property(_GetConstructor)\r
1171 DestructorList = property(_GetDestructor)\r
1172 Defines = property(_GetDefines)\r
1173 DxsFile = property(_GetDxsFile)\r
1174\r
1175 Binaries = property(_GetBinaryFiles)\r
1176 Sources = property(_GetSourceFiles)\r
1177 LibraryClasses = property(_GetLibraryClassUses)\r
1178 Libraries = property(_GetLibraryNames)\r
1179 Protocols = property(_GetProtocols)\r
1180 ProtocolComments = property(_GetProtocolComments)\r
1181 Ppis = property(_GetPpis)\r
1182 PpiComments = property(_GetPpiComments)\r
1183 Guids = property(_GetGuids)\r
1184 GuidComments = property(_GetGuidComments)\r
1185 Includes = property(_GetIncludes)\r
1186 Packages = property(_GetPackages)\r
1187 Pcds = property(_GetPcds)\r
1188 PcdComments = property(_GetPcdComments)\r
1189 BuildOptions = property(_GetBuildOptions)\r
1190 Depex = property(_GetDepex)\r
1191 DepexExpression = property(_GetDepexExpression)\r
1192 IsBinaryModule = property(_IsBinaryModule)\r
1193 IsSupportedArch = property(_IsSupportedArch)\r