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