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