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