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