]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
ShellPkg: Fix EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL_GUID to match UEFI Shell 2.1 spec
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / WorkspaceDatabase.py
CommitLineData
52302d4d
LG
1## @file\r
2# This file is used to create a database used by build tool\r
3#\r
2bc3256c 4# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
52302d4d
LG
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
13\r
14##\r
15# Import Modules\r
16#\r
17import sqlite3\r
18import os\r
19import os.path\r
20import pickle\r
e56468c0 21import uuid\r
52302d4d
LG
22\r
23import Common.EdkLogger as EdkLogger\r
24import Common.GlobalData as GlobalData\r
25\r
26from Common.String import *\r
27from Common.DataType import *\r
28from Common.Misc import *\r
29from types import *\r
30\r
31from CommonDataClass.CommonClass import SkuInfoClass\r
32\r
33from MetaDataTable import *\r
34from MetaFileTable import *\r
35from MetaFileParser import *\r
36from BuildClassObject import *\r
4afd3d04
LG
37from WorkspaceCommon import GetDeclaredPcd\r
38from Common.Misc import AnalyzeDscPcd\r
2bc3256c 39import re\r
e4ac870f 40from Common.Parsing import IsValidWord\r
52302d4d
LG
41\r
42## Platform build information from DSC file\r
43#\r
44# This class is used to retrieve information stored in database and convert them\r
45# into PlatformBuildClassObject form for easier use for AutoGen.\r
46#\r
47class DscBuildData(PlatformBuildClassObject):\r
48 # dict used to convert PCD type in database to string used by build tool\r
49 _PCD_TYPE_STRING_ = {\r
50 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
51 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
52 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
53 MODEL_PCD_DYNAMIC : "Dynamic",\r
54 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
55 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
56 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
57 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
58 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
59 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
60 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
61 }\r
62\r
63 # dict used to convert part of [Defines] to members of DscBuildData directly\r
64 _PROPERTY_ = {\r
65 #\r
66 # Required Fields\r
67 #\r
68 TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName",\r
69 TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid",\r
70 TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version",\r
71 TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification",\r
72 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",\r
73 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",\r
74 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",\r
e8a47801 75 TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",\r
52302d4d
LG
76 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",\r
77 TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",\r
78 TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",\r
79 TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",\r
80 TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",\r
6780eef1
LG
81 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",\r
82 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",\r
52302d4d
LG
83 }\r
84\r
85 # used to compose dummy library class name for those forced library instances\r
86 _NullLibraryNumber = 0\r
87\r
88 ## Constructor of DscBuildData\r
89 #\r
90 # Initialize object of DscBuildData\r
91 #\r
92 # @param FilePath The path of platform description file\r
93 # @param RawData The raw data of DSC file\r
94 # @param BuildDataBase Database used to retrieve module/package information\r
95 # @param Arch The target architecture\r
96 # @param Platform (not used for DscBuildData)\r
97 # @param Macros Macros used for replacement in DSC file\r
98 #\r
0d2711a6 99 def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r
52302d4d
LG
100 self.MetaFile = FilePath\r
101 self._RawData = RawData\r
102 self._Bdb = BuildDataBase\r
103 self._Arch = Arch\r
0d2711a6
LG
104 self._Target = Target\r
105 self._Toolchain = Toolchain\r
52302d4d 106 self._Clear()\r
52302d4d
LG
107\r
108 ## XXX[key] = value\r
109 def __setitem__(self, key, value):\r
110 self.__dict__[self._PROPERTY_[key]] = value\r
111\r
112 ## value = XXX[key]\r
113 def __getitem__(self, key):\r
114 return self.__dict__[self._PROPERTY_[key]]\r
115\r
116 ## "in" test support\r
117 def __contains__(self, key):\r
118 return key in self._PROPERTY_\r
119\r
120 ## Set all internal used members of DscBuildData to None\r
121 def _Clear(self):\r
122 self._Header = None\r
123 self._PlatformName = None\r
124 self._Guid = None\r
125 self._Version = None\r
126 self._DscSpecification = None\r
127 self._OutputDirectory = None\r
128 self._SupArchList = None\r
129 self._BuildTargets = None\r
130 self._SkuName = None\r
e8a47801
LG
131 self._SkuIdentifier = None\r
132 self._PcdInfoFlag = None\r
52302d4d
LG
133 self._FlashDefinition = None\r
134 self._BuildNumber = None\r
135 self._MakefileName = None\r
136 self._BsBaseAddress = None\r
137 self._RtBaseAddress = None\r
138 self._SkuIds = None\r
139 self._Modules = None\r
140 self._LibraryInstances = None\r
141 self._LibraryClasses = None\r
142 self._Pcds = None\r
4afd3d04 143 self._DecPcds = None\r
52302d4d
LG
144 self._BuildOptions = None\r
145 self._LoadFixAddress = None\r
6780eef1
LG
146 self._RFCLanguages = None\r
147 self._ISOLanguages = None\r
e56468c0 148 self._VpdToolGuid = None\r
0d2711a6
LG
149 self.__Macros = None\r
150\r
151 ## Get current effective macros\r
152 def _GetMacros(self):\r
153 if self.__Macros == None:\r
154 self.__Macros = {}\r
155 self.__Macros.update(GlobalData.gPlatformDefines)\r
156 self.__Macros.update(GlobalData.gGlobalDefines)\r
157 self.__Macros.update(GlobalData.gCommandLineDefines)\r
158 return self.__Macros\r
52302d4d
LG
159\r
160 ## Get architecture\r
161 def _GetArch(self):\r
162 return self._Arch\r
163\r
164 ## Set architecture\r
165 #\r
166 # Changing the default ARCH to another may affect all other information\r
167 # because all information in a platform may be ARCH-related. That's\r
168 # why we need to clear all internal used members, in order to cause all\r
169 # information to be re-retrieved.\r
170 #\r
171 # @param Value The value of ARCH\r
172 #\r
173 def _SetArch(self, Value):\r
174 if self._Arch == Value:\r
175 return\r
176 self._Arch = Value\r
177 self._Clear()\r
178\r
179 ## Retrieve all information in [Defines] section\r
180 #\r
181 # (Retriving all [Defines] information in one-shot is just to save time.)\r
182 #\r
183 def _GetHeaderInfo(self):\r
184 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
185 for Record in RecordList:\r
0d2711a6 186 Name = Record[1]\r
52302d4d 187 # items defined _PROPERTY_ don't need additional processing\r
e8a47801 188 \r
52302d4d 189 # some special items in [Defines] section need special treatment\r
e8a47801 190 if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:\r
0d2711a6 191 self._OutputDirectory = NormPath(Record[2], self._Macros)\r
52302d4d
LG
192 if ' ' in self._OutputDirectory:\r
193 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",\r
194 File=self.MetaFile, Line=Record[-1],\r
195 ExtraData=self._OutputDirectory)\r
196 elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:\r
0d2711a6 197 self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
52302d4d
LG
198 ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')\r
199 if ErrorCode != 0:\r
200 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r
201 ExtraData=ErrorInfo)\r
202 elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
0d2711a6 203 self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
52302d4d 204 elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
0d2711a6 205 self._BuildTargets = GetSplitValueList(Record[2])\r
52302d4d
LG
206 elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:\r
207 if self._SkuName == None:\r
0d2711a6 208 self._SkuName = Record[2]\r
e8a47801
LG
209 self._SkuIdentifier = Record[2]\r
210 elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:\r
211 self._PcdInfoFlag = Record[2]\r
52302d4d 212 elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:\r
0d2711a6
LG
213 try:\r
214 self._LoadFixAddress = int (Record[2], 0)\r
215 except:\r
216 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))\r
6780eef1 217 elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:\r
0d2711a6 218 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:\r
6780eef1
LG
219 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',\r
220 File=self.MetaFile, Line=Record[-1])\r
0d2711a6 221 LanguageCodes = Record[2][1:-1]\r
6780eef1
LG
222 if not LanguageCodes:\r
223 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',\r
224 File=self.MetaFile, Line=Record[-1]) \r
225 LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)\r
226 # check whether there is empty entries in the list\r
227 if None in LanguageList:\r
228 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',\r
229 File=self.MetaFile, Line=Record[-1]) \r
230 self._RFCLanguages = LanguageList\r
231 elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:\r
0d2711a6 232 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:\r
6780eef1
LG
233 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',\r
234 File=self.MetaFile, Line=Record[-1])\r
0d2711a6 235 LanguageCodes = Record[2][1:-1]\r
6780eef1
LG
236 if not LanguageCodes:\r
237 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',\r
238 File=self.MetaFile, Line=Record[-1]) \r
239 if len(LanguageCodes)%3:\r
240 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',\r
241 File=self.MetaFile, Line=Record[-1])\r
242 LanguageList = []\r
243 for i in range(0, len(LanguageCodes), 3):\r
244 LanguageList.append(LanguageCodes[i:i+3])\r
245 self._ISOLanguages = LanguageList \r
e56468c0 246 elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:\r
247 #\r
248 # try to convert GUID to a real UUID value to see whether the GUID is format \r
249 # for VPD_TOOL_GUID is correct.\r
250 #\r
251 try:\r
0d2711a6 252 uuid.UUID(Record[2])\r
e56468c0 253 except:\r
254 EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)\r
0d2711a6 255 self._VpdToolGuid = Record[2] \r
e8a47801
LG
256 elif Name in self:\r
257 self[Name] = Record[2] \r
52302d4d
LG
258 # set _Header to non-None in order to avoid database re-querying\r
259 self._Header = 'DUMMY'\r
260\r
261 ## Retrieve platform name\r
262 def _GetPlatformName(self):\r
263 if self._PlatformName == None:\r
264 if self._Header == None:\r
265 self._GetHeaderInfo()\r
266 if self._PlatformName == None:\r
267 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)\r
268 return self._PlatformName\r
269\r
270 ## Retrieve file guid\r
271 def _GetFileGuid(self):\r
272 if self._Guid == None:\r
273 if self._Header == None:\r
274 self._GetHeaderInfo()\r
275 if self._Guid == None:\r
64b2609f 276 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)\r
52302d4d
LG
277 return self._Guid\r
278\r
279 ## Retrieve platform version\r
280 def _GetVersion(self):\r
281 if self._Version == None:\r
282 if self._Header == None:\r
283 self._GetHeaderInfo()\r
284 if self._Version == None:\r
64b2609f 285 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)\r
52302d4d
LG
286 return self._Version\r
287\r
288 ## Retrieve platform description file version\r
289 def _GetDscSpec(self):\r
290 if self._DscSpecification == None:\r
291 if self._Header == None:\r
292 self._GetHeaderInfo()\r
293 if self._DscSpecification == None:\r
64b2609f 294 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile) \r
52302d4d
LG
295 return self._DscSpecification\r
296\r
297 ## Retrieve OUTPUT_DIRECTORY\r
298 def _GetOutpuDir(self):\r
299 if self._OutputDirectory == None:\r
300 if self._Header == None:\r
301 self._GetHeaderInfo()\r
302 if self._OutputDirectory == None:\r
303 self._OutputDirectory = os.path.join("Build", self._PlatformName)\r
304 return self._OutputDirectory\r
305\r
306 ## Retrieve SUPPORTED_ARCHITECTURES\r
307 def _GetSupArch(self):\r
308 if self._SupArchList == None:\r
309 if self._Header == None:\r
310 self._GetHeaderInfo()\r
311 if self._SupArchList == None:\r
64b2609f 312 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)\r
52302d4d
LG
313 return self._SupArchList\r
314\r
315 ## Retrieve BUILD_TARGETS\r
316 def _GetBuildTarget(self):\r
317 if self._BuildTargets == None:\r
318 if self._Header == None:\r
319 self._GetHeaderInfo()\r
320 if self._BuildTargets == None:\r
64b2609f 321 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)\r
52302d4d 322 return self._BuildTargets\r
e8a47801
LG
323 \r
324 def _GetPcdInfoFlag(self):\r
325 if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE':\r
326 return False\r
327 elif self._PcdInfoFlag.upper() == 'TRUE':\r
328 return True\r
329 else:\r
330 return False\r
331 \r
332 def _GetSkuIdentifier(self):\r
2bc3256c
LG
333 if self._SkuName:\r
334 return self._SkuName\r
e8a47801
LG
335 if self._SkuIdentifier == None:\r
336 if self._Header == None:\r
337 self._GetHeaderInfo()\r
338 return self._SkuIdentifier\r
52302d4d
LG
339 ## Retrieve SKUID_IDENTIFIER\r
340 def _GetSkuName(self):\r
341 if self._SkuName == None:\r
342 if self._Header == None:\r
343 self._GetHeaderInfo()\r
2bc3256c 344 if (self._SkuName == None or self._SkuName not in self.SkuIds):\r
52302d4d
LG
345 self._SkuName = 'DEFAULT'\r
346 return self._SkuName\r
347\r
348 ## Override SKUID_IDENTIFIER\r
349 def _SetSkuName(self, Value):\r
2bc3256c
LG
350 self._SkuName = Value\r
351 self._Pcds = None\r
52302d4d
LG
352\r
353 def _GetFdfFile(self):\r
354 if self._FlashDefinition == None:\r
355 if self._Header == None:\r
356 self._GetHeaderInfo()\r
357 if self._FlashDefinition == None:\r
358 self._FlashDefinition = ''\r
359 return self._FlashDefinition\r
360\r
361 ## Retrieve FLASH_DEFINITION\r
362 def _GetBuildNumber(self):\r
363 if self._BuildNumber == None:\r
364 if self._Header == None:\r
365 self._GetHeaderInfo()\r
366 if self._BuildNumber == None:\r
367 self._BuildNumber = ''\r
368 return self._BuildNumber\r
369\r
370 ## Retrieve MAKEFILE_NAME\r
371 def _GetMakefileName(self):\r
372 if self._MakefileName == None:\r
373 if self._Header == None:\r
374 self._GetHeaderInfo()\r
375 if self._MakefileName == None:\r
376 self._MakefileName = ''\r
377 return self._MakefileName\r
378\r
379 ## Retrieve BsBaseAddress\r
380 def _GetBsBaseAddress(self):\r
381 if self._BsBaseAddress == None:\r
382 if self._Header == None:\r
383 self._GetHeaderInfo()\r
384 if self._BsBaseAddress == None:\r
385 self._BsBaseAddress = ''\r
386 return self._BsBaseAddress\r
387\r
388 ## Retrieve RtBaseAddress\r
389 def _GetRtBaseAddress(self):\r
390 if self._RtBaseAddress == None:\r
391 if self._Header == None:\r
392 self._GetHeaderInfo()\r
393 if self._RtBaseAddress == None:\r
394 self._RtBaseAddress = ''\r
395 return self._RtBaseAddress\r
396\r
397 ## Retrieve the top address for the load fix address\r
398 def _GetLoadFixAddress(self):\r
399 if self._LoadFixAddress == None:\r
400 if self._Header == None:\r
401 self._GetHeaderInfo()\r
0d2711a6 402\r
52302d4d 403 if self._LoadFixAddress == None:\r
0d2711a6
LG
404 self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')\r
405\r
406 try:\r
407 self._LoadFixAddress = int (self._LoadFixAddress, 0)\r
408 except:\r
409 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))\r
9508d0fa
LG
410 \r
411 #\r
412 # If command line defined, should override the value in DSC file.\r
413 #\r
414 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():\r
415 try:\r
416 self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)\r
417 except:\r
418 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))\r
419 \r
420 if self._LoadFixAddress < 0:\r
421 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))\r
422 if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:\r
423 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))\r
424 \r
52302d4d
LG
425 return self._LoadFixAddress\r
426\r
6780eef1
LG
427 ## Retrieve RFCLanguage filter\r
428 def _GetRFCLanguages(self):\r
429 if self._RFCLanguages == None:\r
430 if self._Header == None:\r
431 self._GetHeaderInfo()\r
432 if self._RFCLanguages == None:\r
433 self._RFCLanguages = []\r
434 return self._RFCLanguages\r
435\r
436 ## Retrieve ISOLanguage filter\r
437 def _GetISOLanguages(self):\r
438 if self._ISOLanguages == None:\r
439 if self._Header == None:\r
440 self._GetHeaderInfo()\r
441 if self._ISOLanguages == None:\r
442 self._ISOLanguages = []\r
443 return self._ISOLanguages\r
e56468c0 444 ## Retrieve the GUID string for VPD tool\r
445 def _GetVpdToolGuid(self):\r
446 if self._VpdToolGuid == None:\r
447 if self._Header == None:\r
448 self._GetHeaderInfo()\r
449 if self._VpdToolGuid == None:\r
450 self._VpdToolGuid = ''\r
451 return self._VpdToolGuid\r
08dd311f 452 \r
52302d4d
LG
453 ## Retrieve [SkuIds] section information\r
454 def _GetSkuIds(self):\r
455 if self._SkuIds == None:\r
0d2711a6
LG
456 self._SkuIds = sdict()\r
457 RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]\r
52302d4d
LG
458 for Record in RecordList:\r
459 if Record[0] in [None, '']:\r
460 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',\r
461 File=self.MetaFile, Line=Record[-1])\r
462 if Record[1] in [None, '']:\r
463 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',\r
464 File=self.MetaFile, Line=Record[-1])\r
2bc3256c 465 self._SkuIds[Record[1]] = Record[0]\r
52302d4d 466 if 'DEFAULT' not in self._SkuIds:\r
d0acc87a 467 self._SkuIds['DEFAULT'] = '0'\r
e8a47801
LG
468 if 'COMMON' not in self._SkuIds:\r
469 self._SkuIds['COMMON'] = '0'\r
52302d4d
LG
470 return self._SkuIds\r
471\r
472 ## Retrieve [Components] section information\r
473 def _GetModules(self):\r
474 if self._Modules != None:\r
475 return self._Modules\r
476\r
477 self._Modules = sdict()\r
478 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]\r
0d2711a6
LG
479 Macros = self._Macros\r
480 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
52302d4d
LG
481 for Record in RecordList:\r
482 ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
483 ModuleId = Record[5]\r
484 LineNo = Record[6]\r
485\r
486 # check the file validation\r
487 ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')\r
488 if ErrorCode != 0:\r
489 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
490 ExtraData=ErrorInfo)\r
491 # Check duplication\r
64b2609f
LG
492 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected\r
493 if self._Arch != 'COMMON' and ModuleFile in self._Modules:\r
52302d4d
LG
494 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)\r
495\r
496 Module = ModuleBuildClassObject()\r
497 Module.MetaFile = ModuleFile\r
498\r
499 # get module override path\r
500 RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]\r
501 if RecordList != []:\r
502 Module.SourceOverridePath = os.path.join(GlobalData.gWorkspace, NormPath(RecordList[0][0], Macros))\r
503\r
504 # Check if the source override path exists\r
505 if not os.path.isdir(Module.SourceOverridePath):\r
506 EdkLogger.error('build', FILE_NOT_FOUND, Message = 'Source override path does not exist:', File=self.MetaFile, ExtraData=Module.SourceOverridePath, Line=LineNo)\r
507 \r
508 #Add to GlobalData Variables\r
509 GlobalData.gOverrideDir[ModuleFile.Key] = Module.SourceOverridePath\r
510\r
511 # get module private library instance\r
512 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]\r
513 for Record in RecordList:\r
514 LibraryClass = Record[0]\r
515 LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
516 LineNo = Record[-1]\r
517\r
518 # check the file validation\r
519 ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')\r
520 if ErrorCode != 0:\r
521 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
522 ExtraData=ErrorInfo)\r
523\r
524 if LibraryClass == '' or LibraryClass == 'NULL':\r
525 self._NullLibraryNumber += 1\r
526 LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
527 EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))\r
528 Module.LibraryClasses[LibraryClass] = LibraryPath\r
529 if LibraryPath not in self.LibraryInstances:\r
530 self.LibraryInstances.append(LibraryPath)\r
531\r
532 # get module private PCD setting\r
533 for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \\r
534 MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:\r
535 RecordList = self._RawData[Type, self._Arch, None, ModuleId]\r
536 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
537 TokenList = GetSplitValueList(Setting)\r
538 DefaultValue = TokenList[0]\r
539 if len(TokenList) > 1:\r
540 MaxDatumSize = TokenList[1]\r
541 else:\r
542 MaxDatumSize = ''\r
543 TypeString = self._PCD_TYPE_STRING_[Type]\r
544 Pcd = PcdClassObject(\r
545 PcdCName,\r
546 TokenSpaceGuid,\r
547 TypeString,\r
548 '',\r
549 DefaultValue,\r
550 '',\r
551 MaxDatumSize,\r
552 {},\r
e56468c0 553 False,\r
52302d4d
LG
554 None\r
555 )\r
556 Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
557\r
558 # get module private build options\r
559 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]\r
560 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
561 if (ToolChainFamily, ToolChain) not in Module.BuildOptions:\r
562 Module.BuildOptions[ToolChainFamily, ToolChain] = Option\r
563 else:\r
564 OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]\r
565 Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
566\r
567 self._Modules[ModuleFile] = Module\r
568 return self._Modules\r
569\r
570 ## Retrieve all possible library instances used in this platform\r
571 def _GetLibraryInstances(self):\r
572 if self._LibraryInstances == None:\r
573 self._GetLibraryClasses()\r
574 return self._LibraryInstances\r
575\r
576 ## Retrieve [LibraryClasses] information\r
577 def _GetLibraryClasses(self):\r
578 if self._LibraryClasses == None:\r
579 self._LibraryInstances = []\r
580 #\r
581 # tdict is a special dict kind of type, used for selecting correct\r
582 # library instance for given library class and module type\r
583 #\r
584 LibraryClassDict = tdict(True, 3)\r
585 # track all library class names\r
586 LibraryClassSet = set()\r
0d2711a6
LG
587 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]\r
588 Macros = self._Macros\r
52302d4d
LG
589 for Record in RecordList:\r
590 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record\r
591 if LibraryClass == '' or LibraryClass == 'NULL':\r
592 self._NullLibraryNumber += 1\r
593 LibraryClass = 'NULL%d' % self._NullLibraryNumber\r
594 EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))\r
595 LibraryClassSet.add(LibraryClass)\r
596 LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
597 # check the file validation\r
598 ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')\r
599 if ErrorCode != 0:\r
600 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
601 ExtraData=ErrorInfo)\r
602\r
603 if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:\r
604 EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,\r
605 File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)\r
606 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance\r
607 if LibraryInstance not in self._LibraryInstances:\r
608 self._LibraryInstances.append(LibraryInstance)\r
609\r
610 # resolve the specific library instance for each class and each module type\r
611 self._LibraryClasses = tdict(True)\r
612 for LibraryClass in LibraryClassSet:\r
613 # try all possible module types\r
614 for ModuleType in SUP_MODULE_LIST:\r
615 LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]\r
616 if LibraryInstance == None:\r
617 continue\r
618 self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance\r
619\r
0d2711a6
LG
620 # for Edk style library instances, which are listed in different section\r
621 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
52302d4d
LG
622 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]\r
623 for Record in RecordList:\r
624 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
625 LineNo = Record[-1]\r
626 # check the file validation\r
627 ErrorCode, ErrorInfo = File.Validate('.inf')\r
628 if ErrorCode != 0:\r
629 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,\r
630 ExtraData=ErrorInfo)\r
631 if File not in self._LibraryInstances:\r
632 self._LibraryInstances.append(File)\r
633 #\r
634 # we need the module name as the library class name, so we have\r
635 # to parse it here. (self._Bdb[] will trigger a file parse if it\r
636 # hasn't been parsed)\r
637 #\r
0d2711a6 638 Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
52302d4d
LG
639 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library\r
640 return self._LibraryClasses\r
641\r
4afd3d04
LG
642 def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):\r
643 if self._DecPcds == None:\r
644 self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain)\r
645 if (PcdCName, TokenSpaceGuid) not in self._DecPcds:\r
646 EdkLogger.error('build', PARSER_ERROR,\r
647 "Pcd (%s.%s) defined in DSC is not declared in DEC files." % (TokenSpaceGuid, PcdCName),\r
648 File=self.MetaFile, Line=LineNo)\r
649 ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)\r
650 if not IsValid and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
651 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,\r
652 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))\r
653 if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:\r
654 try:\r
655 ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)\r
656 except WrnExpression, Value:\r
657 ValueList[Index] = Value.result\r
658 except EvaluationException, Excpt:\r
659 if hasattr(Excpt, 'Pcd'):\r
660 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
661 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"\r
662 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
663 " of the DSC file" % Excpt.Pcd,\r
664 File=self.MetaFile, Line=LineNo)\r
665 else:\r
666 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,\r
667 File=self.MetaFile, Line=LineNo)\r
668 else:\r
669 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),\r
670 File=self.MetaFile, Line=LineNo)\r
671 if ValueList[Index] == 'True':\r
672 ValueList[Index] = '1'\r
673 elif ValueList[Index] == 'False':\r
674 ValueList[Index] = '0'\r
675 if ValueList[Index]:\r
676 Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])\r
677 if not Valid:\r
678 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,\r
679 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))\r
680 return ValueList\r
681\r
52302d4d
LG
682 ## Retrieve all PCD settings in platform\r
683 def _GetPcds(self):\r
684 if self._Pcds == None:\r
0d2711a6 685 self._Pcds = sdict()\r
52302d4d
LG
686 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
687 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
688 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
689 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))\r
690 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))\r
691 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))\r
692 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))\r
693 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))\r
694 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))\r
695 return self._Pcds\r
696\r
697 ## Retrieve [BuildOptions]\r
698 def _GetBuildOptions(self):\r
699 if self._BuildOptions == None:\r
0d2711a6 700 self._BuildOptions = sdict()\r
52302d4d
LG
701 #\r
702 # Retrieve build option for EDKII style module\r
703 #\r
0d2711a6 704 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, EDKII_NAME]\r
52302d4d
LG
705 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
706 self._BuildOptions[ToolChainFamily, ToolChain, EDKII_NAME] = Option\r
707 #\r
708 # Retrieve build option for EDK style module\r
709 #\r
0d2711a6 710 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, EDK_NAME] \r
52302d4d
LG
711 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
712 self._BuildOptions[ToolChainFamily, ToolChain, EDK_NAME] = Option\r
713 return self._BuildOptions\r
714\r
715 ## Retrieve non-dynamic PCD settings\r
716 #\r
717 # @param Type PCD type\r
718 #\r
719 # @retval a dict object contains settings of given PCD type\r
720 #\r
721 def _GetPcd(self, Type):\r
0d2711a6 722 Pcds = sdict()\r
52302d4d
LG
723 #\r
724 # tdict is a special dict kind of type, used for selecting correct\r
725 # PCD settings for certain ARCH\r
726 #\r
e8a47801
LG
727 \r
728 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
729 \r
52302d4d
LG
730 PcdDict = tdict(True, 3)\r
731 PcdSet = set()\r
732 # Find out all possible PCD candidates for self._Arch\r
733 RecordList = self._RawData[Type, self._Arch]\r
e8a47801 734 PcdValueDict = sdict()\r
52302d4d 735 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
736 if SkuName in (SkuObj.SystemSkuId,'DEFAULT','COMMON'):\r
737 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
738 PcdDict[Arch, PcdCName, TokenSpaceGuid,SkuName] = Setting\r
739 \r
740 #handle pcd value override \r
741 for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdSet:\r
742 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid,SkuName]\r
52302d4d
LG
743 if Setting == None:\r
744 continue\r
4afd3d04 745 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
e8a47801
LG
746 if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
747 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue,DatumType,MaxDatumSize) \r
748 else:\r
749 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue,DatumType,MaxDatumSize)} \r
750 \r
751 PcdsKeys = PcdValueDict.keys()\r
752 for PcdCName,TokenSpaceGuid in PcdsKeys:\r
753 \r
754 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
755 PcdValue = None\r
756 DatumType = None\r
757 MaxDatumSize = None\r
758 if 'COMMON' in PcdSetting:\r
759 PcdValue,DatumType,MaxDatumSize = PcdSetting['COMMON']\r
760 if 'DEFAULT' in PcdSetting:\r
761 PcdValue,DatumType,MaxDatumSize = PcdSetting['DEFAULT']\r
762 if SkuObj.SystemSkuId in PcdSetting:\r
763 PcdValue,DatumType,MaxDatumSize = PcdSetting[SkuObj.SystemSkuId]\r
764 \r
52302d4d
LG
765 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
766 PcdCName,\r
767 TokenSpaceGuid,\r
768 self._PCD_TYPE_STRING_[Type],\r
769 DatumType,\r
770 PcdValue,\r
771 '',\r
772 MaxDatumSize,\r
773 {},\r
e56468c0 774 False,\r
52302d4d
LG
775 None\r
776 )\r
777 return Pcds\r
778\r
779 ## Retrieve dynamic PCD settings\r
780 #\r
781 # @param Type PCD type\r
782 #\r
783 # @retval a dict object contains settings of given PCD type\r
784 #\r
785 def _GetDynamicPcd(self, Type):\r
e8a47801
LG
786 \r
787 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
788 \r
0d2711a6 789 Pcds = sdict()\r
52302d4d
LG
790 #\r
791 # tdict is a special dict kind of type, used for selecting correct\r
792 # PCD settings for certain ARCH and SKU\r
793 #\r
794 PcdDict = tdict(True, 4)\r
6780eef1 795 PcdList = []\r
52302d4d
LG
796 # Find out all possible PCD candidates for self._Arch\r
797 RecordList = self._RawData[Type, self._Arch]\r
e8a47801
LG
798 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
799 \r
800 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
52302d4d 801 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
802 if SkuName not in AvailableSkuIdSet:\r
803 continue\r
804 \r
805 PcdList.append((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
52302d4d
LG
806 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
807 # Remove redundant PCD candidates, per the ARCH and SKU\r
e8a47801
LG
808 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
809 \r
810 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
52302d4d
LG
811 if Setting == None:\r
812 continue\r
6780eef1 813 \r
4afd3d04 814 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
e8a47801
LG
815 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue)\r
816 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
817 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
818 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2bc3256c
LG
819 if MaxDatumSize.strip():\r
820 CurrentMaxSize = int(MaxDatumSize.strip(),0)\r
821 else:\r
822 CurrentMaxSize = 0\r
823 if pcdObject.MaxDatumSize:\r
824 PcdMaxSize = int(pcdObject.MaxDatumSize,0)\r
825 else:\r
826 PcdMaxSize = 0\r
827 if CurrentMaxSize > PcdMaxSize:\r
828 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
e8a47801
LG
829 else: \r
830 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
831 PcdCName,\r
832 TokenSpaceGuid,\r
833 self._PCD_TYPE_STRING_[Type],\r
834 DatumType,\r
835 PcdValue,\r
836 '',\r
837 MaxDatumSize,\r
838 {SkuName : SkuInfo},\r
839 False,\r
840 None\r
841 )\r
842 \r
843 for pcd in Pcds.values():\r
2bc3256c
LG
844 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
845 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): \r
e8a47801
LG
846 valuefromDec = pcdDecObject.DefaultValue\r
847 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
848 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
849 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
850 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
851 del(pcd.SkuInfoList['COMMON'])\r
852 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
853 del(pcd.SkuInfoList['COMMON'])\r
854 if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
855 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
856 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
857 del(pcd.SkuInfoList['DEFAULT'])\r
2bc3256c 858 \r
52302d4d
LG
859 return Pcds\r
860\r
861 ## Retrieve dynamic HII PCD settings\r
862 #\r
863 # @param Type PCD type\r
864 #\r
865 # @retval a dict object contains settings of given PCD type\r
866 #\r
867 def _GetDynamicHiiPcd(self, Type):\r
e8a47801
LG
868 \r
869 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
870 \r
0d2711a6 871 Pcds = sdict()\r
52302d4d
LG
872 #\r
873 # tdict is a special dict kind of type, used for selecting correct\r
874 # PCD settings for certain ARCH and SKU\r
875 #\r
876 PcdDict = tdict(True, 4)\r
877 PcdSet = set()\r
878 RecordList = self._RawData[Type, self._Arch]\r
879 # Find out all possible PCD candidates for self._Arch\r
e8a47801
LG
880 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
881 \r
882 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
52302d4d 883 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
884 if SkuName not in AvailableSkuIdSet:\r
885 continue\r
886 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
52302d4d
LG
887 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
888 # Remove redundant PCD candidates, per the ARCH and SKU\r
e8a47801
LG
889 for PcdCName, TokenSpaceGuid,SkuName, Dummy4 in PcdSet:\r
890 \r
891 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
52302d4d
LG
892 if Setting == None:\r
893 continue\r
4afd3d04 894 VariableName, VariableGuid, VariableOffset, DefaultValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
2bc3256c
LG
895 \r
896 ExceedMax = False\r
e4ac870f 897 FormatCorrect = True\r
2bc3256c
LG
898 if VariableOffset.isdigit():\r
899 if int(VariableOffset,10) > 0xFFFF:\r
900 ExceedMax = True\r
901 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset):\r
902 if int(VariableOffset,16) > 0xFFFF:\r
903 ExceedMax = True\r
e4ac870f
LG
904 # For Offset written in "A.B"\r
905 elif VariableOffset.find('.') > -1:\r
906 VariableOffsetList = VariableOffset.split(".")\r
907 if not (len(VariableOffsetList) == 2\r
908 and IsValidWord(VariableOffsetList[0])\r
909 and IsValidWord(VariableOffsetList[1])):\r
910 FormatCorrect = False\r
2bc3256c 911 else:\r
e4ac870f
LG
912 FormatCorrect = False\r
913 if not FormatCorrect:\r
2bc3256c
LG
914 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid,PcdCName)))\r
915 \r
916 if ExceedMax:\r
917 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid,PcdCName)))\r
918 \r
e8a47801
LG
919 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)\r
920 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
921 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
922 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
923 else:\r
924 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
52302d4d
LG
925 PcdCName,\r
926 TokenSpaceGuid,\r
927 self._PCD_TYPE_STRING_[Type],\r
928 '',\r
929 DefaultValue,\r
930 '',\r
931 '',\r
e8a47801 932 {SkuName : SkuInfo},\r
e56468c0 933 False,\r
52302d4d
LG
934 None\r
935 )\r
e8a47801
LG
936 \r
937\r
938 for pcd in Pcds.values():\r
939 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
2bc3256c
LG
940 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
941 # Only fix the value while no value provided in DSC file.\r
942 for sku in pcd.SkuInfoList.values():\r
943 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue==None):\r
944 sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
945 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): \r
e8a47801
LG
946 valuefromDec = pcdDecObject.DefaultValue\r
947 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)\r
948 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
949 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
950 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
951 del(pcd.SkuInfoList['COMMON'])\r
952 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
953 del(pcd.SkuInfoList['COMMON'])\r
954 \r
955 if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
956 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
957 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
958 del(pcd.SkuInfoList['DEFAULT'])\r
2bc3256c
LG
959 \r
960 \r
961 if pcd.MaxDatumSize.strip(): \r
962 MaxSize = int(pcd.MaxDatumSize,0)\r
963 else:\r
964 MaxSize = 0\r
965 if pcdDecObject.DatumType == 'VOID*':\r
966 for (skuname,skuobj) in pcd.SkuInfoList.items():\r
967 datalen = 0\r
968 if skuobj.HiiDefaultValue.startswith("L"):\r
969 datalen = (len(skuobj.HiiDefaultValue)- 3 + 1) * 2\r
970 elif skuobj.HiiDefaultValue.startswith("{"):\r
971 datalen = len(skuobj.HiiDefaultValue.split(","))\r
972 else:\r
973 datalen = len(skuobj.HiiDefaultValue) -2 + 1 \r
974 if datalen>MaxSize:\r
975 MaxSize = datalen\r
976 pcd.MaxDatumSize = str(MaxSize)\r
52302d4d
LG
977 return Pcds\r
978\r
979 ## Retrieve dynamic VPD PCD settings\r
980 #\r
981 # @param Type PCD type\r
982 #\r
983 # @retval a dict object contains settings of given PCD type\r
984 #\r
985 def _GetDynamicVpdPcd(self, Type):\r
e8a47801
LG
986 \r
987 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
988 \r
0d2711a6 989 Pcds = sdict()\r
52302d4d
LG
990 #\r
991 # tdict is a special dict kind of type, used for selecting correct\r
992 # PCD settings for certain ARCH and SKU\r
993 #\r
994 PcdDict = tdict(True, 4)\r
6780eef1 995 PcdList = []\r
52302d4d
LG
996 # Find out all possible PCD candidates for self._Arch\r
997 RecordList = self._RawData[Type, self._Arch]\r
e8a47801
LG
998 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
999 \r
1000 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
52302d4d 1001 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
1002 if SkuName not in AvailableSkuIdSet:\r
1003 continue\r
1004\r
1005 PcdList.append((PcdCName, TokenSpaceGuid,SkuName, Dummy4))\r
52302d4d
LG
1006 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1007 # Remove redundant PCD candidates, per the ARCH and SKU\r
e8a47801
LG
1008 for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdList:\r
1009 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
52302d4d
LG
1010 if Setting == None:\r
1011 continue\r
e56468c0 1012 #\r
1013 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
1014 # For the Integer & Boolean type, the optional data can only be InitialValue.\r
1015 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
1016 # until the DEC parser has been called.\r
1017 # \r
4afd3d04 1018 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
e8a47801
LG
1019 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue)\r
1020 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
1021 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
1022 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2bc3256c
LG
1023 if MaxDatumSize.strip():\r
1024 CurrentMaxSize = int(MaxDatumSize.strip(),0)\r
1025 else:\r
1026 CurrentMaxSize = 0\r
1027 if pcdObject.MaxDatumSize:\r
1028 PcdMaxSize = int(pcdObject.MaxDatumSize,0)\r
1029 else:\r
1030 PcdMaxSize = 0\r
1031 if CurrentMaxSize > PcdMaxSize:\r
1032 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
e8a47801
LG
1033 else:\r
1034 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
52302d4d
LG
1035 PcdCName,\r
1036 TokenSpaceGuid,\r
1037 self._PCD_TYPE_STRING_[Type],\r
1038 '',\r
1039 '',\r
1040 '',\r
1041 MaxDatumSize,\r
e8a47801 1042 {SkuName : SkuInfo},\r
e56468c0 1043 False,\r
52302d4d
LG
1044 None\r
1045 )\r
e8a47801
LG
1046 for pcd in Pcds.values():\r
1047 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
2bc3256c 1048 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
e8a47801 1049 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
e8a47801
LG
1050 valuefromDec = pcdDecObject.DefaultValue\r
1051 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj.VpdOffset, valuefromDec)\r
1052 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1053 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1054 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1055 del(pcd.SkuInfoList['COMMON'])\r
1056 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1057 del(pcd.SkuInfoList['COMMON'])\r
1058 if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
1059 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
1060 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
1061 del(pcd.SkuInfoList['DEFAULT'])\r
1062 \r
52302d4d
LG
1063 return Pcds\r
1064\r
1065 ## Add external modules\r
1066 #\r
1067 # The external modules are mostly those listed in FDF file, which don't\r
1068 # need "build".\r
1069 #\r
1070 # @param FilePath The path of module description file\r
1071 #\r
1072 def AddModule(self, FilePath):\r
1073 FilePath = NormPath(FilePath)\r
1074 if FilePath not in self.Modules:\r
1075 Module = ModuleBuildClassObject()\r
1076 Module.MetaFile = FilePath\r
1077 self.Modules.append(Module)\r
1078\r
1079 ## Add external PCDs\r
1080 #\r
1081 # The external PCDs are mostly those listed in FDF file to specify address\r
1082 # or offset information.\r
1083 #\r
1084 # @param Name Name of the PCD\r
1085 # @param Guid Token space guid of the PCD\r
1086 # @param Value Value of the PCD\r
1087 #\r
1088 def AddPcd(self, Name, Guid, Value):\r
1089 if (Name, Guid) not in self.Pcds:\r
e56468c0 1090 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
52302d4d
LG
1091 self.Pcds[Name, Guid].DefaultValue = Value\r
1092\r
0d2711a6 1093 _Macros = property(_GetMacros)\r
52302d4d
LG
1094 Arch = property(_GetArch, _SetArch)\r
1095 Platform = property(_GetPlatformName)\r
1096 PlatformName = property(_GetPlatformName)\r
1097 Guid = property(_GetFileGuid)\r
1098 Version = property(_GetVersion)\r
1099 DscSpecification = property(_GetDscSpec)\r
1100 OutputDirectory = property(_GetOutpuDir)\r
1101 SupArchList = property(_GetSupArch)\r
1102 BuildTargets = property(_GetBuildTarget)\r
1103 SkuName = property(_GetSkuName, _SetSkuName)\r
e8a47801
LG
1104 SkuIdentifier = property(_GetSkuIdentifier)\r
1105 PcdInfoFlag = property(_GetPcdInfoFlag)\r
52302d4d
LG
1106 FlashDefinition = property(_GetFdfFile)\r
1107 BuildNumber = property(_GetBuildNumber)\r
1108 MakefileName = property(_GetMakefileName)\r
1109 BsBaseAddress = property(_GetBsBaseAddress)\r
1110 RtBaseAddress = property(_GetRtBaseAddress)\r
1111 LoadFixAddress = property(_GetLoadFixAddress)\r
6780eef1
LG
1112 RFCLanguages = property(_GetRFCLanguages)\r
1113 ISOLanguages = property(_GetISOLanguages)\r
08dd311f 1114 VpdToolGuid = property(_GetVpdToolGuid) \r
52302d4d
LG
1115 SkuIds = property(_GetSkuIds)\r
1116 Modules = property(_GetModules)\r
1117 LibraryInstances = property(_GetLibraryInstances)\r
1118 LibraryClasses = property(_GetLibraryClasses)\r
1119 Pcds = property(_GetPcds)\r
1120 BuildOptions = property(_GetBuildOptions)\r
1121\r
e56468c0 1122## Platform build information from DEC file\r
52302d4d
LG
1123#\r
1124# This class is used to retrieve information stored in database and convert them\r
1125# into PackageBuildClassObject form for easier use for AutoGen.\r
1126#\r
1127class DecBuildData(PackageBuildClassObject):\r
1128 # dict used to convert PCD type in database to string used by build tool\r
1129 _PCD_TYPE_STRING_ = {\r
1130 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
1131 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
1132 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
1133 MODEL_PCD_DYNAMIC : "Dynamic",\r
1134 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
1135 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
1136 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
1137 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
1138 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
1139 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
1140 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
1141 }\r
1142\r
1143 # dict used to convert part of [Defines] to members of DecBuildData directly\r
1144 _PROPERTY_ = {\r
1145 #\r
1146 # Required Fields\r
1147 #\r
1148 TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName",\r
1149 TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid",\r
1150 TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version",\r
e56468c0 1151 TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile",\r
52302d4d
LG
1152 }\r
1153\r
1154\r
1155 ## Constructor of DecBuildData\r
1156 #\r
1157 # Initialize object of DecBuildData\r
1158 #\r
1159 # @param FilePath The path of package description file\r
1160 # @param RawData The raw data of DEC file\r
1161 # @param BuildDataBase Database used to retrieve module information\r
1162 # @param Arch The target architecture\r
1163 # @param Platform (not used for DecBuildData)\r
1164 # @param Macros Macros used for replacement in DSC file\r
1165 #\r
0d2711a6 1166 def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r
52302d4d
LG
1167 self.MetaFile = File\r
1168 self._PackageDir = File.Dir\r
1169 self._RawData = RawData\r
1170 self._Bdb = BuildDataBase\r
1171 self._Arch = Arch\r
0d2711a6
LG
1172 self._Target = Target\r
1173 self._Toolchain = Toolchain\r
52302d4d
LG
1174 self._Clear()\r
1175\r
1176 ## XXX[key] = value\r
1177 def __setitem__(self, key, value):\r
1178 self.__dict__[self._PROPERTY_[key]] = value\r
1179\r
1180 ## value = XXX[key]\r
1181 def __getitem__(self, key):\r
1182 return self.__dict__[self._PROPERTY_[key]]\r
1183\r
1184 ## "in" test support\r
1185 def __contains__(self, key):\r
1186 return key in self._PROPERTY_\r
1187\r
1188 ## Set all internal used members of DecBuildData to None\r
1189 def _Clear(self):\r
1190 self._Header = None\r
1191 self._PackageName = None\r
1192 self._Guid = None\r
1193 self._Version = None\r
e56468c0 1194 self._PkgUniFile = None\r
52302d4d
LG
1195 self._Protocols = None\r
1196 self._Ppis = None\r
1197 self._Guids = None\r
1198 self._Includes = None\r
1199 self._LibraryClasses = None\r
1200 self._Pcds = None\r
0d2711a6
LG
1201 self.__Macros = None\r
1202\r
1203 ## Get current effective macros\r
1204 def _GetMacros(self):\r
1205 if self.__Macros == None:\r
1206 self.__Macros = {}\r
1207 self.__Macros.update(GlobalData.gGlobalDefines)\r
1208 return self.__Macros\r
52302d4d
LG
1209\r
1210 ## Get architecture\r
1211 def _GetArch(self):\r
1212 return self._Arch\r
1213\r
1214 ## Set architecture\r
1215 #\r
1216 # Changing the default ARCH to another may affect all other information\r
1217 # because all information in a platform may be ARCH-related. That's\r
1218 # why we need to clear all internal used members, in order to cause all\r
1219 # information to be re-retrieved.\r
1220 #\r
1221 # @param Value The value of ARCH\r
1222 #\r
1223 def _SetArch(self, Value):\r
1224 if self._Arch == Value:\r
1225 return\r
1226 self._Arch = Value\r
1227 self._Clear()\r
1228\r
1229 ## Retrieve all information in [Defines] section\r
1230 #\r
1231 # (Retriving all [Defines] information in one-shot is just to save time.)\r
1232 #\r
1233 def _GetHeaderInfo(self):\r
0d2711a6 1234 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
52302d4d 1235 for Record in RecordList:\r
0d2711a6 1236 Name = Record[1]\r
52302d4d 1237 if Name in self:\r
0d2711a6 1238 self[Name] = Record[2]\r
52302d4d
LG
1239 self._Header = 'DUMMY'\r
1240\r
1241 ## Retrieve package name\r
1242 def _GetPackageName(self):\r
1243 if self._PackageName == None:\r
1244 if self._Header == None:\r
1245 self._GetHeaderInfo()\r
1246 if self._PackageName == None:\r
1247 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)\r
1248 return self._PackageName\r
1249\r
1250 ## Retrieve file guid\r
1251 def _GetFileGuid(self):\r
1252 if self._Guid == None:\r
1253 if self._Header == None:\r
1254 self._GetHeaderInfo()\r
1255 if self._Guid == None:\r
1256 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)\r
1257 return self._Guid\r
1258\r
1259 ## Retrieve package version\r
1260 def _GetVersion(self):\r
1261 if self._Version == None:\r
1262 if self._Header == None:\r
1263 self._GetHeaderInfo()\r
1264 if self._Version == None:\r
1265 self._Version = ''\r
1266 return self._Version\r
1267\r
1268 ## Retrieve protocol definitions (name/value pairs)\r
1269 def _GetProtocol(self):\r
1270 if self._Protocols == None:\r
1271 #\r
1272 # tdict is a special kind of dict, used for selecting correct\r
1273 # protocol defition for given ARCH\r
1274 #\r
1275 ProtocolDict = tdict(True)\r
1276 NameList = []\r
1277 # find out all protocol definitions for specific and 'common' arch\r
1278 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]\r
1279 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
1280 if Name not in NameList:\r
1281 NameList.append(Name)\r
1282 ProtocolDict[Arch, Name] = Guid\r
1283 # use sdict to keep the order\r
1284 self._Protocols = sdict()\r
1285 for Name in NameList:\r
1286 #\r
1287 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1288 # will automatically turn to 'common' ARCH for trying\r
1289 #\r
1290 self._Protocols[Name] = ProtocolDict[self._Arch, Name]\r
1291 return self._Protocols\r
1292\r
1293 ## Retrieve PPI definitions (name/value pairs)\r
1294 def _GetPpi(self):\r
1295 if self._Ppis == None:\r
1296 #\r
1297 # tdict is a special kind of dict, used for selecting correct\r
1298 # PPI defition for given ARCH\r
1299 #\r
1300 PpiDict = tdict(True)\r
1301 NameList = []\r
1302 # find out all PPI definitions for specific arch and 'common' arch\r
1303 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]\r
1304 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
1305 if Name not in NameList:\r
1306 NameList.append(Name)\r
1307 PpiDict[Arch, Name] = Guid\r
1308 # use sdict to keep the order\r
1309 self._Ppis = sdict()\r
1310 for Name in NameList:\r
1311 #\r
1312 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1313 # will automatically turn to 'common' ARCH for trying\r
1314 #\r
1315 self._Ppis[Name] = PpiDict[self._Arch, Name]\r
1316 return self._Ppis\r
1317\r
1318 ## Retrieve GUID definitions (name/value pairs)\r
1319 def _GetGuid(self):\r
1320 if self._Guids == None:\r
1321 #\r
1322 # tdict is a special kind of dict, used for selecting correct\r
1323 # GUID defition for given ARCH\r
1324 #\r
1325 GuidDict = tdict(True)\r
1326 NameList = []\r
1327 # find out all protocol definitions for specific and 'common' arch\r
1328 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]\r
1329 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
1330 if Name not in NameList:\r
1331 NameList.append(Name)\r
1332 GuidDict[Arch, Name] = Guid\r
1333 # use sdict to keep the order\r
1334 self._Guids = sdict()\r
1335 for Name in NameList:\r
1336 #\r
1337 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1338 # will automatically turn to 'common' ARCH for trying\r
1339 #\r
1340 self._Guids[Name] = GuidDict[self._Arch, Name]\r
1341 return self._Guids\r
1342\r
1343 ## Retrieve public include paths declared in this package\r
1344 def _GetInclude(self):\r
1345 if self._Includes == None:\r
1346 self._Includes = []\r
1347 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]\r
0d2711a6
LG
1348 Macros = self._Macros\r
1349 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
52302d4d
LG
1350 for Record in RecordList:\r
1351 File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)\r
1352 LineNo = Record[-1]\r
1353 # validate the path\r
1354 ErrorCode, ErrorInfo = File.Validate()\r
1355 if ErrorCode != 0:\r
1356 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1357\r
1358 # avoid duplicate include path\r
1359 if File not in self._Includes:\r
1360 self._Includes.append(File)\r
1361 return self._Includes\r
1362\r
1363 ## Retrieve library class declarations (not used in build at present)\r
1364 def _GetLibraryClass(self):\r
1365 if self._LibraryClasses == None:\r
1366 #\r
1367 # tdict is a special kind of dict, used for selecting correct\r
1368 # library class declaration for given ARCH\r
1369 #\r
1370 LibraryClassDict = tdict(True)\r
1371 LibraryClassSet = set()\r
1372 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
0d2711a6 1373 Macros = self._Macros\r
52302d4d
LG
1374 for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:\r
1375 File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)\r
1376 # check the file validation\r
1377 ErrorCode, ErrorInfo = File.Validate()\r
1378 if ErrorCode != 0:\r
1379 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1380 LibraryClassSet.add(LibraryClass)\r
1381 LibraryClassDict[Arch, LibraryClass] = File\r
1382 self._LibraryClasses = sdict()\r
1383 for LibraryClass in LibraryClassSet:\r
1384 self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]\r
1385 return self._LibraryClasses\r
1386\r
1387 ## Retrieve PCD declarations\r
1388 def _GetPcds(self):\r
1389 if self._Pcds == None:\r
0d2711a6 1390 self._Pcds = sdict()\r
52302d4d
LG
1391 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
1392 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
1393 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
1394 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
1395 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
1396 return self._Pcds\r
1397\r
1398 ## Retrieve PCD declarations for given type\r
1399 def _GetPcd(self, Type):\r
0d2711a6 1400 Pcds = sdict()\r
52302d4d
LG
1401 #\r
1402 # tdict is a special kind of dict, used for selecting correct\r
1403 # PCD declaration for given ARCH\r
1404 #\r
1405 PcdDict = tdict(True, 3)\r
1406 # for summarizing PCD\r
1407 PcdSet = set()\r
1408 # find out all PCDs of the 'type'\r
1409 RecordList = self._RawData[Type, self._Arch]\r
1410 for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList:\r
1411 PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
1412 PcdSet.add((PcdCName, TokenSpaceGuid))\r
1413\r
1414 for PcdCName, TokenSpaceGuid in PcdSet:\r
52302d4d
LG
1415 #\r
1416 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1417 # will automatically turn to 'common' ARCH and try again\r
1418 #\r
1419 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
1420 if Setting == None:\r
1421 continue\r
6780eef1
LG
1422\r
1423 DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)\r
1424 \r
52302d4d
LG
1425 Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
1426 PcdCName,\r
1427 TokenSpaceGuid,\r
1428 self._PCD_TYPE_STRING_[Type],\r
1429 DatumType,\r
1430 DefaultValue,\r
1431 TokenNumber,\r
1432 '',\r
1433 {},\r
e56468c0 1434 False,\r
52302d4d
LG
1435 None\r
1436 )\r
1437 return Pcds\r
1438\r
1439\r
0d2711a6 1440 _Macros = property(_GetMacros)\r
52302d4d
LG
1441 Arch = property(_GetArch, _SetArch)\r
1442 PackageName = property(_GetPackageName)\r
1443 Guid = property(_GetFileGuid)\r
1444 Version = property(_GetVersion)\r
1445\r
1446 Protocols = property(_GetProtocol)\r
1447 Ppis = property(_GetPpi)\r
1448 Guids = property(_GetGuid)\r
1449 Includes = property(_GetInclude)\r
1450 LibraryClasses = property(_GetLibraryClass)\r
1451 Pcds = property(_GetPcds)\r
1452\r
1453## Module build information from INF file\r
1454#\r
1455# This class is used to retrieve information stored in database and convert them\r
1456# into ModuleBuildClassObject form for easier use for AutoGen.\r
1457#\r
1458class InfBuildData(ModuleBuildClassObject):\r
1459 # dict used to convert PCD type in database to string used by build tool\r
1460 _PCD_TYPE_STRING_ = {\r
1461 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
1462 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
1463 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
1464 MODEL_PCD_DYNAMIC : "Dynamic",\r
1465 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
1466 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
1467 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
1468 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
1469 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
1470 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
1471 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
1472 }\r
1473\r
1474 # dict used to convert part of [Defines] to members of InfBuildData directly\r
1475 _PROPERTY_ = {\r
1476 #\r
1477 # Required Fields\r
1478 #\r
1479 TAB_INF_DEFINES_BASE_NAME : "_BaseName",\r
1480 TAB_INF_DEFINES_FILE_GUID : "_Guid",\r
1481 TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",\r
1482 #\r
1483 # Optional Fields\r
1484 #\r
0d2711a6 1485 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",\r
52302d4d
LG
1486 TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",\r
1487 TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",\r
1488 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",\r
b36d134f 1489 TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",\r
52302d4d
LG
1490 TAB_INF_DEFINES_VERSION_NUMBER : "_Version",\r
1491 TAB_INF_DEFINES_VERSION_STRING : "_Version",\r
1492 TAB_INF_DEFINES_VERSION : "_Version",\r
1493 TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",\r
1494 TAB_INF_DEFINES_SHADOW : "_Shadow",\r
1495\r
1496 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath",\r
1497 }\r
1498\r
1499 # dict used to convert Component type to Module type\r
1500 _MODULE_TYPE_ = {\r
1501 "LIBRARY" : "BASE",\r
1502 "SECURITY_CORE" : "SEC",\r
1503 "PEI_CORE" : "PEI_CORE",\r
1504 "COMBINED_PEIM_DRIVER" : "PEIM",\r
1505 "PIC_PEIM" : "PEIM",\r
1506 "RELOCATABLE_PEIM" : "PEIM",\r
1507 "PE32_PEIM" : "PEIM",\r
1508 "BS_DRIVER" : "DXE_DRIVER",\r
1509 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",\r
1510 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",\r
1511 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",\r
1512 # "SMM_DRIVER" : "DXE_SMM_DRIVER",\r
1513 # "BS_DRIVER" : "DXE_SMM_DRIVER",\r
1514 # "BS_DRIVER" : "UEFI_DRIVER",\r
1515 "APPLICATION" : "UEFI_APPLICATION",\r
1516 "LOGO" : "BASE",\r
1517 }\r
1518\r
1519 # regular expression for converting XXX_FLAGS in [nmake] section to new type\r
1520 _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)\r
1521 # dict used to convert old tool name used in [nmake] section to new ones\r
1522 _TOOL_CODE_ = {\r
1523 "C" : "CC",\r
1524 "LIB" : "SLINK",\r
1525 "LINK" : "DLINK",\r
1526 }\r
1527\r
1528\r
1529 ## Constructor of DscBuildData\r
1530 #\r
1531 # Initialize object of DscBuildData\r
1532 #\r
1533 # @param FilePath The path of platform description file\r
1534 # @param RawData The raw data of DSC file\r
1535 # @param BuildDataBase Database used to retrieve module/package information\r
1536 # @param Arch The target architecture\r
1537 # @param Platform The name of platform employing this module\r
1538 # @param Macros Macros used for replacement in DSC file\r
1539 #\r
0d2711a6 1540 def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):\r
52302d4d
LG
1541 self.MetaFile = FilePath\r
1542 self._ModuleDir = FilePath.Dir\r
1543 self._RawData = RawData\r
1544 self._Bdb = BuildDatabase\r
1545 self._Arch = Arch\r
0d2711a6
LG
1546 self._Target = Target\r
1547 self._Toolchain = Toolchain\r
52302d4d 1548 self._Platform = 'COMMON'\r
52302d4d
LG
1549 self._SourceOverridePath = None\r
1550 if FilePath.Key in GlobalData.gOverrideDir:\r
1551 self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]\r
1552 self._Clear()\r
1553\r
1554 ## XXX[key] = value\r
1555 def __setitem__(self, key, value):\r
1556 self.__dict__[self._PROPERTY_[key]] = value\r
1557\r
1558 ## value = XXX[key]\r
1559 def __getitem__(self, key):\r
1560 return self.__dict__[self._PROPERTY_[key]]\r
1561\r
1562 ## "in" test support\r
1563 def __contains__(self, key):\r
1564 return key in self._PROPERTY_\r
1565\r
1566 ## Set all internal used members of InfBuildData to None\r
1567 def _Clear(self):\r
e8a47801 1568 self._HeaderComments = None\r
2bc3256c 1569 self._TailComments = None\r
52302d4d
LG
1570 self._Header_ = None\r
1571 self._AutoGenVersion = None\r
1572 self._BaseName = None\r
b36d134f 1573 self._DxsFile = None\r
52302d4d
LG
1574 self._ModuleType = None\r
1575 self._ComponentType = None\r
1576 self._BuildType = None\r
1577 self._Guid = None\r
1578 self._Version = None\r
1579 self._PcdIsDriver = None\r
1580 self._BinaryModule = None\r
1581 self._Shadow = None\r
1582 self._MakefileName = None\r
1583 self._CustomMakefile = None\r
1584 self._Specification = None\r
1585 self._LibraryClass = None\r
1586 self._ModuleEntryPointList = None\r
1587 self._ModuleUnloadImageList = None\r
1588 self._ConstructorList = None\r
1589 self._DestructorList = None\r
1590 self._Defs = None\r
1591 self._Binaries = None\r
1592 self._Sources = None\r
1593 self._LibraryClasses = None\r
1594 self._Libraries = None\r
1595 self._Protocols = None\r
e8a47801 1596 self._ProtocolComments = None\r
52302d4d 1597 self._Ppis = None\r
e8a47801 1598 self._PpiComments = None\r
52302d4d 1599 self._Guids = None\r
e8a47801
LG
1600 self._GuidsUsedByPcd = sdict()\r
1601 self._GuidComments = None\r
52302d4d
LG
1602 self._Includes = None\r
1603 self._Packages = None\r
1604 self._Pcds = None\r
e8a47801 1605 self._PcdComments = None\r
52302d4d
LG
1606 self._BuildOptions = None\r
1607 self._Depex = None\r
1608 self._DepexExpression = None\r
0d2711a6
LG
1609 self.__Macros = None\r
1610\r
1611 ## Get current effective macros\r
1612 def _GetMacros(self):\r
1613 if self.__Macros == None:\r
1614 self.__Macros = {}\r
d0acc87a 1615 # EDK_GLOBAL defined macros can be applied to EDK module\r
0d2711a6
LG
1616 if self.AutoGenVersion < 0x00010005:\r
1617 self.__Macros.update(GlobalData.gEdkGlobal)\r
d0acc87a 1618 self.__Macros.update(GlobalData.gGlobalDefines)\r
0d2711a6 1619 return self.__Macros\r
52302d4d
LG
1620\r
1621 ## Get architecture\r
1622 def _GetArch(self):\r
1623 return self._Arch\r
1624\r
1625 ## Set architecture\r
1626 #\r
1627 # Changing the default ARCH to another may affect all other information\r
1628 # because all information in a platform may be ARCH-related. That's\r
1629 # why we need to clear all internal used members, in order to cause all\r
1630 # information to be re-retrieved.\r
1631 #\r
1632 # @param Value The value of ARCH\r
1633 #\r
1634 def _SetArch(self, Value):\r
1635 if self._Arch == Value:\r
1636 return\r
1637 self._Arch = Value\r
1638 self._Clear()\r
1639\r
1640 ## Return the name of platform employing this module\r
1641 def _GetPlatform(self):\r
1642 return self._Platform\r
1643\r
1644 ## Change the name of platform employing this module\r
1645 #\r
1646 # Changing the default name of platform to another may affect some information\r
1647 # because they may be PLATFORM-related. That's why we need to clear all internal\r
1648 # used members, in order to cause all information to be re-retrieved.\r
1649 #\r
1650 def _SetPlatform(self, Value):\r
1651 if self._Platform == Value:\r
1652 return\r
1653 self._Platform = Value\r
1654 self._Clear()\r
e8a47801
LG
1655 def _GetHeaderComments(self):\r
1656 if not self._HeaderComments:\r
1657 self._HeaderComments = []\r
1658 RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]\r
1659 for Record in RecordList:\r
1660 self._HeaderComments.append(Record[0])\r
1661 return self._HeaderComments\r
2bc3256c
LG
1662 def _GetTailComments(self):\r
1663 if not self._TailComments:\r
1664 self._TailComments = []\r
1665 RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]\r
1666 for Record in RecordList:\r
1667 self._TailComments.append(Record[0])\r
1668 return self._TailComments\r
52302d4d
LG
1669 ## Retrieve all information in [Defines] section\r
1670 #\r
1671 # (Retriving all [Defines] information in one-shot is just to save time.)\r
1672 #\r
1673 def _GetHeaderInfo(self):\r
1674 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
1675 for Record in RecordList:\r
0d2711a6 1676 Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)\r
52302d4d
LG
1677 # items defined _PROPERTY_ don't need additional processing\r
1678 if Name in self:\r
0d2711a6 1679 self[Name] = Value\r
52302d4d 1680 # some special items in [Defines] section need special treatment\r
08dd311f
LG
1681 elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):\r
1682 if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):\r
1683 Name = 'UEFI_SPECIFICATION_VERSION'\r
52302d4d
LG
1684 if self._Specification == None:\r
1685 self._Specification = sdict()\r
0d2711a6 1686 self._Specification[Name] = GetHexVerValue(Value)\r
08dd311f
LG
1687 if self._Specification[Name] == None:\r
1688 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
0d2711a6 1689 "'%s' format is not supported for %s" % (Value, Name),\r
08dd311f 1690 File=self.MetaFile, Line=Record[-1])\r
52302d4d
LG
1691 elif Name == 'LIBRARY_CLASS':\r
1692 if self._LibraryClass == None:\r
1693 self._LibraryClass = []\r
0d2711a6 1694 ValueList = GetSplitValueList(Value)\r
52302d4d
LG
1695 LibraryClass = ValueList[0]\r
1696 if len(ValueList) > 1:\r
1697 SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
1698 else:\r
1699 SupModuleList = SUP_MODULE_LIST\r
1700 self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))\r
1701 elif Name == 'ENTRY_POINT':\r
1702 if self._ModuleEntryPointList == None:\r
1703 self._ModuleEntryPointList = []\r
0d2711a6 1704 self._ModuleEntryPointList.append(Value)\r
52302d4d
LG
1705 elif Name == 'UNLOAD_IMAGE':\r
1706 if self._ModuleUnloadImageList == None:\r
1707 self._ModuleUnloadImageList = []\r
0d2711a6 1708 if not Value:\r
52302d4d 1709 continue\r
0d2711a6 1710 self._ModuleUnloadImageList.append(Value)\r
52302d4d
LG
1711 elif Name == 'CONSTRUCTOR':\r
1712 if self._ConstructorList == None:\r
1713 self._ConstructorList = []\r
0d2711a6 1714 if not Value:\r
52302d4d 1715 continue\r
0d2711a6 1716 self._ConstructorList.append(Value)\r
52302d4d
LG
1717 elif Name == 'DESTRUCTOR':\r
1718 if self._DestructorList == None:\r
1719 self._DestructorList = []\r
0d2711a6 1720 if not Value:\r
52302d4d 1721 continue\r
0d2711a6 1722 self._DestructorList.append(Value)\r
52302d4d 1723 elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:\r
0d2711a6 1724 TokenList = GetSplitValueList(Value)\r
52302d4d
LG
1725 if self._CustomMakefile == None:\r
1726 self._CustomMakefile = {}\r
1727 if len(TokenList) < 2:\r
1728 self._CustomMakefile['MSFT'] = TokenList[0]\r
1729 self._CustomMakefile['GCC'] = TokenList[0]\r
1730 else:\r
1731 if TokenList[0] not in ['MSFT', 'GCC']:\r
1732 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
1733 "No supported family [%s]" % TokenList[0],\r
1734 File=self.MetaFile, Line=Record[-1])\r
1735 self._CustomMakefile[TokenList[0]] = TokenList[1]\r
1736 else:\r
1737 if self._Defs == None:\r
1738 self._Defs = sdict()\r
0d2711a6 1739 self._Defs[Name] = Value\r
52302d4d
LG
1740\r
1741 #\r
0d2711a6 1742 # Retrieve information in sections specific to Edk.x modules\r
52302d4d 1743 #\r
0d2711a6 1744 if self.AutoGenVersion >= 0x00010005:\r
52302d4d
LG
1745 if not self._ModuleType:\r
1746 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
1747 "MODULE_TYPE is not given", File=self.MetaFile)\r
da92f276
LG
1748 if self._ModuleType not in SUP_MODULE_LIST:\r
1749 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
1750 for Record in RecordList:\r
0d2711a6 1751 Name = Record[1]\r
da92f276
LG
1752 if Name == "MODULE_TYPE":\r
1753 LineNo = Record[6]\r
1754 break\r
1755 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
1756 "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
0d2711a6 1757 File=self.MetaFile, Line=LineNo)\r
da92f276 1758 if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):\r
52302d4d
LG
1759 if self._ModuleType == SUP_MODULE_SMM_CORE:\r
1760 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
1761 if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
1762 and 'PCI_CLASS_CODE' in self._Defs:\r
1763 self._BuildType = 'UEFI_OPTIONROM'\r
1764 elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \\r
1765 and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':\r
1766 self._BuildType = 'UEFI_HII'\r
1767 else:\r
1768 self._BuildType = self._ModuleType.upper()\r
b36d134f
LG
1769 \r
1770 if self._DxsFile:\r
1771 File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
1772 # check the file validation\r
1773 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
1774 if ErrorCode != 0:\r
1775 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
1776 File=self.MetaFile, Line=LineNo)\r
1777 if self.Sources == None:\r
1778 self._Sources = []\r
1779 self._Sources.append(File)\r
0d2711a6 1780 else: \r
52302d4d
LG
1781 if not self._ComponentType:\r
1782 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
1783 "COMPONENT_TYPE is not given", File=self.MetaFile)\r
0d2711a6 1784 self._BuildType = self._ComponentType.upper() \r
52302d4d
LG
1785 if self._ComponentType in self._MODULE_TYPE_:\r
1786 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
1787 if self._ComponentType == 'LIBRARY':\r
1788 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
1789 # make use some [nmake] section macros\r
0d2711a6
LG
1790 Macros = self._Macros\r
1791 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
1792 Macros['PROCESSOR'] = self._Arch\r
52302d4d
LG
1793 RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
1794 for Name,Value,Dummy,Arch,Platform,ID,LineNo in RecordList:\r
0d2711a6 1795 Value = ReplaceMacro(Value, Macros, True)\r
52302d4d
LG
1796 if Name == "IMAGE_ENTRY_POINT":\r
1797 if self._ModuleEntryPointList == None:\r
1798 self._ModuleEntryPointList = []\r
1799 self._ModuleEntryPointList.append(Value)\r
1800 elif Name == "DPX_SOURCE":\r
0d2711a6 1801 File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)\r
52302d4d
LG
1802 # check the file validation\r
1803 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
1804 if ErrorCode != 0:\r
1805 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
1806 File=self.MetaFile, Line=LineNo)\r
1807 if self.Sources == None:\r
1808 self._Sources = []\r
1809 self._Sources.append(File)\r
1810 else:\r
1811 ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
1812 if len(ToolList) == 0 or len(ToolList) != 1:\r
1813 pass\r
1814# EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,\r
1815# File=self.MetaFile, Line=LineNo)\r
1816 else:\r
1817 if self._BuildOptions == None:\r
1818 self._BuildOptions = sdict()\r
1819\r
1820 if ToolList[0] in self._TOOL_CODE_:\r
1821 Tool = self._TOOL_CODE_[ToolList[0]]\r
1822 else:\r
1823 Tool = ToolList[0]\r
1824 ToolChain = "*_*_*_%s_FLAGS" % Tool\r
f51461c8 1825 ToolChainFamily = 'MSFT' # Edk.x only support MSFT tool chain\r
52302d4d 1826 #ignore not replaced macros in value\r
0d2711a6 1827 ValueList = GetSplitList(' ' + Value, '/D')\r
52302d4d
LG
1828 Dummy = ValueList[0]\r
1829 for Index in range(1, len(ValueList)):\r
1830 if ValueList[Index][-1] == '=' or ValueList[Index] == '':\r
1831 continue\r
1832 Dummy = Dummy + ' /D ' + ValueList[Index]\r
1833 Value = Dummy.strip()\r
1834 if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
1835 self._BuildOptions[ToolChainFamily, ToolChain] = Value\r
1836 else:\r
1837 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
1838 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value\r
1839 # set _Header to non-None in order to avoid database re-querying\r
1840 self._Header_ = 'DUMMY'\r
1841\r
1842 ## Retrieve file version\r
1843 def _GetInfVersion(self):\r
1844 if self._AutoGenVersion == None:\r
0d2711a6
LG
1845 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
1846 for Record in RecordList:\r
1847 if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
1848 self._AutoGenVersion = int(Record[2], 0)\r
1849 break\r
52302d4d
LG
1850 if self._AutoGenVersion == None:\r
1851 self._AutoGenVersion = 0x00010000\r
1852 return self._AutoGenVersion\r
1853\r
1854 ## Retrieve BASE_NAME\r
1855 def _GetBaseName(self):\r
1856 if self._BaseName == None:\r
1857 if self._Header_ == None:\r
1858 self._GetHeaderInfo()\r
1859 if self._BaseName == None:\r
1860 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)\r
1861 return self._BaseName\r
1862\r
b36d134f
LG
1863 ## Retrieve DxsFile\r
1864 def _GetDxsFile(self):\r
1865 if self._DxsFile == None:\r
1866 if self._Header_ == None:\r
1867 self._GetHeaderInfo()\r
1868 if self._DxsFile == None:\r
1869 self._DxsFile = ''\r
1870 return self._DxsFile\r
1871\r
52302d4d
LG
1872 ## Retrieve MODULE_TYPE\r
1873 def _GetModuleType(self):\r
1874 if self._ModuleType == None:\r
1875 if self._Header_ == None:\r
1876 self._GetHeaderInfo()\r
1877 if self._ModuleType == None:\r
1878 self._ModuleType = 'BASE'\r
1879 if self._ModuleType not in SUP_MODULE_LIST:\r
1880 self._ModuleType = "USER_DEFINED"\r
1881 return self._ModuleType\r
1882\r
1883 ## Retrieve COMPONENT_TYPE\r
1884 def _GetComponentType(self):\r
1885 if self._ComponentType == None:\r
1886 if self._Header_ == None:\r
1887 self._GetHeaderInfo()\r
1888 if self._ComponentType == None:\r
1889 self._ComponentType = 'USER_DEFINED'\r
1890 return self._ComponentType\r
1891\r
1892 ## Retrieve "BUILD_TYPE"\r
1893 def _GetBuildType(self):\r
1894 if self._BuildType == None:\r
1895 if self._Header_ == None:\r
1896 self._GetHeaderInfo()\r
1897 if not self._BuildType:\r
1898 self._BuildType = "BASE"\r
1899 return self._BuildType\r
1900\r
1901 ## Retrieve file guid\r
1902 def _GetFileGuid(self):\r
1903 if self._Guid == None:\r
1904 if self._Header_ == None:\r
1905 self._GetHeaderInfo()\r
1906 if self._Guid == None:\r
1907 self._Guid = '00000000-0000-0000-000000000000'\r
1908 return self._Guid\r
1909\r
1910 ## Retrieve module version\r
1911 def _GetVersion(self):\r
1912 if self._Version == None:\r
1913 if self._Header_ == None:\r
1914 self._GetHeaderInfo()\r
1915 if self._Version == None:\r
1916 self._Version = '0.0'\r
1917 return self._Version\r
1918\r
1919 ## Retrieve PCD_IS_DRIVER\r
1920 def _GetPcdIsDriver(self):\r
1921 if self._PcdIsDriver == None:\r
1922 if self._Header_ == None:\r
1923 self._GetHeaderInfo()\r
1924 if self._PcdIsDriver == None:\r
1925 self._PcdIsDriver = ''\r
1926 return self._PcdIsDriver\r
1927\r
1928 ## Retrieve SHADOW\r
1929 def _GetShadow(self):\r
1930 if self._Shadow == None:\r
1931 if self._Header_ == None:\r
1932 self._GetHeaderInfo()\r
1933 if self._Shadow != None and self._Shadow.upper() == 'TRUE':\r
1934 self._Shadow = True\r
1935 else:\r
1936 self._Shadow = False\r
1937 return self._Shadow\r
1938\r
1939 ## Retrieve CUSTOM_MAKEFILE\r
1940 def _GetMakefile(self):\r
1941 if self._CustomMakefile == None:\r
1942 if self._Header_ == None:\r
1943 self._GetHeaderInfo()\r
1944 if self._CustomMakefile == None:\r
1945 self._CustomMakefile = {}\r
1946 return self._CustomMakefile\r
1947\r
1948 ## Retrieve EFI_SPECIFICATION_VERSION\r
1949 def _GetSpec(self):\r
1950 if self._Specification == None:\r
1951 if self._Header_ == None:\r
1952 self._GetHeaderInfo()\r
1953 if self._Specification == None:\r
1954 self._Specification = {}\r
1955 return self._Specification\r
1956\r
1957 ## Retrieve LIBRARY_CLASS\r
1958 def _GetLibraryClass(self):\r
1959 if self._LibraryClass == None:\r
1960 if self._Header_ == None:\r
1961 self._GetHeaderInfo()\r
1962 if self._LibraryClass == None:\r
1963 self._LibraryClass = []\r
1964 return self._LibraryClass\r
1965\r
1966 ## Retrieve ENTRY_POINT\r
1967 def _GetEntryPoint(self):\r
1968 if self._ModuleEntryPointList == None:\r
1969 if self._Header_ == None:\r
1970 self._GetHeaderInfo()\r
1971 if self._ModuleEntryPointList == None:\r
1972 self._ModuleEntryPointList = []\r
1973 return self._ModuleEntryPointList\r
1974\r
1975 ## Retrieve UNLOAD_IMAGE\r
1976 def _GetUnloadImage(self):\r
1977 if self._ModuleUnloadImageList == None:\r
1978 if self._Header_ == None:\r
1979 self._GetHeaderInfo()\r
1980 if self._ModuleUnloadImageList == None:\r
1981 self._ModuleUnloadImageList = []\r
1982 return self._ModuleUnloadImageList\r
1983\r
1984 ## Retrieve CONSTRUCTOR\r
1985 def _GetConstructor(self):\r
1986 if self._ConstructorList == None:\r
1987 if self._Header_ == None:\r
1988 self._GetHeaderInfo()\r
1989 if self._ConstructorList == None:\r
1990 self._ConstructorList = []\r
1991 return self._ConstructorList\r
1992\r
1993 ## Retrieve DESTRUCTOR\r
1994 def _GetDestructor(self):\r
1995 if self._DestructorList == None:\r
1996 if self._Header_ == None:\r
1997 self._GetHeaderInfo()\r
1998 if self._DestructorList == None:\r
1999 self._DestructorList = []\r
2000 return self._DestructorList\r
2001\r
2002 ## Retrieve definies other than above ones\r
2003 def _GetDefines(self):\r
2004 if self._Defs == None:\r
2005 if self._Header_ == None:\r
2006 self._GetHeaderInfo()\r
2007 if self._Defs == None:\r
2008 self._Defs = sdict()\r
2009 return self._Defs\r
2010\r
2011 ## Retrieve binary files\r
2012 def _GetBinaryFiles(self):\r
2013 if self._Binaries == None:\r
2014 self._Binaries = []\r
2015 RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
0d2711a6
LG
2016 Macros = self._Macros\r
2017 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
2018 Macros['PROCESSOR'] = self._Arch\r
52302d4d 2019 for Record in RecordList:\r
52302d4d
LG
2020 FileType = Record[0]\r
2021 LineNo = Record[-1]\r
2022 Target = 'COMMON'\r
2023 FeatureFlag = []\r
2024 if Record[2]:\r
2025 TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
2026 if TokenList:\r
2027 Target = TokenList[0]\r
2028 if len(TokenList) > 1:\r
2029 FeatureFlag = Record[1:]\r
2030\r
2031 File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)\r
2032 # check the file validation\r
2033 ErrorCode, ErrorInfo = File.Validate()\r
2034 if ErrorCode != 0:\r
2035 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
2036 self._Binaries.append(File)\r
2037 return self._Binaries\r
2038\r
2039 ## Retrieve source files\r
2040 def _GetSourceFiles(self):\r
2041 if self._Sources == None:\r
2042 self._Sources = []\r
2043 RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
0d2711a6 2044 Macros = self._Macros\r
52302d4d 2045 for Record in RecordList:\r
52302d4d
LG
2046 LineNo = Record[-1]\r
2047 ToolChainFamily = Record[1]\r
2048 TagName = Record[2]\r
2049 ToolCode = Record[3]\r
2050 FeatureFlag = Record[4]\r
0d2711a6 2051 if self.AutoGenVersion < 0x00010005:\r
d0acc87a
LG
2052 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
2053 Macros['PROCESSOR'] = self._Arch\r
0d2711a6 2054 # old module source files (Edk)\r
52302d4d
LG
2055 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath,\r
2056 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
2057 # check the file validation\r
2058 ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
2059 if ErrorCode != 0:\r
2060 if File.Ext.lower() == '.h':\r
2061 EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,\r
2062 File=self.MetaFile, Line=LineNo)\r
2063 continue\r
2064 else:\r
2065 EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)\r
2066 else:\r
2067 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',\r
2068 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
2069 # check the file validation\r
2070 ErrorCode, ErrorInfo = File.Validate()\r
2071 if ErrorCode != 0:\r
2072 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
2073\r
2074 self._Sources.append(File)\r
2075 return self._Sources\r
2076\r
2077 ## Retrieve library classes employed by this module\r
2078 def _GetLibraryClassUses(self):\r
2079 if self._LibraryClasses == None:\r
2080 self._LibraryClasses = sdict()\r
2081 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
2082 for Record in RecordList:\r
52302d4d
LG
2083 Lib = Record[0]\r
2084 Instance = Record[1]\r
0d2711a6 2085 if Instance:\r
52302d4d
LG
2086 Instance = NormPath(Instance, self._Macros)\r
2087 self._LibraryClasses[Lib] = Instance\r
2088 return self._LibraryClasses\r
2089\r
0d2711a6 2090 ## Retrieve library names (for Edk.x style of modules)\r
52302d4d
LG
2091 def _GetLibraryNames(self):\r
2092 if self._Libraries == None:\r
2093 self._Libraries = []\r
2094 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
2095 for Record in RecordList:\r
0d2711a6
LG
2096 LibraryName = ReplaceMacro(Record[0], self._Macros, False)\r
2097 # in case of name with '.lib' extension, which is unusual in Edk.x inf\r
2098 LibraryName = os.path.splitext(LibraryName)[0]\r
52302d4d
LG
2099 if LibraryName not in self._Libraries:\r
2100 self._Libraries.append(LibraryName)\r
2101 return self._Libraries\r
2102\r
e8a47801
LG
2103 def _GetProtocolComments(self):\r
2104 self._GetProtocols()\r
2105 return self._ProtocolComments\r
52302d4d
LG
2106 ## Retrieve protocols consumed/produced by this module\r
2107 def _GetProtocols(self):\r
2108 if self._Protocols == None:\r
2109 self._Protocols = sdict()\r
e8a47801 2110 self._ProtocolComments = sdict()\r
52302d4d
LG
2111 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
2112 for Record in RecordList:\r
2113 CName = Record[0]\r
2114 Value = ProtocolValue(CName, self.Packages)\r
2115 if Value == None:\r
2116 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2117 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2118 "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
2119 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2120 self._Protocols[CName] = Value\r
e8a47801
LG
2121 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
2122 Comments = []\r
2123 for CmtRec in CommentRecords:\r
2124 Comments.append(CmtRec[0])\r
2125 self._ProtocolComments[CName] = Comments\r
52302d4d
LG
2126 return self._Protocols\r
2127\r
e8a47801
LG
2128 def _GetPpiComments(self):\r
2129 self._GetPpis()\r
2130 return self._PpiComments\r
52302d4d
LG
2131 ## Retrieve PPIs consumed/produced by this module\r
2132 def _GetPpis(self):\r
2133 if self._Ppis == None:\r
2134 self._Ppis = sdict()\r
e8a47801 2135 self._PpiComments = sdict()\r
52302d4d
LG
2136 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
2137 for Record in RecordList:\r
2138 CName = Record[0]\r
2139 Value = PpiValue(CName, self.Packages)\r
2140 if Value == None:\r
2141 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2142 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2143 "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
2144 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2145 self._Ppis[CName] = Value\r
e8a47801
LG
2146 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
2147 Comments = []\r
2148 for CmtRec in CommentRecords:\r
2149 Comments.append(CmtRec[0])\r
2150 self._PpiComments[CName] = Comments\r
52302d4d
LG
2151 return self._Ppis\r
2152\r
e8a47801
LG
2153 def _GetGuidComments(self):\r
2154 self._GetGuids()\r
2155 return self._GuidComments\r
52302d4d
LG
2156 ## Retrieve GUIDs consumed/produced by this module\r
2157 def _GetGuids(self):\r
2158 if self._Guids == None:\r
2159 self._Guids = sdict()\r
e8a47801 2160 self._GuidComments = sdict()\r
52302d4d
LG
2161 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
2162 for Record in RecordList:\r
2163 CName = Record[0]\r
2164 Value = GuidValue(CName, self.Packages)\r
2165 if Value == None:\r
2166 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2167 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2168 "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
2169 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2170 self._Guids[CName] = Value\r
e8a47801
LG
2171 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
2172 Comments = []\r
2173 for CmtRec in CommentRecords:\r
2174 Comments.append(CmtRec[0])\r
2175 self._GuidComments[CName] = Comments\r
52302d4d
LG
2176 return self._Guids\r
2177\r
0d2711a6 2178 ## Retrieve include paths necessary for this module (for Edk.x style of modules)\r
52302d4d
LG
2179 def _GetIncludes(self):\r
2180 if self._Includes == None:\r
2181 self._Includes = []\r
2182 if self._SourceOverridePath:\r
2183 self._Includes.append(self._SourceOverridePath)\r
0d2711a6
LG
2184\r
2185 Macros = self._Macros\r
2186 if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():\r
2187 Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']\r
2188 else:\r
2189 Macros['PROCESSOR'] = self._Arch\r
52302d4d 2190 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
52302d4d 2191 for Record in RecordList:\r
52302d4d 2192 if Record[0].find('EDK_SOURCE') > -1:\r
0d2711a6
LG
2193 Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
2194 File = NormPath(Record[0], self._Macros)\r
52302d4d
LG
2195 if File[0] == '.':\r
2196 File = os.path.join(self._ModuleDir, File)\r
2197 else:\r
2198 File = os.path.join(GlobalData.gWorkspace, File)\r
2199 File = RealPath(os.path.normpath(File))\r
2200 if File:\r
2201 self._Includes.append(File)\r
2202\r
2203 #TRICK: let compiler to choose correct header file\r
0d2711a6
LG
2204 Macros['EDK_SOURCE'] = GlobalData.gEdkSource\r
2205 File = NormPath(Record[0], self._Macros)\r
52302d4d
LG
2206 if File[0] == '.':\r
2207 File = os.path.join(self._ModuleDir, File)\r
2208 else:\r
2209 File = os.path.join(GlobalData.gWorkspace, File)\r
2210 File = RealPath(os.path.normpath(File))\r
2211 if File:\r
2212 self._Includes.append(File)\r
2213 else:\r
0d2711a6 2214 File = NormPath(Record[0], Macros)\r
52302d4d
LG
2215 if File[0] == '.':\r
2216 File = os.path.join(self._ModuleDir, File)\r
2217 else:\r
2218 File = os.path.join(GlobalData.gWorkspace, File)\r
2219 File = RealPath(os.path.normpath(File))\r
2220 if File:\r
2221 self._Includes.append(File)\r
2222 return self._Includes\r
2223\r
2224 ## Retrieve packages this module depends on\r
2225 def _GetPackages(self):\r
2226 if self._Packages == None:\r
2227 self._Packages = []\r
2228 RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
0d2711a6
LG
2229 Macros = self._Macros\r
2230 Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
52302d4d
LG
2231 for Record in RecordList:\r
2232 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
2233 LineNo = Record[-1]\r
2234 # check the file validation\r
2235 ErrorCode, ErrorInfo = File.Validate('.dec')\r
2236 if ErrorCode != 0:\r
2237 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
2238 # parse this package now. we need it to get protocol/ppi/guid value\r
0d2711a6 2239 Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
52302d4d
LG
2240 self._Packages.append(Package)\r
2241 return self._Packages\r
2242\r
e8a47801
LG
2243 ## Retrieve PCD comments\r
2244 def _GetPcdComments(self):\r
2245 self._GetPcds()\r
2246 return self._PcdComments\r
52302d4d
LG
2247 ## Retrieve PCDs used in this module\r
2248 def _GetPcds(self):\r
2249 if self._Pcds == None:\r
79b74a03 2250 self._Pcds = sdict()\r
e8a47801 2251 self._PcdComments = sdict()\r
52302d4d
LG
2252 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
2253 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
2254 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
2255 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
2256 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
2257 return self._Pcds\r
2258\r
2259 ## Retrieve build options specific to this module\r
2260 def _GetBuildOptions(self):\r
2261 if self._BuildOptions == None:\r
2262 self._BuildOptions = sdict()\r
2263 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]\r
2264 for Record in RecordList:\r
2265 ToolChainFamily = Record[0]\r
2266 ToolChain = Record[1]\r
2267 Option = Record[2]\r
2268 if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
2269 self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
2270 else:\r
2271 # concatenate the option string if they're for the same tool\r
2272 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
2273 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
2274 return self._BuildOptions\r
2275\r
0d2711a6 2276 ## Retrieve dependency expression\r
52302d4d
LG
2277 def _GetDepex(self):\r
2278 if self._Depex == None:\r
2279 self._Depex = tdict(False, 2)\r
2280 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
da92f276
LG
2281 \r
2282 # If the module has only Binaries and no Sources, then ignore [Depex] \r
2283 if self.Sources == None or self.Sources == []:\r
0d2711a6
LG
2284 if self.Binaries != None and self.Binaries != []:\r
2285 return self._Depex\r
da92f276 2286 \r
52302d4d
LG
2287 # PEIM and DXE drivers must have a valid [Depex] section\r
2288 if len(self.LibraryClass) == 0 and len(RecordList) == 0:\r
2289 if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \\r
2290 self.ModuleType == 'DXE_SAL_DRIVER' or self.ModuleType == 'DXE_RUNTIME_DRIVER':\r
2291 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
2292 % self.ModuleType, File=self.MetaFile)\r
2293\r
0d2711a6 2294 Depex = sdict()\r
52302d4d 2295 for Record in RecordList:\r
0d2711a6 2296 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
52302d4d
LG
2297 Arch = Record[3]\r
2298 ModuleType = Record[4]\r
0d2711a6 2299 TokenList = DepexStr.split()\r
52302d4d
LG
2300 if (Arch, ModuleType) not in Depex:\r
2301 Depex[Arch, ModuleType] = []\r
2302 DepexList = Depex[Arch, ModuleType]\r
2303 for Token in TokenList:\r
2304 if Token in DEPEX_SUPPORTED_OPCODE:\r
2305 DepexList.append(Token)\r
2306 elif Token.endswith(".inf"): # module file name\r
2307 ModuleFile = os.path.normpath(Token)\r
2308 Module = self.BuildDatabase[ModuleFile]\r
2309 if Module == None:\r
2310 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",\r
2311 ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
2312 DepexList.append(Module.Guid)\r
2313 else:\r
2314 # get the GUID value now\r
2315 Value = ProtocolValue(Token, self.Packages)\r
2316 if Value == None:\r
2317 Value = PpiValue(Token, self.Packages)\r
2318 if Value == None:\r
2319 Value = GuidValue(Token, self.Packages)\r
2320 if Value == None:\r
2321 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2322 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2323 "Value of [%s] is not found in" % Token,\r
2324 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2325 DepexList.append(Value)\r
2326 for Arch, ModuleType in Depex:\r
2327 self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]\r
2328 return self._Depex\r
2329\r
2330 ## Retrieve depedency expression\r
2331 def _GetDepexExpression(self):\r
2332 if self._DepexExpression == None:\r
2333 self._DepexExpression = tdict(False, 2)\r
2334 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
0d2711a6 2335 DepexExpression = sdict()\r
52302d4d 2336 for Record in RecordList:\r
0d2711a6 2337 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
52302d4d
LG
2338 Arch = Record[3]\r
2339 ModuleType = Record[4]\r
0d2711a6 2340 TokenList = DepexStr.split()\r
52302d4d
LG
2341 if (Arch, ModuleType) not in DepexExpression:\r
2342 DepexExpression[Arch, ModuleType] = ''\r
2343 for Token in TokenList:\r
2344 DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '\r
2345 for Arch, ModuleType in DepexExpression:\r
2346 self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]\r
2347 return self._DepexExpression\r
2348\r
e8a47801
LG
2349 def GetGuidsUsedByPcd(self):\r
2350 return self._GuidsUsedByPcd\r
52302d4d
LG
2351 ## Retrieve PCD for given type\r
2352 def _GetPcd(self, Type):\r
79b74a03 2353 Pcds = sdict()\r
52302d4d 2354 PcdDict = tdict(True, 4)\r
6780eef1 2355 PcdList = []\r
52302d4d 2356 RecordList = self._RawData[Type, self._Arch, self._Platform]\r
e8a47801 2357 for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:\r
52302d4d 2358 PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)\r
6780eef1 2359 PcdList.append((PcdCName, TokenSpaceGuid))\r
52302d4d
LG
2360 # get the guid value\r
2361 if TokenSpaceGuid not in self.Guids:\r
2362 Value = GuidValue(TokenSpaceGuid, self.Packages)\r
2363 if Value == None:\r
2364 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2365 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2366 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,\r
2367 ExtraData=PackageList, File=self.MetaFile, Line=LineNo)\r
2368 self.Guids[TokenSpaceGuid] = Value\r
e8a47801
LG
2369 self._GuidsUsedByPcd[TokenSpaceGuid] = Value\r
2370 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]\r
2371 Comments = []\r
2372 for CmtRec in CommentRecords:\r
2373 Comments.append(CmtRec[0])\r
2374 self._PcdComments[TokenSpaceGuid, PcdCName] = Comments\r
52302d4d
LG
2375\r
2376 # resolve PCD type, value, datum info, etc. by getting its definition from package\r
6780eef1 2377 for PcdCName, TokenSpaceGuid in PcdList:\r
52302d4d
LG
2378 Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
2379 if Setting == None:\r
2380 continue\r
6780eef1 2381 ValueList = AnalyzePcdData(Setting)\r
52302d4d
LG
2382 DefaultValue = ValueList[0]\r
2383 Pcd = PcdClassObject(\r
2384 PcdCName,\r
2385 TokenSpaceGuid,\r
2386 '',\r
2387 '',\r
2388 DefaultValue,\r
2389 '',\r
2390 '',\r
2391 {},\r
e56468c0 2392 False,\r
52302d4d
LG
2393 self.Guids[TokenSpaceGuid]\r
2394 )\r
e8a47801
LG
2395 if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:\r
2396 # Patch PCD: TokenSpace.PcdCName|Value|Offset\r
2397 Pcd.Offset = ValueList[1]\r
52302d4d
LG
2398\r
2399 # get necessary info from package declaring this PCD\r
2400 for Package in self.Packages:\r
2401 #\r
2402 # 'dynamic' in INF means its type is determined by platform;\r
2403 # if platform doesn't give its type, use 'lowest' one in the\r
2404 # following order, if any\r
2405 #\r
2406 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"\r
2407 #\r
2408 PcdType = self._PCD_TYPE_STRING_[Type]\r
e56468c0 2409 if Type == MODEL_PCD_DYNAMIC:\r
52302d4d
LG
2410 Pcd.Pending = True\r
2411 for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
2412 if (PcdCName, TokenSpaceGuid, T) in Package.Pcds:\r
2413 PcdType = T\r
2414 break\r
2415 else:\r
2416 Pcd.Pending = False\r
2417\r
2418 if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
2419 PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]\r
2420 Pcd.Type = PcdType\r
2421 Pcd.TokenValue = PcdInPackage.TokenValue\r
6780eef1
LG
2422 \r
2423 #\r
2424 # Check whether the token value exist or not.\r
2425 #\r
2426 if Pcd.TokenValue == None or Pcd.TokenValue == "":\r
2427 EdkLogger.error(\r
2428 'build',\r
2429 FORMAT_INVALID,\r
2430 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdCName, str(Package)),\r
2431 File =self.MetaFile, Line=LineNo,\r
2432 ExtraData=None\r
2433 ) \r
2434 #\r
2435 # Check hexadecimal token value length and format.\r
2436 #\r
79b74a03 2437 ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)\r
6780eef1 2438 if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):\r
79b74a03 2439 if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:\r
6780eef1
LG
2440 EdkLogger.error(\r
2441 'build',\r
2442 FORMAT_INVALID,\r
2443 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
2444 File =self.MetaFile, Line=LineNo,\r
2445 ExtraData=None\r
2446 )\r
2447 \r
2448 #\r
2449 # Check decimal token value length and format.\r
2450 # \r
2451 else:\r
2452 try:\r
2453 TokenValueInt = int (Pcd.TokenValue, 10)\r
2454 if (TokenValueInt < 0 or TokenValueInt > 4294967295):\r
2455 EdkLogger.error(\r
2456 'build',\r
2457 FORMAT_INVALID,\r
2458 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!"% (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
2459 File =self.MetaFile, Line=LineNo,\r
2460 ExtraData=None\r
2461 ) \r
2462 except:\r
2463 EdkLogger.error(\r
2464 'build',\r
2465 FORMAT_INVALID,\r
2466 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!"% (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
2467 File =self.MetaFile, Line=LineNo,\r
2468 ExtraData=None\r
2469 )\r
2470 \r
52302d4d
LG
2471 Pcd.DatumType = PcdInPackage.DatumType\r
2472 Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
2473 Pcd.InfDefaultValue = Pcd.DefaultValue\r
2474 if Pcd.DefaultValue in [None, '']:\r
2475 Pcd.DefaultValue = PcdInPackage.DefaultValue\r
2476 break\r
2477 else:\r
2478 EdkLogger.error(\r
2479 'build',\r
6780eef1 2480 FORMAT_INVALID,\r
52302d4d
LG
2481 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),\r
2482 File =self.MetaFile, Line=LineNo,\r
2483 ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])\r
2484 )\r
2485 Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
6780eef1 2486\r
52302d4d
LG
2487 return Pcds\r
2488\r
e8a47801
LG
2489 ## check whether current module is binary module\r
2490 def _IsBinaryModule(self):\r
2491 if self.Binaries and not self.Sources:\r
2492 return True\r
2493 elif GlobalData.gIgnoreSource:\r
2494 return True\r
2495 else:\r
2496 return False\r
2497\r
2498 _Macros = property(_GetMacros)\r
2499 Arch = property(_GetArch, _SetArch)\r
2500 Platform = property(_GetPlatform, _SetPlatform)\r
52302d4d 2501\r
e8a47801 2502 HeaderComments = property(_GetHeaderComments)\r
2bc3256c 2503 TailComments = property(_GetTailComments)\r
52302d4d
LG
2504 AutoGenVersion = property(_GetInfVersion)\r
2505 BaseName = property(_GetBaseName)\r
2506 ModuleType = property(_GetModuleType)\r
2507 ComponentType = property(_GetComponentType)\r
2508 BuildType = property(_GetBuildType)\r
2509 Guid = property(_GetFileGuid)\r
2510 Version = property(_GetVersion)\r
2511 PcdIsDriver = property(_GetPcdIsDriver)\r
2512 Shadow = property(_GetShadow)\r
2513 CustomMakefile = property(_GetMakefile)\r
2514 Specification = property(_GetSpec)\r
2515 LibraryClass = property(_GetLibraryClass)\r
2516 ModuleEntryPointList = property(_GetEntryPoint)\r
2517 ModuleUnloadImageList = property(_GetUnloadImage)\r
2518 ConstructorList = property(_GetConstructor)\r
2519 DestructorList = property(_GetDestructor)\r
2520 Defines = property(_GetDefines)\r
b36d134f
LG
2521 DxsFile = property(_GetDxsFile)\r
2522 \r
52302d4d
LG
2523 Binaries = property(_GetBinaryFiles)\r
2524 Sources = property(_GetSourceFiles)\r
2525 LibraryClasses = property(_GetLibraryClassUses)\r
2526 Libraries = property(_GetLibraryNames)\r
2527 Protocols = property(_GetProtocols)\r
e8a47801 2528 ProtocolComments = property(_GetProtocolComments)\r
52302d4d 2529 Ppis = property(_GetPpis)\r
e8a47801 2530 PpiComments = property(_GetPpiComments)\r
52302d4d 2531 Guids = property(_GetGuids)\r
e8a47801 2532 GuidComments = property(_GetGuidComments)\r
52302d4d
LG
2533 Includes = property(_GetIncludes)\r
2534 Packages = property(_GetPackages)\r
2535 Pcds = property(_GetPcds)\r
e8a47801 2536 PcdComments = property(_GetPcdComments)\r
52302d4d
LG
2537 BuildOptions = property(_GetBuildOptions)\r
2538 Depex = property(_GetDepex)\r
2539 DepexExpression = property(_GetDepexExpression)\r
e8a47801 2540 IsBinaryModule = property(_IsBinaryModule)\r
52302d4d
LG
2541\r
2542## Database\r
2543#\r
e56468c0 2544# This class defined the build database for all modules, packages and platform.\r
52302d4d
LG
2545# It will call corresponding parser for the given file if it cannot find it in\r
2546# the database.\r
2547#\r
2548# @param DbPath Path of database file\r
2549# @param GlobalMacros Global macros used for replacement during file parsing\r
2550# @prarm RenewDb=False Create new database file if it's already there\r
2551#\r
2552class WorkspaceDatabase(object):\r
52302d4d
LG
2553\r
2554 # default database file path\r
2555 _DB_PATH_ = "Conf/.cache/build.db"\r
2556\r
2557 #\r
2558 # internal class used for call corresponding file parser and caching the result\r
2559 # to avoid unnecessary re-parsing\r
2560 #\r
2561 class BuildObjectFactory(object):\r
0d2711a6 2562\r
52302d4d
LG
2563 _FILE_TYPE_ = {\r
2564 ".inf" : MODEL_FILE_INF,\r
2565 ".dec" : MODEL_FILE_DEC,\r
2566 ".dsc" : MODEL_FILE_DSC,\r
0d2711a6
LG
2567 }\r
2568\r
2569 # file parser\r
2570 _FILE_PARSER_ = {\r
2571 MODEL_FILE_INF : InfParser,\r
2572 MODEL_FILE_DEC : DecParser,\r
2573 MODEL_FILE_DSC : DscParser,\r
52302d4d
LG
2574 }\r
2575\r
2576 # convert to xxxBuildData object\r
2577 _GENERATOR_ = {\r
2578 MODEL_FILE_INF : InfBuildData,\r
2579 MODEL_FILE_DEC : DecBuildData,\r
2580 MODEL_FILE_DSC : DscBuildData,\r
52302d4d
LG
2581 }\r
2582\r
2583 _CACHE_ = {} # (FilePath, Arch) : <object>\r
2584\r
2585 # constructor\r
2586 def __init__(self, WorkspaceDb):\r
2587 self.WorkspaceDb = WorkspaceDb\r
2588\r
0d2711a6 2589 # key = (FilePath, Arch=None)\r
52302d4d
LG
2590 def __contains__(self, Key):\r
2591 FilePath = Key[0]\r
52302d4d
LG
2592 if len(Key) > 1:\r
2593 Arch = Key[1]\r
0d2711a6
LG
2594 else:\r
2595 Arch = None\r
52302d4d
LG
2596 return (FilePath, Arch) in self._CACHE_\r
2597\r
0d2711a6 2598 # key = (FilePath, Arch=None, Target=None, Toochain=None)\r
52302d4d
LG
2599 def __getitem__(self, Key):\r
2600 FilePath = Key[0]\r
0d2711a6
LG
2601 KeyLength = len(Key)\r
2602 if KeyLength > 1:\r
52302d4d 2603 Arch = Key[1]\r
0d2711a6
LG
2604 else:\r
2605 Arch = None\r
2606 if KeyLength > 2:\r
2607 Target = Key[2]\r
2608 else:\r
2609 Target = None\r
2610 if KeyLength > 3:\r
2611 Toolchain = Key[3]\r
2612 else:\r
2613 Toolchain = None\r
52302d4d
LG
2614\r
2615 # if it's generated before, just return the cached one\r
0d2711a6 2616 Key = (FilePath, Arch, Target, Toolchain)\r
52302d4d
LG
2617 if Key in self._CACHE_:\r
2618 return self._CACHE_[Key]\r
2619\r
2620 # check file type\r
0d2711a6 2621 Ext = FilePath.Type\r
52302d4d
LG
2622 if Ext not in self._FILE_TYPE_:\r
2623 return None\r
2624 FileType = self._FILE_TYPE_[Ext]\r
2625 if FileType not in self._GENERATOR_:\r
2626 return None\r
2627\r
0d2711a6
LG
2628 # get the parser ready for this file\r
2629 MetaFile = self._FILE_PARSER_[FileType](\r
2630 FilePath, \r
2631 FileType, \r
2632 MetaFileStorage(self.WorkspaceDb.Cur, FilePath, FileType)\r
2633 )\r
2634 # alwasy do post-process, in case of macros change\r
2635 MetaFile.DoPostProcess()\r
2636 # object the build is based on\r
52302d4d
LG
2637 BuildObject = self._GENERATOR_[FileType](\r
2638 FilePath,\r
2639 MetaFile,\r
2640 self,\r
2641 Arch,\r
0d2711a6
LG
2642 Target,\r
2643 Toolchain\r
52302d4d
LG
2644 )\r
2645 self._CACHE_[Key] = BuildObject\r
2646 return BuildObject\r
2647\r
2648 # placeholder for file format conversion\r
2649 class TransformObjectFactory:\r
2650 def __init__(self, WorkspaceDb):\r
2651 self.WorkspaceDb = WorkspaceDb\r
2652\r
2653 # key = FilePath, Arch\r
2654 def __getitem__(self, Key):\r
2655 pass\r
2656\r
2657 ## Constructor of WorkspaceDatabase\r
2658 #\r
2659 # @param DbPath Path of database file\r
2660 # @param GlobalMacros Global macros used for replacement during file parsing\r
2661 # @prarm RenewDb=False Create new database file if it's already there\r
2662 #\r
0d2711a6 2663 def __init__(self, DbPath, RenewDb=False):\r
4234283c 2664 self._DbClosedFlag = False\r
0d2711a6 2665 if not DbPath:\r
52302d4d
LG
2666 DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, self._DB_PATH_))\r
2667\r
2668 # don't create necessary path for db in memory\r
2669 if DbPath != ':memory:':\r
2670 DbDir = os.path.split(DbPath)[0]\r
2671 if not os.path.exists(DbDir):\r
2672 os.makedirs(DbDir)\r
2673\r
2674 # remove db file in case inconsistency between db and file in file system\r
2675 if self._CheckWhetherDbNeedRenew(RenewDb, DbPath):\r
2676 os.remove(DbPath)\r
2677 \r
2678 # create db with optimized parameters\r
2679 self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED')\r
2680 self.Conn.execute("PRAGMA synchronous=OFF")\r
2681 self.Conn.execute("PRAGMA temp_store=MEMORY")\r
2682 self.Conn.execute("PRAGMA count_changes=OFF")\r
2683 self.Conn.execute("PRAGMA cache_size=8192")\r
2684 #self.Conn.execute("PRAGMA page_size=8192")\r
2685\r
2686 # to avoid non-ascii character conversion issue\r
2687 self.Conn.text_factory = str\r
2688 self.Cur = self.Conn.cursor()\r
2689\r
2690 # create table for internal uses\r
2691 self.TblDataModel = TableDataModel(self.Cur)\r
2692 self.TblFile = TableFile(self.Cur)\r
0d2711a6 2693 self.Platform = None\r
52302d4d
LG
2694\r
2695 # conversion object for build or file format conversion purpose\r
2696 self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)\r
2697 self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)\r
2698\r
2699 ## Check whether workspace database need to be renew.\r
2700 # The renew reason maybe:\r
2701 # 1) If user force to renew;\r
2702 # 2) If user do not force renew, and\r
2703 # a) If the time of last modified python source is newer than database file;\r
2704 # b) If the time of last modified frozen executable file is newer than database file;\r
2705 #\r
2706 # @param force User force renew database\r
2707 # @param DbPath The absolute path of workspace database file\r
2708 #\r
2709 # @return Bool value for whether need renew workspace databse\r
2710 #\r
2711 def _CheckWhetherDbNeedRenew (self, force, DbPath):\r
52302d4d
LG
2712 # if database does not exist, we need do nothing\r
2713 if not os.path.exists(DbPath): return False\r
2714 \r
2715 # if user force to renew database, then not check whether database is out of date\r
2716 if force: return True\r
2717 \r
2718 # \r
2719 # Check the time of last modified source file or build.exe\r
2720 # if is newer than time of database, then database need to be re-created.\r
2721 #\r
2722 timeOfToolModified = 0\r
2723 if hasattr(sys, "frozen"):\r
2724 exePath = os.path.abspath(sys.executable)\r
2725 timeOfToolModified = os.stat(exePath).st_mtime\r
2726 else:\r
2727 curPath = os.path.dirname(__file__) # curPath is the path of WorkspaceDatabase.py\r
2728 rootPath = os.path.split(curPath)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python\r
2729 if rootPath == "" or rootPath == None:\r
2730 EdkLogger.verbose("\nFail to find the root path of build.exe or python sources, so can not \\r
2731determine whether database file is out of date!\n")\r
2732 \r
2733 # walk the root path of source or build's binary to get the time last modified.\r
2734 \r
2735 for root, dirs, files in os.walk (rootPath):\r
2736 for dir in dirs:\r
2737 # bypass source control folder \r
2738 if dir.lower() in [".svn", "_svn", "cvs"]:\r
2739 dirs.remove(dir)\r
2740 \r
2741 for file in files:\r
2742 ext = os.path.splitext(file)[1]\r
2743 if ext.lower() == ".py": # only check .py files\r
2744 fd = os.stat(os.path.join(root, file))\r
2745 if timeOfToolModified < fd.st_mtime:\r
2746 timeOfToolModified = fd.st_mtime\r
2747 if timeOfToolModified > os.stat(DbPath).st_mtime:\r
2748 EdkLogger.verbose("\nWorkspace database is out of data!")\r
2749 return True\r
2750 \r
2751 return False\r
2752 \r
2753 ## Initialize build database\r
2754 def InitDatabase(self):\r
2755 EdkLogger.verbose("\nInitialize build database started ...")\r
2756\r
2757 #\r
2758 # Create new tables\r
2759 #\r
2760 self.TblDataModel.Create(False)\r
2761 self.TblFile.Create(False)\r
2762\r
2763 #\r
2764 # Initialize table DataModel\r
2765 #\r
2766 self.TblDataModel.InitTable()\r
2767 EdkLogger.verbose("Initialize build database ... DONE!")\r
2768\r
2769 ## Query a table\r
2770 #\r
2771 # @param Table: The instance of the table to be queried\r
2772 #\r
2773 def QueryTable(self, Table):\r
2774 Table.Query()\r
2775\r
0d2711a6
LG
2776 def __del__(self):\r
2777 self.Close()\r
2778\r
52302d4d
LG
2779 ## Close entire database\r
2780 #\r
2781 # Commit all first\r
2782 # Close the connection and cursor\r
2783 #\r
2784 def Close(self):\r
4234283c
LG
2785 if not self._DbClosedFlag:\r
2786 self.Conn.commit()\r
2787 self.Cur.close()\r
2788 self.Conn.close()\r
2789 self._DbClosedFlag = True\r
52302d4d 2790\r
52302d4d 2791 ## Summarize all packages in the database\r
0d2711a6
LG
2792 def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):\r
2793 self.Platform = Platform\r
2794 PackageList =[]\r
2795 Pa = self.BuildObject[self.Platform, 'COMMON']\r
2796 #\r
2797 # Get Package related to Modules\r
2798 #\r
2799 for Module in Pa.Modules:\r
2800 ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag]\r
2801 for Package in ModuleObj.Packages:\r
52302d4d
LG
2802 if Package not in PackageList:\r
2803 PackageList.append(Package)\r
0d2711a6
LG
2804 #\r
2805 # Get Packages related to Libraries\r
2806 #\r
2807 for Lib in Pa.LibraryInstances:\r
2808 LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]\r
2809 for Package in LibObj.Packages:\r
2810 if Package not in PackageList:\r
2811 PackageList.append(Package) \r
2812 \r
52302d4d
LG
2813 return PackageList\r
2814\r
2815 ## Summarize all platforms in the database\r
2816 def _GetPlatformList(self):\r
2817 PlatformList = []\r
2818 for PlatformFile in self.TblFile.GetFileList(MODEL_FILE_DSC):\r
2819 try:\r
2820 Platform = self.BuildObject[PathClass(PlatformFile), 'COMMON']\r
2821 except:\r
2822 Platform = None\r
2823 if Platform != None:\r
2824 PlatformList.append(Platform)\r
2825 return PlatformList\r
2826\r
52302d4d 2827 PlatformList = property(_GetPlatformList)\r
52302d4d
LG
2828\r
2829##\r
2830#\r
2831# This acts like the main() function for the script, unless it is 'import'ed into another\r
2832# script.\r
2833#\r
2834if __name__ == '__main__':\r
2835 pass\r
2836\r