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