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