]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
BaseTools: Fixed BuildOptions bug.
[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
0d2711a6 756 self._BuildOptions = sdict()\r
52302d4d 757 #\r
1ba5124e 758 # Retrieve build option for EDKII and EDK style module\r
52302d4d 759 #\r
1ba5124e
YL
760 for CodeBase in (EDKII_NAME, EDK_NAME):\r
761 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
762 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
763 CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
1ba5124e
YL
764 #\r
765 # Only flags can be appended\r
766 #\r
5015bee2 767 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
1ba5124e
YL
768 self._BuildOptions[CurKey] = Option\r
769 else:\r
770 self._BuildOptions[CurKey] += ' ' + Option\r
52302d4d
LG
771 return self._BuildOptions\r
772\r
35f69db9
YL
773 def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
774 if self._ModuleTypeOptions == None:\r
775 self._ModuleTypeOptions = sdict()\r
776 if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
777 options = sdict()\r
778 self._ModuleTypeOptions[Edk, ModuleType] = options\r
779 DriverType = '%s.%s' % (Edk, ModuleType)\r
780 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]\r
781 for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList:\r
5015bee2 782 if Type == DriverType:\r
1ba5124e 783 Key = (ToolChainFamily, ToolChain, Edk)\r
5015bee2 784 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
1ba5124e
YL
785 options[Key] = Option\r
786 else:\r
787 options[Key] += ' ' + Option\r
35f69db9
YL
788 return self._ModuleTypeOptions[Edk, ModuleType]\r
789\r
52302d4d
LG
790 ## Retrieve non-dynamic PCD settings\r
791 #\r
792 # @param Type PCD type\r
793 #\r
794 # @retval a dict object contains settings of given PCD type\r
795 #\r
796 def _GetPcd(self, Type):\r
0d2711a6 797 Pcds = sdict()\r
52302d4d
LG
798 #\r
799 # tdict is a special dict kind of type, used for selecting correct\r
800 # PCD settings for certain ARCH\r
801 #\r
e8a47801
LG
802 \r
803 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
804 \r
52302d4d
LG
805 PcdDict = tdict(True, 3)\r
806 PcdSet = set()\r
807 # Find out all possible PCD candidates for self._Arch\r
808 RecordList = self._RawData[Type, self._Arch]\r
e8a47801 809 PcdValueDict = sdict()\r
52302d4d 810 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
811 if SkuName in (SkuObj.SystemSkuId,'DEFAULT','COMMON'):\r
812 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
813 PcdDict[Arch, PcdCName, TokenSpaceGuid,SkuName] = Setting\r
814 \r
815 #handle pcd value override \r
816 for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdSet:\r
817 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid,SkuName]\r
52302d4d
LG
818 if Setting == None:\r
819 continue\r
4afd3d04 820 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
e8a47801
LG
821 if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
822 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue,DatumType,MaxDatumSize) \r
823 else:\r
824 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue,DatumType,MaxDatumSize)} \r
825 \r
826 PcdsKeys = PcdValueDict.keys()\r
827 for PcdCName,TokenSpaceGuid in PcdsKeys:\r
828 \r
829 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
830 PcdValue = None\r
831 DatumType = None\r
832 MaxDatumSize = None\r
833 if 'COMMON' in PcdSetting:\r
834 PcdValue,DatumType,MaxDatumSize = PcdSetting['COMMON']\r
835 if 'DEFAULT' in PcdSetting:\r
836 PcdValue,DatumType,MaxDatumSize = PcdSetting['DEFAULT']\r
837 if SkuObj.SystemSkuId in PcdSetting:\r
838 PcdValue,DatumType,MaxDatumSize = PcdSetting[SkuObj.SystemSkuId]\r
839 \r
52302d4d
LG
840 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
841 PcdCName,\r
842 TokenSpaceGuid,\r
843 self._PCD_TYPE_STRING_[Type],\r
844 DatumType,\r
845 PcdValue,\r
846 '',\r
847 MaxDatumSize,\r
848 {},\r
e56468c0 849 False,\r
52302d4d
LG
850 None\r
851 )\r
852 return Pcds\r
853\r
854 ## Retrieve dynamic PCD settings\r
855 #\r
856 # @param Type PCD type\r
857 #\r
858 # @retval a dict object contains settings of given PCD type\r
859 #\r
860 def _GetDynamicPcd(self, Type):\r
e8a47801
LG
861 \r
862 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
863 \r
0d2711a6 864 Pcds = sdict()\r
52302d4d
LG
865 #\r
866 # tdict is a special dict kind of type, used for selecting correct\r
867 # PCD settings for certain ARCH and SKU\r
868 #\r
869 PcdDict = tdict(True, 4)\r
6780eef1 870 PcdList = []\r
52302d4d
LG
871 # Find out all possible PCD candidates for self._Arch\r
872 RecordList = self._RawData[Type, self._Arch]\r
e8a47801
LG
873 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
874 \r
875 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
52302d4d 876 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
877 if SkuName not in AvailableSkuIdSet:\r
878 continue\r
879 \r
880 PcdList.append((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
52302d4d
LG
881 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
882 # Remove redundant PCD candidates, per the ARCH and SKU\r
e8a47801
LG
883 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
884 \r
885 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
52302d4d
LG
886 if Setting == None:\r
887 continue\r
6780eef1 888 \r
4afd3d04 889 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
e8a47801
LG
890 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue)\r
891 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
892 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
893 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2bc3256c
LG
894 if MaxDatumSize.strip():\r
895 CurrentMaxSize = int(MaxDatumSize.strip(),0)\r
896 else:\r
897 CurrentMaxSize = 0\r
898 if pcdObject.MaxDatumSize:\r
899 PcdMaxSize = int(pcdObject.MaxDatumSize,0)\r
900 else:\r
901 PcdMaxSize = 0\r
902 if CurrentMaxSize > PcdMaxSize:\r
903 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
e8a47801
LG
904 else: \r
905 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
906 PcdCName,\r
907 TokenSpaceGuid,\r
908 self._PCD_TYPE_STRING_[Type],\r
909 DatumType,\r
910 PcdValue,\r
911 '',\r
912 MaxDatumSize,\r
913 {SkuName : SkuInfo},\r
914 False,\r
915 None\r
916 )\r
917 \r
918 for pcd in Pcds.values():\r
2bc3256c
LG
919 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
920 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): \r
e8a47801
LG
921 valuefromDec = pcdDecObject.DefaultValue\r
922 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
923 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
924 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
925 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
926 del(pcd.SkuInfoList['COMMON'])\r
927 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
928 del(pcd.SkuInfoList['COMMON'])\r
929 if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
930 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
931 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
932 del(pcd.SkuInfoList['DEFAULT'])\r
2bc3256c 933 \r
52302d4d
LG
934 return Pcds\r
935\r
82a6a960
BF
936 def CompareVarAttr(self, Attr1, Attr2):\r
937 if not Attr1 or not Attr2: # for empty string\r
938 return True\r
939 Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
940 Attr1Set = set(Attr1s)\r
941 Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
942 Attr2Set = set(Attr2s)\r
943 if Attr2Set == Attr1Set:\r
944 return True\r
945 else:\r
946 return False\r
52302d4d
LG
947 ## Retrieve dynamic HII PCD settings\r
948 #\r
949 # @param Type PCD type\r
950 #\r
951 # @retval a dict object contains settings of given PCD type\r
952 #\r
953 def _GetDynamicHiiPcd(self, Type):\r
e8a47801
LG
954 \r
955 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
82a6a960 956 VariableAttrs = {}\r
e8a47801 957 \r
0d2711a6 958 Pcds = sdict()\r
52302d4d
LG
959 #\r
960 # tdict is a special dict kind of type, used for selecting correct\r
961 # PCD settings for certain ARCH and SKU\r
962 #\r
963 PcdDict = tdict(True, 4)\r
964 PcdSet = set()\r
965 RecordList = self._RawData[Type, self._Arch]\r
966 # Find out all possible PCD candidates for self._Arch\r
e8a47801
LG
967 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
968 \r
969 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
52302d4d 970 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
971 if SkuName not in AvailableSkuIdSet:\r
972 continue\r
973 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
52302d4d
LG
974 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
975 # Remove redundant PCD candidates, per the ARCH and SKU\r
e8a47801
LG
976 for PcdCName, TokenSpaceGuid,SkuName, Dummy4 in PcdSet:\r
977 \r
978 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
52302d4d
LG
979 if Setting == None:\r
980 continue\r
82a6a960 981 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
2bc3256c 982 \r
82a6a960
BF
983 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
984 if not rt:\r
985 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
986 ExtraData = "[%s]" % VarAttribute)\r
2bc3256c 987 ExceedMax = False\r
e4ac870f 988 FormatCorrect = True\r
2bc3256c
LG
989 if VariableOffset.isdigit():\r
990 if int(VariableOffset,10) > 0xFFFF:\r
991 ExceedMax = True\r
992 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset):\r
993 if int(VariableOffset,16) > 0xFFFF:\r
994 ExceedMax = True\r
e4ac870f
LG
995 # For Offset written in "A.B"\r
996 elif VariableOffset.find('.') > -1:\r
997 VariableOffsetList = VariableOffset.split(".")\r
998 if not (len(VariableOffsetList) == 2\r
999 and IsValidWord(VariableOffsetList[0])\r
1000 and IsValidWord(VariableOffsetList[1])):\r
1001 FormatCorrect = False\r
2bc3256c 1002 else:\r
e4ac870f
LG
1003 FormatCorrect = False\r
1004 if not FormatCorrect:\r
2bc3256c
LG
1005 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid,PcdCName)))\r
1006 \r
1007 if ExceedMax:\r
1008 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
1009 if (VariableName, VariableGuid) not in VariableAttrs:\r
1010 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
1011 else:\r
1012 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
1013 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 1014 \r
82a6a960
BF
1015 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute = VarAttribute)\r
1016 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
e8a47801
LG
1017 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
1018 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
1019 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
1020 else:\r
1021 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
52302d4d
LG
1022 PcdCName,\r
1023 TokenSpaceGuid,\r
1024 self._PCD_TYPE_STRING_[Type],\r
1025 '',\r
1026 DefaultValue,\r
1027 '',\r
1028 '',\r
e8a47801 1029 {SkuName : SkuInfo},\r
e56468c0 1030 False,\r
82a6a960
BF
1031 None,\r
1032 pcdDecObject.validateranges,\r
1033 pcdDecObject.validlists,\r
1034 pcdDecObject.expressions\r
52302d4d 1035 )\r
e8a47801
LG
1036 \r
1037\r
1038 for pcd in Pcds.values():\r
1039 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
2bc3256c
LG
1040 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
1041 # Only fix the value while no value provided in DSC file.\r
1042 for sku in pcd.SkuInfoList.values():\r
1043 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue==None):\r
1044 sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
1045 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): \r
e8a47801
LG
1046 valuefromDec = pcdDecObject.DefaultValue\r
1047 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)\r
1048 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1049 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1050 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1051 del(pcd.SkuInfoList['COMMON'])\r
1052 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1053 del(pcd.SkuInfoList['COMMON'])\r
1054 \r
1055 if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
1056 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
1057 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
1058 del(pcd.SkuInfoList['DEFAULT'])\r
2bc3256c
LG
1059 \r
1060 \r
1061 if pcd.MaxDatumSize.strip(): \r
1062 MaxSize = int(pcd.MaxDatumSize,0)\r
1063 else:\r
1064 MaxSize = 0\r
1065 if pcdDecObject.DatumType == 'VOID*':\r
1066 for (skuname,skuobj) in pcd.SkuInfoList.items():\r
1067 datalen = 0\r
1068 if skuobj.HiiDefaultValue.startswith("L"):\r
1069 datalen = (len(skuobj.HiiDefaultValue)- 3 + 1) * 2\r
1070 elif skuobj.HiiDefaultValue.startswith("{"):\r
1071 datalen = len(skuobj.HiiDefaultValue.split(","))\r
1072 else:\r
1073 datalen = len(skuobj.HiiDefaultValue) -2 + 1 \r
1074 if datalen>MaxSize:\r
1075 MaxSize = datalen\r
1076 pcd.MaxDatumSize = str(MaxSize)\r
52302d4d
LG
1077 return Pcds\r
1078\r
1079 ## Retrieve dynamic VPD PCD settings\r
1080 #\r
1081 # @param Type PCD type\r
1082 #\r
1083 # @retval a dict object contains settings of given PCD type\r
1084 #\r
1085 def _GetDynamicVpdPcd(self, Type):\r
e8a47801
LG
1086 \r
1087 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
1088 \r
0d2711a6 1089 Pcds = sdict()\r
52302d4d
LG
1090 #\r
1091 # tdict is a special dict kind of type, used for selecting correct\r
1092 # PCD settings for certain ARCH and SKU\r
1093 #\r
1094 PcdDict = tdict(True, 4)\r
6780eef1 1095 PcdList = []\r
52302d4d
LG
1096 # Find out all possible PCD candidates for self._Arch\r
1097 RecordList = self._RawData[Type, self._Arch]\r
e8a47801
LG
1098 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
1099 \r
1100 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
52302d4d 1101 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
1102 if SkuName not in AvailableSkuIdSet:\r
1103 continue\r
1104\r
1105 PcdList.append((PcdCName, TokenSpaceGuid,SkuName, Dummy4))\r
52302d4d
LG
1106 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1107 # Remove redundant PCD candidates, per the ARCH and SKU\r
e8a47801
LG
1108 for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdList:\r
1109 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
52302d4d
LG
1110 if Setting == None:\r
1111 continue\r
e56468c0 1112 #\r
1113 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
1114 # For the Integer & Boolean type, the optional data can only be InitialValue.\r
1115 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
1116 # until the DEC parser has been called.\r
1117 # \r
4afd3d04 1118 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
e8a47801
LG
1119 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue)\r
1120 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
1121 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
1122 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2bc3256c
LG
1123 if MaxDatumSize.strip():\r
1124 CurrentMaxSize = int(MaxDatumSize.strip(),0)\r
1125 else:\r
1126 CurrentMaxSize = 0\r
1127 if pcdObject.MaxDatumSize:\r
1128 PcdMaxSize = int(pcdObject.MaxDatumSize,0)\r
1129 else:\r
1130 PcdMaxSize = 0\r
1131 if CurrentMaxSize > PcdMaxSize:\r
1132 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
e8a47801
LG
1133 else:\r
1134 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
52302d4d
LG
1135 PcdCName,\r
1136 TokenSpaceGuid,\r
1137 self._PCD_TYPE_STRING_[Type],\r
1138 '',\r
37fe82ee 1139 InitialValue,\r
52302d4d
LG
1140 '',\r
1141 MaxDatumSize,\r
e8a47801 1142 {SkuName : SkuInfo},\r
e56468c0 1143 False,\r
52302d4d
LG
1144 None\r
1145 )\r
e8a47801
LG
1146 for pcd in Pcds.values():\r
1147 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
2bc3256c 1148 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
e8a47801 1149 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
e8a47801
LG
1150 valuefromDec = pcdDecObject.DefaultValue\r
1151 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj.VpdOffset, valuefromDec)\r
1152 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1153 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1154 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1155 del(pcd.SkuInfoList['COMMON'])\r
1156 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1157 del(pcd.SkuInfoList['COMMON'])\r
1158 if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
1159 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
1160 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
1161 del(pcd.SkuInfoList['DEFAULT'])\r
1162 \r
52302d4d
LG
1163 return Pcds\r
1164\r
1165 ## Add external modules\r
1166 #\r
1167 # The external modules are mostly those listed in FDF file, which don't\r
1168 # need "build".\r
1169 #\r
1170 # @param FilePath The path of module description file\r
1171 #\r
1172 def AddModule(self, FilePath):\r
1173 FilePath = NormPath(FilePath)\r
1174 if FilePath not in self.Modules:\r
1175 Module = ModuleBuildClassObject()\r
1176 Module.MetaFile = FilePath\r
1177 self.Modules.append(Module)\r
1178\r
1179 ## Add external PCDs\r
1180 #\r
1181 # The external PCDs are mostly those listed in FDF file to specify address\r
1182 # or offset information.\r
1183 #\r
1184 # @param Name Name of the PCD\r
1185 # @param Guid Token space guid of the PCD\r
1186 # @param Value Value of the PCD\r
1187 #\r
1188 def AddPcd(self, Name, Guid, Value):\r
1189 if (Name, Guid) not in self.Pcds:\r
e56468c0 1190 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
52302d4d
LG
1191 self.Pcds[Name, Guid].DefaultValue = Value\r
1192\r
0d2711a6 1193 _Macros = property(_GetMacros)\r
52302d4d
LG
1194 Arch = property(_GetArch, _SetArch)\r
1195 Platform = property(_GetPlatformName)\r
1196 PlatformName = property(_GetPlatformName)\r
1197 Guid = property(_GetFileGuid)\r
1198 Version = property(_GetVersion)\r
1199 DscSpecification = property(_GetDscSpec)\r
1200 OutputDirectory = property(_GetOutpuDir)\r
1201 SupArchList = property(_GetSupArch)\r
1202 BuildTargets = property(_GetBuildTarget)\r
1203 SkuName = property(_GetSkuName, _SetSkuName)\r
e8a47801 1204 SkuIdentifier = property(_GetSkuIdentifier)\r
1ae469b9 1205 AvilableSkuIds = property(_GetAviableSkuIds)\r
e8a47801 1206 PcdInfoFlag = property(_GetPcdInfoFlag)\r
82a6a960 1207 VarCheckFlag = property(_GetVarCheckFlag)\r
52302d4d
LG
1208 FlashDefinition = property(_GetFdfFile)\r
1209 BuildNumber = property(_GetBuildNumber)\r
1210 MakefileName = property(_GetMakefileName)\r
1211 BsBaseAddress = property(_GetBsBaseAddress)\r
1212 RtBaseAddress = property(_GetRtBaseAddress)\r
1213 LoadFixAddress = property(_GetLoadFixAddress)\r
6780eef1
LG
1214 RFCLanguages = property(_GetRFCLanguages)\r
1215 ISOLanguages = property(_GetISOLanguages)\r
08dd311f 1216 VpdToolGuid = property(_GetVpdToolGuid) \r
52302d4d
LG
1217 SkuIds = property(_GetSkuIds)\r
1218 Modules = property(_GetModules)\r
1219 LibraryInstances = property(_GetLibraryInstances)\r
1220 LibraryClasses = property(_GetLibraryClasses)\r
1221 Pcds = property(_GetPcds)\r
1222 BuildOptions = property(_GetBuildOptions)\r
1223\r
e56468c0 1224## Platform build information from DEC file\r
52302d4d
LG
1225#\r
1226# This class is used to retrieve information stored in database and convert them\r
1227# into PackageBuildClassObject form for easier use for AutoGen.\r
1228#\r
1229class DecBuildData(PackageBuildClassObject):\r
1230 # dict used to convert PCD type in database to string used by build tool\r
1231 _PCD_TYPE_STRING_ = {\r
1232 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
1233 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
1234 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
1235 MODEL_PCD_DYNAMIC : "Dynamic",\r
1236 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
1237 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
1238 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
1239 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
1240 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
1241 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
1242 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
1243 }\r
1244\r
1245 # dict used to convert part of [Defines] to members of DecBuildData directly\r
1246 _PROPERTY_ = {\r
1247 #\r
1248 # Required Fields\r
1249 #\r
1250 TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName",\r
1251 TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid",\r
1252 TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version",\r
e56468c0 1253 TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile",\r
52302d4d
LG
1254 }\r
1255\r
1256\r
1257 ## Constructor of DecBuildData\r
1258 #\r
1259 # Initialize object of DecBuildData\r
1260 #\r
1261 # @param FilePath The path of package description file\r
1262 # @param RawData The raw data of DEC file\r
1263 # @param BuildDataBase Database used to retrieve module information\r
1264 # @param Arch The target architecture\r
1265 # @param Platform (not used for DecBuildData)\r
1266 # @param Macros Macros used for replacement in DSC file\r
1267 #\r
0d2711a6 1268 def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r
52302d4d
LG
1269 self.MetaFile = File\r
1270 self._PackageDir = File.Dir\r
1271 self._RawData = RawData\r
1272 self._Bdb = BuildDataBase\r
1273 self._Arch = Arch\r
0d2711a6
LG
1274 self._Target = Target\r
1275 self._Toolchain = Toolchain\r
52302d4d
LG
1276 self._Clear()\r
1277\r
1278 ## XXX[key] = value\r
1279 def __setitem__(self, key, value):\r
1280 self.__dict__[self._PROPERTY_[key]] = value\r
1281\r
1282 ## value = XXX[key]\r
1283 def __getitem__(self, key):\r
1284 return self.__dict__[self._PROPERTY_[key]]\r
1285\r
1286 ## "in" test support\r
1287 def __contains__(self, key):\r
1288 return key in self._PROPERTY_\r
1289\r
1290 ## Set all internal used members of DecBuildData to None\r
1291 def _Clear(self):\r
1292 self._Header = None\r
1293 self._PackageName = None\r
1294 self._Guid = None\r
1295 self._Version = None\r
e56468c0 1296 self._PkgUniFile = None\r
52302d4d
LG
1297 self._Protocols = None\r
1298 self._Ppis = None\r
1299 self._Guids = None\r
1300 self._Includes = None\r
1301 self._LibraryClasses = None\r
1302 self._Pcds = None\r
0d2711a6
LG
1303 self.__Macros = None\r
1304\r
1305 ## Get current effective macros\r
1306 def _GetMacros(self):\r
1307 if self.__Macros == None:\r
1308 self.__Macros = {}\r
1309 self.__Macros.update(GlobalData.gGlobalDefines)\r
1310 return self.__Macros\r
52302d4d
LG
1311\r
1312 ## Get architecture\r
1313 def _GetArch(self):\r
1314 return self._Arch\r
1315\r
1316 ## Set architecture\r
1317 #\r
1318 # Changing the default ARCH to another may affect all other information\r
1319 # because all information in a platform may be ARCH-related. That's\r
1320 # why we need to clear all internal used members, in order to cause all\r
1321 # information to be re-retrieved.\r
1322 #\r
1323 # @param Value The value of ARCH\r
1324 #\r
1325 def _SetArch(self, Value):\r
1326 if self._Arch == Value:\r
1327 return\r
1328 self._Arch = Value\r
1329 self._Clear()\r
1330\r
1331 ## Retrieve all information in [Defines] section\r
1332 #\r
1333 # (Retriving all [Defines] information in one-shot is just to save time.)\r
1334 #\r
1335 def _GetHeaderInfo(self):\r
0d2711a6 1336 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
52302d4d 1337 for Record in RecordList:\r
0d2711a6 1338 Name = Record[1]\r
52302d4d 1339 if Name in self:\r
0d2711a6 1340 self[Name] = Record[2]\r
52302d4d
LG
1341 self._Header = 'DUMMY'\r
1342\r
1343 ## Retrieve package name\r
1344 def _GetPackageName(self):\r
1345 if self._PackageName == None:\r
1346 if self._Header == None:\r
1347 self._GetHeaderInfo()\r
1348 if self._PackageName == None:\r
1349 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)\r
1350 return self._PackageName\r
1351\r
1352 ## Retrieve file guid\r
1353 def _GetFileGuid(self):\r
1354 if self._Guid == None:\r
1355 if self._Header == None:\r
1356 self._GetHeaderInfo()\r
1357 if self._Guid == None:\r
1358 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)\r
1359 return self._Guid\r
1360\r
1361 ## Retrieve package version\r
1362 def _GetVersion(self):\r
1363 if self._Version == None:\r
1364 if self._Header == None:\r
1365 self._GetHeaderInfo()\r
1366 if self._Version == None:\r
1367 self._Version = ''\r
1368 return self._Version\r
1369\r
1370 ## Retrieve protocol definitions (name/value pairs)\r
1371 def _GetProtocol(self):\r
1372 if self._Protocols == None:\r
1373 #\r
1374 # tdict is a special kind of dict, used for selecting correct\r
1375 # protocol defition for given ARCH\r
1376 #\r
1377 ProtocolDict = tdict(True)\r
1378 NameList = []\r
1379 # find out all protocol definitions for specific and 'common' arch\r
1380 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]\r
1381 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
1382 if Name not in NameList:\r
1383 NameList.append(Name)\r
1384 ProtocolDict[Arch, Name] = Guid\r
1385 # use sdict to keep the order\r
1386 self._Protocols = sdict()\r
1387 for Name in NameList:\r
1388 #\r
1389 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1390 # will automatically turn to 'common' ARCH for trying\r
1391 #\r
1392 self._Protocols[Name] = ProtocolDict[self._Arch, Name]\r
1393 return self._Protocols\r
1394\r
1395 ## Retrieve PPI definitions (name/value pairs)\r
1396 def _GetPpi(self):\r
1397 if self._Ppis == None:\r
1398 #\r
1399 # tdict is a special kind of dict, used for selecting correct\r
1400 # PPI defition for given ARCH\r
1401 #\r
1402 PpiDict = tdict(True)\r
1403 NameList = []\r
1404 # find out all PPI definitions for specific arch and 'common' arch\r
1405 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]\r
1406 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
1407 if Name not in NameList:\r
1408 NameList.append(Name)\r
1409 PpiDict[Arch, Name] = Guid\r
1410 # use sdict to keep the order\r
1411 self._Ppis = sdict()\r
1412 for Name in NameList:\r
1413 #\r
1414 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1415 # will automatically turn to 'common' ARCH for trying\r
1416 #\r
1417 self._Ppis[Name] = PpiDict[self._Arch, Name]\r
1418 return self._Ppis\r
1419\r
1420 ## Retrieve GUID definitions (name/value pairs)\r
1421 def _GetGuid(self):\r
1422 if self._Guids == None:\r
1423 #\r
1424 # tdict is a special kind of dict, used for selecting correct\r
1425 # GUID defition for given ARCH\r
1426 #\r
1427 GuidDict = tdict(True)\r
1428 NameList = []\r
1429 # find out all protocol definitions for specific and 'common' arch\r
1430 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]\r
1431 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
1432 if Name not in NameList:\r
1433 NameList.append(Name)\r
1434 GuidDict[Arch, Name] = Guid\r
1435 # use sdict to keep the order\r
1436 self._Guids = sdict()\r
1437 for Name in NameList:\r
1438 #\r
1439 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1440 # will automatically turn to 'common' ARCH for trying\r
1441 #\r
1442 self._Guids[Name] = GuidDict[self._Arch, Name]\r
1443 return self._Guids\r
1444\r
1445 ## Retrieve public include paths declared in this package\r
1446 def _GetInclude(self):\r
1447 if self._Includes == None:\r
1448 self._Includes = []\r
1449 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]\r
0d2711a6
LG
1450 Macros = self._Macros\r
1451 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
52302d4d
LG
1452 for Record in RecordList:\r
1453 File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)\r
1454 LineNo = Record[-1]\r
1455 # validate the path\r
1456 ErrorCode, ErrorInfo = File.Validate()\r
1457 if ErrorCode != 0:\r
1458 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1459\r
1460 # avoid duplicate include path\r
1461 if File not in self._Includes:\r
1462 self._Includes.append(File)\r
1463 return self._Includes\r
1464\r
1465 ## Retrieve library class declarations (not used in build at present)\r
1466 def _GetLibraryClass(self):\r
1467 if self._LibraryClasses == None:\r
1468 #\r
1469 # tdict is a special kind of dict, used for selecting correct\r
1470 # library class declaration for given ARCH\r
1471 #\r
1472 LibraryClassDict = tdict(True)\r
1473 LibraryClassSet = set()\r
1474 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
0d2711a6 1475 Macros = self._Macros\r
52302d4d
LG
1476 for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:\r
1477 File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)\r
1478 # check the file validation\r
1479 ErrorCode, ErrorInfo = File.Validate()\r
1480 if ErrorCode != 0:\r
1481 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1482 LibraryClassSet.add(LibraryClass)\r
1483 LibraryClassDict[Arch, LibraryClass] = File\r
1484 self._LibraryClasses = sdict()\r
1485 for LibraryClass in LibraryClassSet:\r
1486 self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]\r
1487 return self._LibraryClasses\r
1488\r
1489 ## Retrieve PCD declarations\r
1490 def _GetPcds(self):\r
1491 if self._Pcds == None:\r
0d2711a6 1492 self._Pcds = sdict()\r
52302d4d
LG
1493 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
1494 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
1495 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
1496 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
1497 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
1498 return self._Pcds\r
1499\r
1500 ## Retrieve PCD declarations for given type\r
1501 def _GetPcd(self, Type):\r
0d2711a6 1502 Pcds = sdict()\r
52302d4d
LG
1503 #\r
1504 # tdict is a special kind of dict, used for selecting correct\r
1505 # PCD declaration for given ARCH\r
1506 #\r
1507 PcdDict = tdict(True, 3)\r
1508 # for summarizing PCD\r
1509 PcdSet = set()\r
1510 # find out all PCDs of the 'type'\r
1511 RecordList = self._RawData[Type, self._Arch]\r
1512 for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList:\r
1513 PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
1514 PcdSet.add((PcdCName, TokenSpaceGuid))\r
1515\r
1516 for PcdCName, TokenSpaceGuid in PcdSet:\r
52302d4d
LG
1517 #\r
1518 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1519 # will automatically turn to 'common' ARCH and try again\r
1520 #\r
1521 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
1522 if Setting == None:\r
1523 continue\r
6780eef1
LG
1524\r
1525 DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)\r
1526 \r
82a6a960 1527 validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName) \r
52302d4d
LG
1528 Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
1529 PcdCName,\r
1530 TokenSpaceGuid,\r
1531 self._PCD_TYPE_STRING_[Type],\r
1532 DatumType,\r
1533 DefaultValue,\r
1534 TokenNumber,\r
1535 '',\r
1536 {},\r
e56468c0 1537 False,\r
82a6a960
BF
1538 None,\r
1539 list(validateranges),\r
1540 list(validlists),\r
1541 list(expressions)\r
52302d4d
LG
1542 )\r
1543 return Pcds\r
1544\r
1545\r
0d2711a6 1546 _Macros = property(_GetMacros)\r
52302d4d
LG
1547 Arch = property(_GetArch, _SetArch)\r
1548 PackageName = property(_GetPackageName)\r
1549 Guid = property(_GetFileGuid)\r
1550 Version = property(_GetVersion)\r
1551\r
1552 Protocols = property(_GetProtocol)\r
1553 Ppis = property(_GetPpi)\r
1554 Guids = property(_GetGuid)\r
1555 Includes = property(_GetInclude)\r
1556 LibraryClasses = property(_GetLibraryClass)\r
1557 Pcds = property(_GetPcds)\r
1558\r
1559## Module build information from INF file\r
1560#\r
1561# This class is used to retrieve information stored in database and convert them\r
1562# into ModuleBuildClassObject form for easier use for AutoGen.\r
1563#\r
1564class InfBuildData(ModuleBuildClassObject):\r
1565 # dict used to convert PCD type in database to string used by build tool\r
1566 _PCD_TYPE_STRING_ = {\r
1567 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
1568 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
1569 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
1570 MODEL_PCD_DYNAMIC : "Dynamic",\r
1571 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
1572 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
1573 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
1574 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
1575 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
1576 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
1577 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
1578 }\r
1579\r
1580 # dict used to convert part of [Defines] to members of InfBuildData directly\r
1581 _PROPERTY_ = {\r
1582 #\r
1583 # Required Fields\r
1584 #\r
1585 TAB_INF_DEFINES_BASE_NAME : "_BaseName",\r
1586 TAB_INF_DEFINES_FILE_GUID : "_Guid",\r
1587 TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",\r
1588 #\r
1589 # Optional Fields\r
1590 #\r
0d2711a6 1591 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",\r
52302d4d
LG
1592 TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",\r
1593 TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",\r
1594 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",\r
b36d134f 1595 TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",\r
52302d4d
LG
1596 TAB_INF_DEFINES_VERSION_NUMBER : "_Version",\r
1597 TAB_INF_DEFINES_VERSION_STRING : "_Version",\r
1598 TAB_INF_DEFINES_VERSION : "_Version",\r
1599 TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",\r
1600 TAB_INF_DEFINES_SHADOW : "_Shadow",\r
1601\r
1602 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath",\r
1603 }\r
1604\r
1605 # dict used to convert Component type to Module type\r
1606 _MODULE_TYPE_ = {\r
1607 "LIBRARY" : "BASE",\r
1608 "SECURITY_CORE" : "SEC",\r
1609 "PEI_CORE" : "PEI_CORE",\r
1610 "COMBINED_PEIM_DRIVER" : "PEIM",\r
1611 "PIC_PEIM" : "PEIM",\r
1612 "RELOCATABLE_PEIM" : "PEIM",\r
1613 "PE32_PEIM" : "PEIM",\r
1614 "BS_DRIVER" : "DXE_DRIVER",\r
1615 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",\r
1616 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",\r
1617 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",\r
1618 # "SMM_DRIVER" : "DXE_SMM_DRIVER",\r
1619 # "BS_DRIVER" : "DXE_SMM_DRIVER",\r
1620 # "BS_DRIVER" : "UEFI_DRIVER",\r
1621 "APPLICATION" : "UEFI_APPLICATION",\r
1622 "LOGO" : "BASE",\r
1623 }\r
1624\r
1625 # regular expression for converting XXX_FLAGS in [nmake] section to new type\r
1626 _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)\r
1627 # dict used to convert old tool name used in [nmake] section to new ones\r
1628 _TOOL_CODE_ = {\r
1629 "C" : "CC",\r
1630 "LIB" : "SLINK",\r
1631 "LINK" : "DLINK",\r
1632 }\r
1633\r
1634\r
1635 ## Constructor of DscBuildData\r
1636 #\r
1637 # Initialize object of DscBuildData\r
1638 #\r
1639 # @param FilePath The path of platform description file\r
1640 # @param RawData The raw data of DSC file\r
1641 # @param BuildDataBase Database used to retrieve module/package information\r
1642 # @param Arch The target architecture\r
1643 # @param Platform The name of platform employing this module\r
1644 # @param Macros Macros used for replacement in DSC file\r
1645 #\r
0d2711a6 1646 def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):\r
52302d4d
LG
1647 self.MetaFile = FilePath\r
1648 self._ModuleDir = FilePath.Dir\r
1649 self._RawData = RawData\r
1650 self._Bdb = BuildDatabase\r
1651 self._Arch = Arch\r
0d2711a6
LG
1652 self._Target = Target\r
1653 self._Toolchain = Toolchain\r
52302d4d 1654 self._Platform = 'COMMON'\r
52302d4d
LG
1655 self._SourceOverridePath = None\r
1656 if FilePath.Key in GlobalData.gOverrideDir:\r
1657 self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]\r
1658 self._Clear()\r
1659\r
1660 ## XXX[key] = value\r
1661 def __setitem__(self, key, value):\r
1662 self.__dict__[self._PROPERTY_[key]] = value\r
1663\r
1664 ## value = XXX[key]\r
1665 def __getitem__(self, key):\r
1666 return self.__dict__[self._PROPERTY_[key]]\r
1667\r
1668 ## "in" test support\r
1669 def __contains__(self, key):\r
1670 return key in self._PROPERTY_\r
1671\r
1672 ## Set all internal used members of InfBuildData to None\r
1673 def _Clear(self):\r
e8a47801 1674 self._HeaderComments = None\r
2bc3256c 1675 self._TailComments = None\r
52302d4d
LG
1676 self._Header_ = None\r
1677 self._AutoGenVersion = None\r
1678 self._BaseName = None\r
b36d134f 1679 self._DxsFile = None\r
52302d4d
LG
1680 self._ModuleType = None\r
1681 self._ComponentType = None\r
1682 self._BuildType = None\r
1683 self._Guid = None\r
1684 self._Version = None\r
1685 self._PcdIsDriver = None\r
1686 self._BinaryModule = None\r
1687 self._Shadow = None\r
1688 self._MakefileName = None\r
1689 self._CustomMakefile = None\r
1690 self._Specification = None\r
1691 self._LibraryClass = None\r
1692 self._ModuleEntryPointList = None\r
1693 self._ModuleUnloadImageList = None\r
1694 self._ConstructorList = None\r
1695 self._DestructorList = None\r
1696 self._Defs = None\r
1697 self._Binaries = None\r
1698 self._Sources = None\r
1699 self._LibraryClasses = None\r
1700 self._Libraries = None\r
1701 self._Protocols = None\r
e8a47801 1702 self._ProtocolComments = None\r
52302d4d 1703 self._Ppis = None\r
e8a47801 1704 self._PpiComments = None\r
52302d4d 1705 self._Guids = None\r
e8a47801
LG
1706 self._GuidsUsedByPcd = sdict()\r
1707 self._GuidComments = None\r
52302d4d
LG
1708 self._Includes = None\r
1709 self._Packages = None\r
1710 self._Pcds = None\r
e8a47801 1711 self._PcdComments = None\r
52302d4d
LG
1712 self._BuildOptions = None\r
1713 self._Depex = None\r
1714 self._DepexExpression = None\r
0d2711a6
LG
1715 self.__Macros = None\r
1716\r
1717 ## Get current effective macros\r
1718 def _GetMacros(self):\r
1719 if self.__Macros == None:\r
1720 self.__Macros = {}\r
d0acc87a 1721 # EDK_GLOBAL defined macros can be applied to EDK module\r
0d2711a6
LG
1722 if self.AutoGenVersion < 0x00010005:\r
1723 self.__Macros.update(GlobalData.gEdkGlobal)\r
d0acc87a 1724 self.__Macros.update(GlobalData.gGlobalDefines)\r
0d2711a6 1725 return self.__Macros\r
52302d4d
LG
1726\r
1727 ## Get architecture\r
1728 def _GetArch(self):\r
1729 return self._Arch\r
1730\r
1731 ## Set architecture\r
1732 #\r
1733 # Changing the default ARCH to another may affect all other information\r
1734 # because all information in a platform may be ARCH-related. That's\r
1735 # why we need to clear all internal used members, in order to cause all\r
1736 # information to be re-retrieved.\r
1737 #\r
1738 # @param Value The value of ARCH\r
1739 #\r
1740 def _SetArch(self, Value):\r
1741 if self._Arch == Value:\r
1742 return\r
1743 self._Arch = Value\r
1744 self._Clear()\r
1745\r
1746 ## Return the name of platform employing this module\r
1747 def _GetPlatform(self):\r
1748 return self._Platform\r
1749\r
1750 ## Change the name of platform employing this module\r
1751 #\r
1752 # Changing the default name of platform to another may affect some information\r
1753 # because they may be PLATFORM-related. That's why we need to clear all internal\r
1754 # used members, in order to cause all information to be re-retrieved.\r
1755 #\r
1756 def _SetPlatform(self, Value):\r
1757 if self._Platform == Value:\r
1758 return\r
1759 self._Platform = Value\r
1760 self._Clear()\r
e8a47801
LG
1761 def _GetHeaderComments(self):\r
1762 if not self._HeaderComments:\r
1763 self._HeaderComments = []\r
1764 RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]\r
1765 for Record in RecordList:\r
1766 self._HeaderComments.append(Record[0])\r
1767 return self._HeaderComments\r
2bc3256c
LG
1768 def _GetTailComments(self):\r
1769 if not self._TailComments:\r
1770 self._TailComments = []\r
1771 RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]\r
1772 for Record in RecordList:\r
1773 self._TailComments.append(Record[0])\r
1774 return self._TailComments\r
52302d4d
LG
1775 ## Retrieve all information in [Defines] section\r
1776 #\r
1777 # (Retriving all [Defines] information in one-shot is just to save time.)\r
1778 #\r
1779 def _GetHeaderInfo(self):\r
1780 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
1781 for Record in RecordList:\r
0d2711a6 1782 Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)\r
52302d4d
LG
1783 # items defined _PROPERTY_ don't need additional processing\r
1784 if Name in self:\r
0d2711a6 1785 self[Name] = Value\r
97fa0ee9
YL
1786 if self._Defs == None:\r
1787 self._Defs = sdict()\r
1788 self._Defs[Name] = Value\r
52302d4d 1789 # some special items in [Defines] section need special treatment\r
08dd311f
LG
1790 elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):\r
1791 if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):\r
1792 Name = 'UEFI_SPECIFICATION_VERSION'\r
52302d4d
LG
1793 if self._Specification == None:\r
1794 self._Specification = sdict()\r
0d2711a6 1795 self._Specification[Name] = GetHexVerValue(Value)\r
08dd311f
LG
1796 if self._Specification[Name] == None:\r
1797 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
0d2711a6 1798 "'%s' format is not supported for %s" % (Value, Name),\r
08dd311f 1799 File=self.MetaFile, Line=Record[-1])\r
52302d4d
LG
1800 elif Name == 'LIBRARY_CLASS':\r
1801 if self._LibraryClass == None:\r
1802 self._LibraryClass = []\r
0d2711a6 1803 ValueList = GetSplitValueList(Value)\r
52302d4d
LG
1804 LibraryClass = ValueList[0]\r
1805 if len(ValueList) > 1:\r
1806 SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
1807 else:\r
1808 SupModuleList = SUP_MODULE_LIST\r
1809 self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))\r
1810 elif Name == 'ENTRY_POINT':\r
1811 if self._ModuleEntryPointList == None:\r
1812 self._ModuleEntryPointList = []\r
0d2711a6 1813 self._ModuleEntryPointList.append(Value)\r
52302d4d
LG
1814 elif Name == 'UNLOAD_IMAGE':\r
1815 if self._ModuleUnloadImageList == None:\r
1816 self._ModuleUnloadImageList = []\r
0d2711a6 1817 if not Value:\r
52302d4d 1818 continue\r
0d2711a6 1819 self._ModuleUnloadImageList.append(Value)\r
52302d4d
LG
1820 elif Name == 'CONSTRUCTOR':\r
1821 if self._ConstructorList == None:\r
1822 self._ConstructorList = []\r
0d2711a6 1823 if not Value:\r
52302d4d 1824 continue\r
0d2711a6 1825 self._ConstructorList.append(Value)\r
52302d4d
LG
1826 elif Name == 'DESTRUCTOR':\r
1827 if self._DestructorList == None:\r
1828 self._DestructorList = []\r
0d2711a6 1829 if not Value:\r
52302d4d 1830 continue\r
0d2711a6 1831 self._DestructorList.append(Value)\r
52302d4d 1832 elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:\r
0d2711a6 1833 TokenList = GetSplitValueList(Value)\r
52302d4d
LG
1834 if self._CustomMakefile == None:\r
1835 self._CustomMakefile = {}\r
1836 if len(TokenList) < 2:\r
1837 self._CustomMakefile['MSFT'] = TokenList[0]\r
1838 self._CustomMakefile['GCC'] = TokenList[0]\r
1839 else:\r
1840 if TokenList[0] not in ['MSFT', 'GCC']:\r
1841 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
1842 "No supported family [%s]" % TokenList[0],\r
1843 File=self.MetaFile, Line=Record[-1])\r
1844 self._CustomMakefile[TokenList[0]] = TokenList[1]\r
1845 else:\r
1846 if self._Defs == None:\r
1847 self._Defs = sdict()\r
0d2711a6 1848 self._Defs[Name] = Value\r
52302d4d
LG
1849\r
1850 #\r
0d2711a6 1851 # Retrieve information in sections specific to Edk.x modules\r
52302d4d 1852 #\r
0d2711a6 1853 if self.AutoGenVersion >= 0x00010005:\r
52302d4d
LG
1854 if not self._ModuleType:\r
1855 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
1856 "MODULE_TYPE is not given", File=self.MetaFile)\r
da92f276
LG
1857 if self._ModuleType not in SUP_MODULE_LIST:\r
1858 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
1859 for Record in RecordList:\r
0d2711a6 1860 Name = Record[1]\r
da92f276
LG
1861 if Name == "MODULE_TYPE":\r
1862 LineNo = Record[6]\r
1863 break\r
1864 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
1865 "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 1866 File=self.MetaFile, Line=LineNo)\r
da92f276 1867 if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):\r
52302d4d
LG
1868 if self._ModuleType == SUP_MODULE_SMM_CORE:\r
1869 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
1870 if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
1871 and 'PCI_CLASS_CODE' in self._Defs:\r
1872 self._BuildType = 'UEFI_OPTIONROM'\r
1873 elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \\r
1874 and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':\r
1875 self._BuildType = 'UEFI_HII'\r
1876 else:\r
1877 self._BuildType = self._ModuleType.upper()\r
b36d134f
LG
1878 \r
1879 if self._DxsFile:\r
1880 File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
1881 # check the file validation\r
1882 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
1883 if ErrorCode != 0:\r
1884 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
1885 File=self.MetaFile, Line=LineNo)\r
1886 if self.Sources == None:\r
1887 self._Sources = []\r
1888 self._Sources.append(File)\r
0d2711a6 1889 else: \r
52302d4d
LG
1890 if not self._ComponentType:\r
1891 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
1892 "COMPONENT_TYPE is not given", File=self.MetaFile)\r
0d2711a6 1893 self._BuildType = self._ComponentType.upper() \r
52302d4d
LG
1894 if self._ComponentType in self._MODULE_TYPE_:\r
1895 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
1896 if self._ComponentType == 'LIBRARY':\r
1897 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
1898 # make use some [nmake] section macros\r
0d2711a6
LG
1899 Macros = self._Macros\r
1900 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
1901 Macros['PROCESSOR'] = self._Arch\r
52302d4d
LG
1902 RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
1903 for Name,Value,Dummy,Arch,Platform,ID,LineNo in RecordList:\r
0d2711a6 1904 Value = ReplaceMacro(Value, Macros, True)\r
52302d4d
LG
1905 if Name == "IMAGE_ENTRY_POINT":\r
1906 if self._ModuleEntryPointList == None:\r
1907 self._ModuleEntryPointList = []\r
1908 self._ModuleEntryPointList.append(Value)\r
1909 elif Name == "DPX_SOURCE":\r
0d2711a6 1910 File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)\r
52302d4d
LG
1911 # check the file validation\r
1912 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
1913 if ErrorCode != 0:\r
1914 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
1915 File=self.MetaFile, Line=LineNo)\r
1916 if self.Sources == None:\r
1917 self._Sources = []\r
1918 self._Sources.append(File)\r
1919 else:\r
1920 ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
1921 if len(ToolList) == 0 or len(ToolList) != 1:\r
1922 pass\r
1923# EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,\r
1924# File=self.MetaFile, Line=LineNo)\r
1925 else:\r
1926 if self._BuildOptions == None:\r
1927 self._BuildOptions = sdict()\r
1928\r
1929 if ToolList[0] in self._TOOL_CODE_:\r
1930 Tool = self._TOOL_CODE_[ToolList[0]]\r
1931 else:\r
1932 Tool = ToolList[0]\r
1933 ToolChain = "*_*_*_%s_FLAGS" % Tool\r
f51461c8 1934 ToolChainFamily = 'MSFT' # Edk.x only support MSFT tool chain\r
52302d4d 1935 #ignore not replaced macros in value\r
0d2711a6 1936 ValueList = GetSplitList(' ' + Value, '/D')\r
52302d4d
LG
1937 Dummy = ValueList[0]\r
1938 for Index in range(1, len(ValueList)):\r
1939 if ValueList[Index][-1] == '=' or ValueList[Index] == '':\r
1940 continue\r
1941 Dummy = Dummy + ' /D ' + ValueList[Index]\r
1942 Value = Dummy.strip()\r
1943 if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
1944 self._BuildOptions[ToolChainFamily, ToolChain] = Value\r
1945 else:\r
1946 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
1947 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value\r
1948 # set _Header to non-None in order to avoid database re-querying\r
1949 self._Header_ = 'DUMMY'\r
1950\r
1951 ## Retrieve file version\r
1952 def _GetInfVersion(self):\r
1953 if self._AutoGenVersion == None:\r
0d2711a6
LG
1954 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
1955 for Record in RecordList:\r
1956 if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
1957 self._AutoGenVersion = int(Record[2], 0)\r
1958 break\r
52302d4d
LG
1959 if self._AutoGenVersion == None:\r
1960 self._AutoGenVersion = 0x00010000\r
1961 return self._AutoGenVersion\r
1962\r
1963 ## Retrieve BASE_NAME\r
1964 def _GetBaseName(self):\r
1965 if self._BaseName == None:\r
1966 if self._Header_ == None:\r
1967 self._GetHeaderInfo()\r
1968 if self._BaseName == None:\r
1969 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)\r
1970 return self._BaseName\r
1971\r
b36d134f
LG
1972 ## Retrieve DxsFile\r
1973 def _GetDxsFile(self):\r
1974 if self._DxsFile == None:\r
1975 if self._Header_ == None:\r
1976 self._GetHeaderInfo()\r
1977 if self._DxsFile == None:\r
1978 self._DxsFile = ''\r
1979 return self._DxsFile\r
1980\r
52302d4d
LG
1981 ## Retrieve MODULE_TYPE\r
1982 def _GetModuleType(self):\r
1983 if self._ModuleType == None:\r
1984 if self._Header_ == None:\r
1985 self._GetHeaderInfo()\r
1986 if self._ModuleType == None:\r
1987 self._ModuleType = 'BASE'\r
1988 if self._ModuleType not in SUP_MODULE_LIST:\r
1989 self._ModuleType = "USER_DEFINED"\r
1990 return self._ModuleType\r
1991\r
1992 ## Retrieve COMPONENT_TYPE\r
1993 def _GetComponentType(self):\r
1994 if self._ComponentType == None:\r
1995 if self._Header_ == None:\r
1996 self._GetHeaderInfo()\r
1997 if self._ComponentType == None:\r
1998 self._ComponentType = 'USER_DEFINED'\r
1999 return self._ComponentType\r
2000\r
2001 ## Retrieve "BUILD_TYPE"\r
2002 def _GetBuildType(self):\r
2003 if self._BuildType == None:\r
2004 if self._Header_ == None:\r
2005 self._GetHeaderInfo()\r
2006 if not self._BuildType:\r
2007 self._BuildType = "BASE"\r
2008 return self._BuildType\r
2009\r
2010 ## Retrieve file guid\r
2011 def _GetFileGuid(self):\r
2012 if self._Guid == None:\r
2013 if self._Header_ == None:\r
2014 self._GetHeaderInfo()\r
2015 if self._Guid == None:\r
1ba5124e 2016 self._Guid = '00000000-0000-0000-0000-000000000000'\r
52302d4d
LG
2017 return self._Guid\r
2018\r
2019 ## Retrieve module version\r
2020 def _GetVersion(self):\r
2021 if self._Version == None:\r
2022 if self._Header_ == None:\r
2023 self._GetHeaderInfo()\r
2024 if self._Version == None:\r
2025 self._Version = '0.0'\r
2026 return self._Version\r
2027\r
2028 ## Retrieve PCD_IS_DRIVER\r
2029 def _GetPcdIsDriver(self):\r
2030 if self._PcdIsDriver == None:\r
2031 if self._Header_ == None:\r
2032 self._GetHeaderInfo()\r
2033 if self._PcdIsDriver == None:\r
2034 self._PcdIsDriver = ''\r
2035 return self._PcdIsDriver\r
2036\r
2037 ## Retrieve SHADOW\r
2038 def _GetShadow(self):\r
2039 if self._Shadow == None:\r
2040 if self._Header_ == None:\r
2041 self._GetHeaderInfo()\r
2042 if self._Shadow != None and self._Shadow.upper() == 'TRUE':\r
2043 self._Shadow = True\r
2044 else:\r
2045 self._Shadow = False\r
2046 return self._Shadow\r
2047\r
2048 ## Retrieve CUSTOM_MAKEFILE\r
2049 def _GetMakefile(self):\r
2050 if self._CustomMakefile == None:\r
2051 if self._Header_ == None:\r
2052 self._GetHeaderInfo()\r
2053 if self._CustomMakefile == None:\r
2054 self._CustomMakefile = {}\r
2055 return self._CustomMakefile\r
2056\r
2057 ## Retrieve EFI_SPECIFICATION_VERSION\r
2058 def _GetSpec(self):\r
2059 if self._Specification == None:\r
2060 if self._Header_ == None:\r
2061 self._GetHeaderInfo()\r
2062 if self._Specification == None:\r
2063 self._Specification = {}\r
2064 return self._Specification\r
2065\r
2066 ## Retrieve LIBRARY_CLASS\r
2067 def _GetLibraryClass(self):\r
2068 if self._LibraryClass == None:\r
2069 if self._Header_ == None:\r
2070 self._GetHeaderInfo()\r
2071 if self._LibraryClass == None:\r
2072 self._LibraryClass = []\r
2073 return self._LibraryClass\r
2074\r
2075 ## Retrieve ENTRY_POINT\r
2076 def _GetEntryPoint(self):\r
2077 if self._ModuleEntryPointList == None:\r
2078 if self._Header_ == None:\r
2079 self._GetHeaderInfo()\r
2080 if self._ModuleEntryPointList == None:\r
2081 self._ModuleEntryPointList = []\r
2082 return self._ModuleEntryPointList\r
2083\r
2084 ## Retrieve UNLOAD_IMAGE\r
2085 def _GetUnloadImage(self):\r
2086 if self._ModuleUnloadImageList == None:\r
2087 if self._Header_ == None:\r
2088 self._GetHeaderInfo()\r
2089 if self._ModuleUnloadImageList == None:\r
2090 self._ModuleUnloadImageList = []\r
2091 return self._ModuleUnloadImageList\r
2092\r
2093 ## Retrieve CONSTRUCTOR\r
2094 def _GetConstructor(self):\r
2095 if self._ConstructorList == None:\r
2096 if self._Header_ == None:\r
2097 self._GetHeaderInfo()\r
2098 if self._ConstructorList == None:\r
2099 self._ConstructorList = []\r
2100 return self._ConstructorList\r
2101\r
2102 ## Retrieve DESTRUCTOR\r
2103 def _GetDestructor(self):\r
2104 if self._DestructorList == None:\r
2105 if self._Header_ == None:\r
2106 self._GetHeaderInfo()\r
2107 if self._DestructorList == None:\r
2108 self._DestructorList = []\r
2109 return self._DestructorList\r
2110\r
2111 ## Retrieve definies other than above ones\r
2112 def _GetDefines(self):\r
2113 if self._Defs == None:\r
2114 if self._Header_ == None:\r
2115 self._GetHeaderInfo()\r
2116 if self._Defs == None:\r
2117 self._Defs = sdict()\r
2118 return self._Defs\r
2119\r
2120 ## Retrieve binary files\r
a0a2cd1e 2121 def _GetBinaries(self):\r
52302d4d
LG
2122 if self._Binaries == None:\r
2123 self._Binaries = []\r
2124 RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
0d2711a6
LG
2125 Macros = self._Macros\r
2126 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
2127 Macros['PROCESSOR'] = self._Arch\r
52302d4d 2128 for Record in RecordList:\r
52302d4d
LG
2129 FileType = Record[0]\r
2130 LineNo = Record[-1]\r
2131 Target = 'COMMON'\r
2132 FeatureFlag = []\r
2133 if Record[2]:\r
2134 TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
2135 if TokenList:\r
2136 Target = TokenList[0]\r
2137 if len(TokenList) > 1:\r
2138 FeatureFlag = Record[1:]\r
2139\r
2140 File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)\r
2141 # check the file validation\r
2142 ErrorCode, ErrorInfo = File.Validate()\r
2143 if ErrorCode != 0:\r
2144 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
2145 self._Binaries.append(File)\r
2146 return self._Binaries\r
2147\r
a0a2cd1e
FB
2148 ## Retrieve binary files with error check.\r
2149 def _GetBinaryFiles(self):\r
2150 Binaries = self._GetBinaries()\r
2151 if GlobalData.gIgnoreSource and Binaries == []:\r
2152 ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"\r
2153 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)\r
2154\r
2155 return Binaries\r
2156 ## Check whether it exists the binaries with current ARCH in AsBuild INF\r
2157 def _IsSupportedArch(self):\r
2158 if self._GetBinaries() and not self._GetSourceFiles():\r
2159 return True\r
2160 else:\r
2161 return False\r
52302d4d
LG
2162 ## Retrieve source files\r
2163 def _GetSourceFiles(self):\r
fae62ff2
HC
2164 #Ignore all source files in a binary build mode\r
2165 if GlobalData.gIgnoreSource:\r
2166 self._Sources = []\r
2167 return self._Sources\r
2168\r
52302d4d
LG
2169 if self._Sources == None:\r
2170 self._Sources = []\r
2171 RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
0d2711a6 2172 Macros = self._Macros\r
52302d4d 2173 for Record in RecordList:\r
52302d4d
LG
2174 LineNo = Record[-1]\r
2175 ToolChainFamily = Record[1]\r
2176 TagName = Record[2]\r
2177 ToolCode = Record[3]\r
2178 FeatureFlag = Record[4]\r
0d2711a6 2179 if self.AutoGenVersion < 0x00010005:\r
d0acc87a
LG
2180 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
2181 Macros['PROCESSOR'] = self._Arch\r
0d2711a6 2182 # old module source files (Edk)\r
52302d4d
LG
2183 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath,\r
2184 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
2185 # check the file validation\r
2186 ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
2187 if ErrorCode != 0:\r
2188 if File.Ext.lower() == '.h':\r
2189 EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,\r
2190 File=self.MetaFile, Line=LineNo)\r
2191 continue\r
2192 else:\r
2193 EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)\r
2194 else:\r
2195 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',\r
2196 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
2197 # check the file validation\r
2198 ErrorCode, ErrorInfo = File.Validate()\r
2199 if ErrorCode != 0:\r
2200 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
2201\r
2202 self._Sources.append(File)\r
2203 return self._Sources\r
2204\r
2205 ## Retrieve library classes employed by this module\r
2206 def _GetLibraryClassUses(self):\r
2207 if self._LibraryClasses == None:\r
2208 self._LibraryClasses = sdict()\r
2209 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
2210 for Record in RecordList:\r
52302d4d
LG
2211 Lib = Record[0]\r
2212 Instance = Record[1]\r
0d2711a6 2213 if Instance:\r
52302d4d
LG
2214 Instance = NormPath(Instance, self._Macros)\r
2215 self._LibraryClasses[Lib] = Instance\r
2216 return self._LibraryClasses\r
2217\r
0d2711a6 2218 ## Retrieve library names (for Edk.x style of modules)\r
52302d4d
LG
2219 def _GetLibraryNames(self):\r
2220 if self._Libraries == None:\r
2221 self._Libraries = []\r
2222 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
2223 for Record in RecordList:\r
0d2711a6
LG
2224 LibraryName = ReplaceMacro(Record[0], self._Macros, False)\r
2225 # in case of name with '.lib' extension, which is unusual in Edk.x inf\r
2226 LibraryName = os.path.splitext(LibraryName)[0]\r
52302d4d
LG
2227 if LibraryName not in self._Libraries:\r
2228 self._Libraries.append(LibraryName)\r
2229 return self._Libraries\r
2230\r
e8a47801
LG
2231 def _GetProtocolComments(self):\r
2232 self._GetProtocols()\r
2233 return self._ProtocolComments\r
52302d4d
LG
2234 ## Retrieve protocols consumed/produced by this module\r
2235 def _GetProtocols(self):\r
2236 if self._Protocols == None:\r
2237 self._Protocols = sdict()\r
e8a47801 2238 self._ProtocolComments = sdict()\r
52302d4d
LG
2239 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
2240 for Record in RecordList:\r
2241 CName = Record[0]\r
2242 Value = ProtocolValue(CName, self.Packages)\r
2243 if Value == None:\r
2244 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2245 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2246 "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
2247 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2248 self._Protocols[CName] = Value\r
e8a47801
LG
2249 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
2250 Comments = []\r
2251 for CmtRec in CommentRecords:\r
2252 Comments.append(CmtRec[0])\r
2253 self._ProtocolComments[CName] = Comments\r
52302d4d
LG
2254 return self._Protocols\r
2255\r
e8a47801
LG
2256 def _GetPpiComments(self):\r
2257 self._GetPpis()\r
2258 return self._PpiComments\r
52302d4d
LG
2259 ## Retrieve PPIs consumed/produced by this module\r
2260 def _GetPpis(self):\r
2261 if self._Ppis == None:\r
2262 self._Ppis = sdict()\r
e8a47801 2263 self._PpiComments = sdict()\r
52302d4d
LG
2264 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
2265 for Record in RecordList:\r
2266 CName = Record[0]\r
2267 Value = PpiValue(CName, self.Packages)\r
2268 if Value == None:\r
2269 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2270 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2271 "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
2272 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2273 self._Ppis[CName] = Value\r
e8a47801
LG
2274 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
2275 Comments = []\r
2276 for CmtRec in CommentRecords:\r
2277 Comments.append(CmtRec[0])\r
2278 self._PpiComments[CName] = Comments\r
52302d4d
LG
2279 return self._Ppis\r
2280\r
e8a47801
LG
2281 def _GetGuidComments(self):\r
2282 self._GetGuids()\r
2283 return self._GuidComments\r
52302d4d
LG
2284 ## Retrieve GUIDs consumed/produced by this module\r
2285 def _GetGuids(self):\r
2286 if self._Guids == None:\r
2287 self._Guids = sdict()\r
e8a47801 2288 self._GuidComments = sdict()\r
52302d4d
LG
2289 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
2290 for Record in RecordList:\r
2291 CName = Record[0]\r
2292 Value = GuidValue(CName, self.Packages)\r
2293 if Value == None:\r
2294 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2295 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2296 "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
2297 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2298 self._Guids[CName] = Value\r
e8a47801
LG
2299 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
2300 Comments = []\r
2301 for CmtRec in CommentRecords:\r
2302 Comments.append(CmtRec[0])\r
2303 self._GuidComments[CName] = Comments\r
52302d4d
LG
2304 return self._Guids\r
2305\r
0d2711a6 2306 ## Retrieve include paths necessary for this module (for Edk.x style of modules)\r
52302d4d
LG
2307 def _GetIncludes(self):\r
2308 if self._Includes == None:\r
2309 self._Includes = []\r
2310 if self._SourceOverridePath:\r
2311 self._Includes.append(self._SourceOverridePath)\r
0d2711a6
LG
2312\r
2313 Macros = self._Macros\r
2314 if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():\r
2315 Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']\r
2316 else:\r
2317 Macros['PROCESSOR'] = self._Arch\r
52302d4d 2318 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
52302d4d 2319 for Record in RecordList:\r
52302d4d 2320 if Record[0].find('EDK_SOURCE') > -1:\r
0d2711a6
LG
2321 Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
2322 File = NormPath(Record[0], self._Macros)\r
52302d4d
LG
2323 if File[0] == '.':\r
2324 File = os.path.join(self._ModuleDir, File)\r
2325 else:\r
2326 File = os.path.join(GlobalData.gWorkspace, File)\r
2327 File = RealPath(os.path.normpath(File))\r
2328 if File:\r
2329 self._Includes.append(File)\r
2330\r
2331 #TRICK: let compiler to choose correct header file\r
0d2711a6
LG
2332 Macros['EDK_SOURCE'] = GlobalData.gEdkSource\r
2333 File = NormPath(Record[0], self._Macros)\r
52302d4d
LG
2334 if File[0] == '.':\r
2335 File = os.path.join(self._ModuleDir, File)\r
2336 else:\r
2337 File = os.path.join(GlobalData.gWorkspace, File)\r
2338 File = RealPath(os.path.normpath(File))\r
2339 if File:\r
2340 self._Includes.append(File)\r
2341 else:\r
0d2711a6 2342 File = NormPath(Record[0], Macros)\r
52302d4d
LG
2343 if File[0] == '.':\r
2344 File = os.path.join(self._ModuleDir, File)\r
2345 else:\r
2346 File = os.path.join(GlobalData.gWorkspace, File)\r
2347 File = RealPath(os.path.normpath(File))\r
2348 if File:\r
2349 self._Includes.append(File)\r
2350 return self._Includes\r
2351\r
2352 ## Retrieve packages this module depends on\r
2353 def _GetPackages(self):\r
2354 if self._Packages == None:\r
2355 self._Packages = []\r
2356 RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
0d2711a6
LG
2357 Macros = self._Macros\r
2358 Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
52302d4d
LG
2359 for Record in RecordList:\r
2360 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
2361 LineNo = Record[-1]\r
2362 # check the file validation\r
2363 ErrorCode, ErrorInfo = File.Validate('.dec')\r
2364 if ErrorCode != 0:\r
2365 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
2366 # parse this package now. we need it to get protocol/ppi/guid value\r
0d2711a6 2367 Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
52302d4d
LG
2368 self._Packages.append(Package)\r
2369 return self._Packages\r
2370\r
e8a47801
LG
2371 ## Retrieve PCD comments\r
2372 def _GetPcdComments(self):\r
2373 self._GetPcds()\r
2374 return self._PcdComments\r
52302d4d
LG
2375 ## Retrieve PCDs used in this module\r
2376 def _GetPcds(self):\r
2377 if self._Pcds == None:\r
79b74a03 2378 self._Pcds = sdict()\r
e8a47801 2379 self._PcdComments = sdict()\r
52302d4d
LG
2380 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
2381 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
2382 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
2383 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
2384 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
2385 return self._Pcds\r
2386\r
2387 ## Retrieve build options specific to this module\r
2388 def _GetBuildOptions(self):\r
2389 if self._BuildOptions == None:\r
2390 self._BuildOptions = sdict()\r
2391 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]\r
2392 for Record in RecordList:\r
2393 ToolChainFamily = Record[0]\r
2394 ToolChain = Record[1]\r
2395 Option = Record[2]\r
5015bee2 2396 if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):\r
52302d4d
LG
2397 self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
2398 else:\r
2399 # concatenate the option string if they're for the same tool\r
2400 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
2401 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
2402 return self._BuildOptions\r
2403\r
0d2711a6 2404 ## Retrieve dependency expression\r
52302d4d
LG
2405 def _GetDepex(self):\r
2406 if self._Depex == None:\r
2407 self._Depex = tdict(False, 2)\r
2408 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
da92f276
LG
2409 \r
2410 # If the module has only Binaries and no Sources, then ignore [Depex] \r
2411 if self.Sources == None or self.Sources == []:\r
0d2711a6
LG
2412 if self.Binaries != None and self.Binaries != []:\r
2413 return self._Depex\r
da92f276 2414 \r
52302d4d
LG
2415 # PEIM and DXE drivers must have a valid [Depex] section\r
2416 if len(self.LibraryClass) == 0 and len(RecordList) == 0:\r
2417 if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \\r
2418 self.ModuleType == 'DXE_SAL_DRIVER' or self.ModuleType == 'DXE_RUNTIME_DRIVER':\r
2419 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
2420 % self.ModuleType, File=self.MetaFile)\r
2421\r
97fa0ee9
YL
2422 if len(RecordList) != 0 and self.ModuleType == 'USER_DEFINED':\r
2423 for Record in RecordList:\r
2424 if Record[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:\r
2425 EdkLogger.error('build', FORMAT_INVALID,\r
2426 "'%s' module must specify the type of [Depex] section" % self.ModuleType,\r
2427 File=self.MetaFile)\r
2428\r
0d2711a6 2429 Depex = sdict()\r
52302d4d 2430 for Record in RecordList:\r
0d2711a6 2431 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
52302d4d
LG
2432 Arch = Record[3]\r
2433 ModuleType = Record[4]\r
0d2711a6 2434 TokenList = DepexStr.split()\r
52302d4d
LG
2435 if (Arch, ModuleType) not in Depex:\r
2436 Depex[Arch, ModuleType] = []\r
2437 DepexList = Depex[Arch, ModuleType]\r
2438 for Token in TokenList:\r
2439 if Token in DEPEX_SUPPORTED_OPCODE:\r
2440 DepexList.append(Token)\r
2441 elif Token.endswith(".inf"): # module file name\r
2442 ModuleFile = os.path.normpath(Token)\r
2443 Module = self.BuildDatabase[ModuleFile]\r
2444 if Module == None:\r
2445 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",\r
2446 ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
2447 DepexList.append(Module.Guid)\r
2448 else:\r
2449 # get the GUID value now\r
2450 Value = ProtocolValue(Token, self.Packages)\r
2451 if Value == None:\r
2452 Value = PpiValue(Token, self.Packages)\r
2453 if Value == None:\r
2454 Value = GuidValue(Token, self.Packages)\r
2455 if Value == None:\r
2456 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2457 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2458 "Value of [%s] is not found in" % Token,\r
2459 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2460 DepexList.append(Value)\r
2461 for Arch, ModuleType in Depex:\r
2462 self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]\r
2463 return self._Depex\r
2464\r
2465 ## Retrieve depedency expression\r
2466 def _GetDepexExpression(self):\r
2467 if self._DepexExpression == None:\r
2468 self._DepexExpression = tdict(False, 2)\r
2469 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
0d2711a6 2470 DepexExpression = sdict()\r
52302d4d 2471 for Record in RecordList:\r
0d2711a6 2472 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
52302d4d
LG
2473 Arch = Record[3]\r
2474 ModuleType = Record[4]\r
0d2711a6 2475 TokenList = DepexStr.split()\r
52302d4d
LG
2476 if (Arch, ModuleType) not in DepexExpression:\r
2477 DepexExpression[Arch, ModuleType] = ''\r
2478 for Token in TokenList:\r
2479 DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '\r
2480 for Arch, ModuleType in DepexExpression:\r
2481 self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]\r
2482 return self._DepexExpression\r
2483\r
e8a47801
LG
2484 def GetGuidsUsedByPcd(self):\r
2485 return self._GuidsUsedByPcd\r
52302d4d
LG
2486 ## Retrieve PCD for given type\r
2487 def _GetPcd(self, Type):\r
79b74a03 2488 Pcds = sdict()\r
52302d4d 2489 PcdDict = tdict(True, 4)\r
6780eef1 2490 PcdList = []\r
52302d4d 2491 RecordList = self._RawData[Type, self._Arch, self._Platform]\r
e8a47801 2492 for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:\r
52302d4d 2493 PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)\r
6780eef1 2494 PcdList.append((PcdCName, TokenSpaceGuid))\r
52302d4d
LG
2495 # get the guid value\r
2496 if TokenSpaceGuid not in self.Guids:\r
2497 Value = GuidValue(TokenSpaceGuid, self.Packages)\r
2498 if Value == None:\r
2499 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2500 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2501 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,\r
2502 ExtraData=PackageList, File=self.MetaFile, Line=LineNo)\r
2503 self.Guids[TokenSpaceGuid] = Value\r
e8a47801
LG
2504 self._GuidsUsedByPcd[TokenSpaceGuid] = Value\r
2505 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]\r
2506 Comments = []\r
2507 for CmtRec in CommentRecords:\r
2508 Comments.append(CmtRec[0])\r
2509 self._PcdComments[TokenSpaceGuid, PcdCName] = Comments\r
52302d4d
LG
2510\r
2511 # resolve PCD type, value, datum info, etc. by getting its definition from package\r
6780eef1 2512 for PcdCName, TokenSpaceGuid in PcdList:\r
52302d4d
LG
2513 Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
2514 if Setting == None:\r
2515 continue\r
6780eef1 2516 ValueList = AnalyzePcdData(Setting)\r
52302d4d
LG
2517 DefaultValue = ValueList[0]\r
2518 Pcd = PcdClassObject(\r
2519 PcdCName,\r
2520 TokenSpaceGuid,\r
2521 '',\r
2522 '',\r
2523 DefaultValue,\r
2524 '',\r
2525 '',\r
2526 {},\r
e56468c0 2527 False,\r
52302d4d
LG
2528 self.Guids[TokenSpaceGuid]\r
2529 )\r
e8a47801
LG
2530 if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:\r
2531 # Patch PCD: TokenSpace.PcdCName|Value|Offset\r
2532 Pcd.Offset = ValueList[1]\r
52302d4d
LG
2533\r
2534 # get necessary info from package declaring this PCD\r
2535 for Package in self.Packages:\r
2536 #\r
2537 # 'dynamic' in INF means its type is determined by platform;\r
2538 # if platform doesn't give its type, use 'lowest' one in the\r
2539 # following order, if any\r
2540 #\r
2541 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"\r
2542 #\r
2543 PcdType = self._PCD_TYPE_STRING_[Type]\r
e56468c0 2544 if Type == MODEL_PCD_DYNAMIC:\r
52302d4d
LG
2545 Pcd.Pending = True\r
2546 for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
2547 if (PcdCName, TokenSpaceGuid, T) in Package.Pcds:\r
2548 PcdType = T\r
2549 break\r
2550 else:\r
2551 Pcd.Pending = False\r
2552\r
2553 if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
2554 PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]\r
2555 Pcd.Type = PcdType\r
2556 Pcd.TokenValue = PcdInPackage.TokenValue\r
6780eef1
LG
2557 \r
2558 #\r
2559 # Check whether the token value exist or not.\r
2560 #\r
2561 if Pcd.TokenValue == None or Pcd.TokenValue == "":\r
2562 EdkLogger.error(\r
2563 'build',\r
2564 FORMAT_INVALID,\r
2565 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdCName, str(Package)),\r
2566 File =self.MetaFile, Line=LineNo,\r
2567 ExtraData=None\r
2568 ) \r
2569 #\r
2570 # Check hexadecimal token value length and format.\r
2571 #\r
79b74a03 2572 ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)\r
6780eef1 2573 if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):\r
79b74a03 2574 if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:\r
6780eef1
LG
2575 EdkLogger.error(\r
2576 'build',\r
2577 FORMAT_INVALID,\r
2578 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
2579 File =self.MetaFile, Line=LineNo,\r
2580 ExtraData=None\r
2581 )\r
2582 \r
2583 #\r
2584 # Check decimal token value length and format.\r
2585 # \r
2586 else:\r
2587 try:\r
2588 TokenValueInt = int (Pcd.TokenValue, 10)\r
2589 if (TokenValueInt < 0 or TokenValueInt > 4294967295):\r
2590 EdkLogger.error(\r
2591 'build',\r
2592 FORMAT_INVALID,\r
2593 "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
2594 File =self.MetaFile, Line=LineNo,\r
2595 ExtraData=None\r
2596 ) \r
2597 except:\r
2598 EdkLogger.error(\r
2599 'build',\r
2600 FORMAT_INVALID,\r
2601 "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
2602 File =self.MetaFile, Line=LineNo,\r
2603 ExtraData=None\r
2604 )\r
2605 \r
52302d4d
LG
2606 Pcd.DatumType = PcdInPackage.DatumType\r
2607 Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
2608 Pcd.InfDefaultValue = Pcd.DefaultValue\r
2609 if Pcd.DefaultValue in [None, '']:\r
2610 Pcd.DefaultValue = PcdInPackage.DefaultValue\r
2611 break\r
2612 else:\r
2613 EdkLogger.error(\r
2614 'build',\r
6780eef1 2615 FORMAT_INVALID,\r
52302d4d
LG
2616 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),\r
2617 File =self.MetaFile, Line=LineNo,\r
2618 ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])\r
2619 )\r
2620 Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
6780eef1 2621\r
52302d4d
LG
2622 return Pcds\r
2623\r
e8a47801
LG
2624 ## check whether current module is binary module\r
2625 def _IsBinaryModule(self):\r
2626 if self.Binaries and not self.Sources:\r
2627 return True\r
2628 elif GlobalData.gIgnoreSource:\r
2629 return True\r
2630 else:\r
2631 return False\r
2632\r
2633 _Macros = property(_GetMacros)\r
2634 Arch = property(_GetArch, _SetArch)\r
2635 Platform = property(_GetPlatform, _SetPlatform)\r
52302d4d 2636\r
e8a47801 2637 HeaderComments = property(_GetHeaderComments)\r
2bc3256c 2638 TailComments = property(_GetTailComments)\r
52302d4d
LG
2639 AutoGenVersion = property(_GetInfVersion)\r
2640 BaseName = property(_GetBaseName)\r
2641 ModuleType = property(_GetModuleType)\r
2642 ComponentType = property(_GetComponentType)\r
2643 BuildType = property(_GetBuildType)\r
2644 Guid = property(_GetFileGuid)\r
2645 Version = property(_GetVersion)\r
2646 PcdIsDriver = property(_GetPcdIsDriver)\r
2647 Shadow = property(_GetShadow)\r
2648 CustomMakefile = property(_GetMakefile)\r
2649 Specification = property(_GetSpec)\r
2650 LibraryClass = property(_GetLibraryClass)\r
2651 ModuleEntryPointList = property(_GetEntryPoint)\r
2652 ModuleUnloadImageList = property(_GetUnloadImage)\r
2653 ConstructorList = property(_GetConstructor)\r
2654 DestructorList = property(_GetDestructor)\r
2655 Defines = property(_GetDefines)\r
b36d134f
LG
2656 DxsFile = property(_GetDxsFile)\r
2657 \r
52302d4d
LG
2658 Binaries = property(_GetBinaryFiles)\r
2659 Sources = property(_GetSourceFiles)\r
2660 LibraryClasses = property(_GetLibraryClassUses)\r
2661 Libraries = property(_GetLibraryNames)\r
2662 Protocols = property(_GetProtocols)\r
e8a47801 2663 ProtocolComments = property(_GetProtocolComments)\r
52302d4d 2664 Ppis = property(_GetPpis)\r
e8a47801 2665 PpiComments = property(_GetPpiComments)\r
52302d4d 2666 Guids = property(_GetGuids)\r
e8a47801 2667 GuidComments = property(_GetGuidComments)\r
52302d4d
LG
2668 Includes = property(_GetIncludes)\r
2669 Packages = property(_GetPackages)\r
2670 Pcds = property(_GetPcds)\r
e8a47801 2671 PcdComments = property(_GetPcdComments)\r
52302d4d
LG
2672 BuildOptions = property(_GetBuildOptions)\r
2673 Depex = property(_GetDepex)\r
2674 DepexExpression = property(_GetDepexExpression)\r
e8a47801 2675 IsBinaryModule = property(_IsBinaryModule)\r
a0a2cd1e 2676 IsSupportedArch = property(_IsSupportedArch)\r
52302d4d
LG
2677\r
2678## Database\r
2679#\r
e56468c0 2680# This class defined the build database for all modules, packages and platform.\r
52302d4d
LG
2681# It will call corresponding parser for the given file if it cannot find it in\r
2682# the database.\r
2683#\r
2684# @param DbPath Path of database file\r
2685# @param GlobalMacros Global macros used for replacement during file parsing\r
2686# @prarm RenewDb=False Create new database file if it's already there\r
2687#\r
2688class WorkspaceDatabase(object):\r
52302d4d 2689\r
52302d4d
LG
2690\r
2691 #\r
2692 # internal class used for call corresponding file parser and caching the result\r
2693 # to avoid unnecessary re-parsing\r
2694 #\r
2695 class BuildObjectFactory(object):\r
0d2711a6 2696\r
52302d4d
LG
2697 _FILE_TYPE_ = {\r
2698 ".inf" : MODEL_FILE_INF,\r
2699 ".dec" : MODEL_FILE_DEC,\r
2700 ".dsc" : MODEL_FILE_DSC,\r
0d2711a6
LG
2701 }\r
2702\r
2703 # file parser\r
2704 _FILE_PARSER_ = {\r
2705 MODEL_FILE_INF : InfParser,\r
2706 MODEL_FILE_DEC : DecParser,\r
2707 MODEL_FILE_DSC : DscParser,\r
52302d4d
LG
2708 }\r
2709\r
2710 # convert to xxxBuildData object\r
2711 _GENERATOR_ = {\r
2712 MODEL_FILE_INF : InfBuildData,\r
2713 MODEL_FILE_DEC : DecBuildData,\r
2714 MODEL_FILE_DSC : DscBuildData,\r
52302d4d
LG
2715 }\r
2716\r
2717 _CACHE_ = {} # (FilePath, Arch) : <object>\r
2718\r
2719 # constructor\r
2720 def __init__(self, WorkspaceDb):\r
2721 self.WorkspaceDb = WorkspaceDb\r
2722\r
0d2711a6 2723 # key = (FilePath, Arch=None)\r
52302d4d
LG
2724 def __contains__(self, Key):\r
2725 FilePath = Key[0]\r
52302d4d
LG
2726 if len(Key) > 1:\r
2727 Arch = Key[1]\r
0d2711a6
LG
2728 else:\r
2729 Arch = None\r
52302d4d
LG
2730 return (FilePath, Arch) in self._CACHE_\r
2731\r
0d2711a6 2732 # key = (FilePath, Arch=None, Target=None, Toochain=None)\r
52302d4d
LG
2733 def __getitem__(self, Key):\r
2734 FilePath = Key[0]\r
0d2711a6
LG
2735 KeyLength = len(Key)\r
2736 if KeyLength > 1:\r
52302d4d 2737 Arch = Key[1]\r
0d2711a6
LG
2738 else:\r
2739 Arch = None\r
2740 if KeyLength > 2:\r
2741 Target = Key[2]\r
2742 else:\r
2743 Target = None\r
2744 if KeyLength > 3:\r
2745 Toolchain = Key[3]\r
2746 else:\r
2747 Toolchain = None\r
52302d4d
LG
2748\r
2749 # if it's generated before, just return the cached one\r
0d2711a6 2750 Key = (FilePath, Arch, Target, Toolchain)\r
52302d4d
LG
2751 if Key in self._CACHE_:\r
2752 return self._CACHE_[Key]\r
2753\r
2754 # check file type\r
0d2711a6 2755 Ext = FilePath.Type\r
52302d4d
LG
2756 if Ext not in self._FILE_TYPE_:\r
2757 return None\r
2758 FileType = self._FILE_TYPE_[Ext]\r
2759 if FileType not in self._GENERATOR_:\r
2760 return None\r
2761\r
0d2711a6
LG
2762 # get the parser ready for this file\r
2763 MetaFile = self._FILE_PARSER_[FileType](\r
2764 FilePath, \r
2765 FileType, \r
2766 MetaFileStorage(self.WorkspaceDb.Cur, FilePath, FileType)\r
2767 )\r
2768 # alwasy do post-process, in case of macros change\r
2769 MetaFile.DoPostProcess()\r
2770 # object the build is based on\r
52302d4d
LG
2771 BuildObject = self._GENERATOR_[FileType](\r
2772 FilePath,\r
2773 MetaFile,\r
2774 self,\r
2775 Arch,\r
0d2711a6
LG
2776 Target,\r
2777 Toolchain\r
52302d4d
LG
2778 )\r
2779 self._CACHE_[Key] = BuildObject\r
2780 return BuildObject\r
2781\r
2782 # placeholder for file format conversion\r
2783 class TransformObjectFactory:\r
2784 def __init__(self, WorkspaceDb):\r
2785 self.WorkspaceDb = WorkspaceDb\r
2786\r
2787 # key = FilePath, Arch\r
2788 def __getitem__(self, Key):\r
2789 pass\r
2790\r
2791 ## Constructor of WorkspaceDatabase\r
2792 #\r
2793 # @param DbPath Path of database file\r
2794 # @param GlobalMacros Global macros used for replacement during file parsing\r
2795 # @prarm RenewDb=False Create new database file if it's already there\r
2796 #\r
0d2711a6 2797 def __init__(self, DbPath, RenewDb=False):\r
4234283c 2798 self._DbClosedFlag = False\r
0d2711a6 2799 if not DbPath:\r
97fa0ee9 2800 DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, 'Conf', GlobalData.gDatabasePath))\r
52302d4d
LG
2801\r
2802 # don't create necessary path for db in memory\r
2803 if DbPath != ':memory:':\r
2804 DbDir = os.path.split(DbPath)[0]\r
2805 if not os.path.exists(DbDir):\r
2806 os.makedirs(DbDir)\r
2807\r
2808 # remove db file in case inconsistency between db and file in file system\r
2809 if self._CheckWhetherDbNeedRenew(RenewDb, DbPath):\r
2810 os.remove(DbPath)\r
2811 \r
2812 # create db with optimized parameters\r
2813 self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED')\r
2814 self.Conn.execute("PRAGMA synchronous=OFF")\r
2815 self.Conn.execute("PRAGMA temp_store=MEMORY")\r
2816 self.Conn.execute("PRAGMA count_changes=OFF")\r
2817 self.Conn.execute("PRAGMA cache_size=8192")\r
2818 #self.Conn.execute("PRAGMA page_size=8192")\r
2819\r
2820 # to avoid non-ascii character conversion issue\r
2821 self.Conn.text_factory = str\r
2822 self.Cur = self.Conn.cursor()\r
2823\r
2824 # create table for internal uses\r
2825 self.TblDataModel = TableDataModel(self.Cur)\r
2826 self.TblFile = TableFile(self.Cur)\r
0d2711a6 2827 self.Platform = None\r
52302d4d
LG
2828\r
2829 # conversion object for build or file format conversion purpose\r
2830 self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)\r
2831 self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)\r
2832\r
2833 ## Check whether workspace database need to be renew.\r
2834 # The renew reason maybe:\r
2835 # 1) If user force to renew;\r
2836 # 2) If user do not force renew, and\r
2837 # a) If the time of last modified python source is newer than database file;\r
2838 # b) If the time of last modified frozen executable file is newer than database file;\r
2839 #\r
2840 # @param force User force renew database\r
2841 # @param DbPath The absolute path of workspace database file\r
2842 #\r
2843 # @return Bool value for whether need renew workspace databse\r
2844 #\r
2845 def _CheckWhetherDbNeedRenew (self, force, DbPath):\r
52302d4d
LG
2846 # if database does not exist, we need do nothing\r
2847 if not os.path.exists(DbPath): return False\r
2848 \r
2849 # if user force to renew database, then not check whether database is out of date\r
2850 if force: return True\r
2851 \r
2852 # \r
2853 # Check the time of last modified source file or build.exe\r
2854 # if is newer than time of database, then database need to be re-created.\r
2855 #\r
2856 timeOfToolModified = 0\r
2857 if hasattr(sys, "frozen"):\r
2858 exePath = os.path.abspath(sys.executable)\r
2859 timeOfToolModified = os.stat(exePath).st_mtime\r
2860 else:\r
2861 curPath = os.path.dirname(__file__) # curPath is the path of WorkspaceDatabase.py\r
2862 rootPath = os.path.split(curPath)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python\r
2863 if rootPath == "" or rootPath == None:\r
2864 EdkLogger.verbose("\nFail to find the root path of build.exe or python sources, so can not \\r
2865determine whether database file is out of date!\n")\r
2866 \r
2867 # walk the root path of source or build's binary to get the time last modified.\r
2868 \r
2869 for root, dirs, files in os.walk (rootPath):\r
2870 for dir in dirs:\r
2871 # bypass source control folder \r
2872 if dir.lower() in [".svn", "_svn", "cvs"]:\r
2873 dirs.remove(dir)\r
2874 \r
2875 for file in files:\r
2876 ext = os.path.splitext(file)[1]\r
2877 if ext.lower() == ".py": # only check .py files\r
2878 fd = os.stat(os.path.join(root, file))\r
2879 if timeOfToolModified < fd.st_mtime:\r
2880 timeOfToolModified = fd.st_mtime\r
2881 if timeOfToolModified > os.stat(DbPath).st_mtime:\r
2882 EdkLogger.verbose("\nWorkspace database is out of data!")\r
2883 return True\r
2884 \r
2885 return False\r
2886 \r
2887 ## Initialize build database\r
2888 def InitDatabase(self):\r
2889 EdkLogger.verbose("\nInitialize build database started ...")\r
2890\r
2891 #\r
2892 # Create new tables\r
2893 #\r
2894 self.TblDataModel.Create(False)\r
2895 self.TblFile.Create(False)\r
2896\r
2897 #\r
2898 # Initialize table DataModel\r
2899 #\r
2900 self.TblDataModel.InitTable()\r
2901 EdkLogger.verbose("Initialize build database ... DONE!")\r
2902\r
2903 ## Query a table\r
2904 #\r
2905 # @param Table: The instance of the table to be queried\r
2906 #\r
2907 def QueryTable(self, Table):\r
2908 Table.Query()\r
2909\r
0d2711a6
LG
2910 def __del__(self):\r
2911 self.Close()\r
2912\r
52302d4d
LG
2913 ## Close entire database\r
2914 #\r
2915 # Commit all first\r
2916 # Close the connection and cursor\r
2917 #\r
2918 def Close(self):\r
4234283c
LG
2919 if not self._DbClosedFlag:\r
2920 self.Conn.commit()\r
2921 self.Cur.close()\r
2922 self.Conn.close()\r
2923 self._DbClosedFlag = True\r
52302d4d 2924\r
52302d4d 2925 ## Summarize all packages in the database\r
0d2711a6
LG
2926 def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):\r
2927 self.Platform = Platform\r
2928 PackageList =[]\r
2929 Pa = self.BuildObject[self.Platform, 'COMMON']\r
2930 #\r
2931 # Get Package related to Modules\r
2932 #\r
2933 for Module in Pa.Modules:\r
2934 ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag]\r
2935 for Package in ModuleObj.Packages:\r
52302d4d
LG
2936 if Package not in PackageList:\r
2937 PackageList.append(Package)\r
0d2711a6
LG
2938 #\r
2939 # Get Packages related to Libraries\r
2940 #\r
2941 for Lib in Pa.LibraryInstances:\r
2942 LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]\r
2943 for Package in LibObj.Packages:\r
2944 if Package not in PackageList:\r
2945 PackageList.append(Package) \r
2946 \r
52302d4d
LG
2947 return PackageList\r
2948\r
2949 ## Summarize all platforms in the database\r
2950 def _GetPlatformList(self):\r
2951 PlatformList = []\r
2952 for PlatformFile in self.TblFile.GetFileList(MODEL_FILE_DSC):\r
2953 try:\r
2954 Platform = self.BuildObject[PathClass(PlatformFile), 'COMMON']\r
2955 except:\r
2956 Platform = None\r
2957 if Platform != None:\r
2958 PlatformList.append(Platform)\r
2959 return PlatformList\r
2960\r
52302d4d 2961 PlatformList = property(_GetPlatformList)\r
52302d4d
LG
2962\r
2963##\r
2964#\r
2965# This acts like the main() function for the script, unless it is 'import'ed into another\r
2966# script.\r
2967#\r
2968if __name__ == '__main__':\r
2969 pass\r
2970\r