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