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