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