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