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