]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
BaseTools: fix the bug to build a compressed ROM image via .INF 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
805 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]\r
806 for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList:\r
5015bee2 807 if Type == DriverType:\r
1ba5124e 808 Key = (ToolChainFamily, ToolChain, Edk)\r
5015bee2 809 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
1ba5124e
YL
810 options[Key] = Option\r
811 else:\r
812 options[Key] += ' ' + Option\r
35f69db9
YL
813 return self._ModuleTypeOptions[Edk, ModuleType]\r
814\r
52302d4d
LG
815 ## Retrieve non-dynamic PCD settings\r
816 #\r
817 # @param Type PCD type\r
818 #\r
819 # @retval a dict object contains settings of given PCD type\r
820 #\r
821 def _GetPcd(self, Type):\r
0d2711a6 822 Pcds = sdict()\r
52302d4d
LG
823 #\r
824 # tdict is a special dict kind of type, used for selecting correct\r
825 # PCD settings for certain ARCH\r
826 #\r
e8a47801
LG
827 \r
828 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
829 \r
52302d4d
LG
830 PcdDict = tdict(True, 3)\r
831 PcdSet = set()\r
832 # Find out all possible PCD candidates for self._Arch\r
833 RecordList = self._RawData[Type, self._Arch]\r
e8a47801 834 PcdValueDict = sdict()\r
52302d4d 835 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
836 if SkuName in (SkuObj.SystemSkuId,'DEFAULT','COMMON'):\r
837 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
838 PcdDict[Arch, PcdCName, TokenSpaceGuid,SkuName] = Setting\r
839 \r
840 #handle pcd value override \r
841 for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdSet:\r
842 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid,SkuName]\r
52302d4d
LG
843 if Setting == None:\r
844 continue\r
4afd3d04 845 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
e8a47801
LG
846 if (PcdCName, TokenSpaceGuid) in PcdValueDict:\r
847 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue,DatumType,MaxDatumSize) \r
848 else:\r
849 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue,DatumType,MaxDatumSize)} \r
850 \r
851 PcdsKeys = PcdValueDict.keys()\r
852 for PcdCName,TokenSpaceGuid in PcdsKeys:\r
853 \r
854 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]\r
855 PcdValue = None\r
856 DatumType = None\r
857 MaxDatumSize = None\r
858 if 'COMMON' in PcdSetting:\r
859 PcdValue,DatumType,MaxDatumSize = PcdSetting['COMMON']\r
860 if 'DEFAULT' in PcdSetting:\r
861 PcdValue,DatumType,MaxDatumSize = PcdSetting['DEFAULT']\r
862 if SkuObj.SystemSkuId in PcdSetting:\r
863 PcdValue,DatumType,MaxDatumSize = PcdSetting[SkuObj.SystemSkuId]\r
864 \r
52302d4d
LG
865 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
866 PcdCName,\r
867 TokenSpaceGuid,\r
868 self._PCD_TYPE_STRING_[Type],\r
869 DatumType,\r
870 PcdValue,\r
871 '',\r
872 MaxDatumSize,\r
873 {},\r
e56468c0 874 False,\r
52302d4d
LG
875 None\r
876 )\r
877 return Pcds\r
878\r
879 ## Retrieve dynamic PCD settings\r
880 #\r
881 # @param Type PCD type\r
882 #\r
883 # @retval a dict object contains settings of given PCD type\r
884 #\r
885 def _GetDynamicPcd(self, Type):\r
e8a47801
LG
886 \r
887 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
888 \r
0d2711a6 889 Pcds = sdict()\r
52302d4d
LG
890 #\r
891 # tdict is a special dict kind of type, used for selecting correct\r
892 # PCD settings for certain ARCH and SKU\r
893 #\r
894 PcdDict = tdict(True, 4)\r
6780eef1 895 PcdList = []\r
52302d4d
LG
896 # Find out all possible PCD candidates for self._Arch\r
897 RecordList = self._RawData[Type, self._Arch]\r
e8a47801
LG
898 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
899 \r
900 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
52302d4d 901 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
902 if SkuName not in AvailableSkuIdSet:\r
903 continue\r
904 \r
905 PcdList.append((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
52302d4d
LG
906 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
907 # Remove redundant PCD candidates, per the ARCH and SKU\r
e8a47801
LG
908 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:\r
909 \r
910 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
52302d4d
LG
911 if Setting == None:\r
912 continue\r
6780eef1 913 \r
4afd3d04 914 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
e8a47801
LG
915 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue)\r
916 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
917 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
918 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2bc3256c
LG
919 if MaxDatumSize.strip():\r
920 CurrentMaxSize = int(MaxDatumSize.strip(),0)\r
921 else:\r
922 CurrentMaxSize = 0\r
923 if pcdObject.MaxDatumSize:\r
924 PcdMaxSize = int(pcdObject.MaxDatumSize,0)\r
925 else:\r
926 PcdMaxSize = 0\r
927 if CurrentMaxSize > PcdMaxSize:\r
928 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
e8a47801
LG
929 else: \r
930 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
931 PcdCName,\r
932 TokenSpaceGuid,\r
933 self._PCD_TYPE_STRING_[Type],\r
934 DatumType,\r
935 PcdValue,\r
936 '',\r
937 MaxDatumSize,\r
938 {SkuName : SkuInfo},\r
939 False,\r
940 None\r
941 )\r
942 \r
943 for pcd in Pcds.values():\r
2bc3256c
LG
944 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
945 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): \r
e8a47801
LG
946 valuefromDec = pcdDecObject.DefaultValue\r
947 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)\r
948 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
949 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
950 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
951 del(pcd.SkuInfoList['COMMON'])\r
952 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
953 del(pcd.SkuInfoList['COMMON'])\r
954 if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
955 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
956 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
957 del(pcd.SkuInfoList['DEFAULT'])\r
2bc3256c 958 \r
52302d4d
LG
959 return Pcds\r
960\r
82a6a960
BF
961 def CompareVarAttr(self, Attr1, Attr2):\r
962 if not Attr1 or not Attr2: # for empty string\r
963 return True\r
964 Attr1s = [attr.strip() for attr in Attr1.split(",")]\r
965 Attr1Set = set(Attr1s)\r
966 Attr2s = [attr.strip() for attr in Attr2.split(",")]\r
967 Attr2Set = set(Attr2s)\r
968 if Attr2Set == Attr1Set:\r
969 return True\r
970 else:\r
971 return False\r
52302d4d
LG
972 ## Retrieve dynamic HII PCD settings\r
973 #\r
974 # @param Type PCD type\r
975 #\r
976 # @retval a dict object contains settings of given PCD type\r
977 #\r
978 def _GetDynamicHiiPcd(self, Type):\r
e8a47801
LG
979 \r
980 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
82a6a960 981 VariableAttrs = {}\r
e8a47801 982 \r
0d2711a6 983 Pcds = sdict()\r
52302d4d
LG
984 #\r
985 # tdict is a special dict kind of type, used for selecting correct\r
986 # PCD settings for certain ARCH and SKU\r
987 #\r
988 PcdDict = tdict(True, 4)\r
989 PcdSet = set()\r
990 RecordList = self._RawData[Type, self._Arch]\r
991 # Find out all possible PCD candidates for self._Arch\r
e8a47801
LG
992 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
993 \r
994 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
52302d4d 995 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
996 if SkuName not in AvailableSkuIdSet:\r
997 continue\r
998 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))\r
52302d4d
LG
999 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1000 # Remove redundant PCD candidates, per the ARCH and SKU\r
e8a47801
LG
1001 for PcdCName, TokenSpaceGuid,SkuName, Dummy4 in PcdSet:\r
1002 \r
1003 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
52302d4d
LG
1004 if Setting == None:\r
1005 continue\r
82a6a960 1006 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
2bc3256c 1007 \r
82a6a960
BF
1008 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)\r
1009 if not rt:\r
1010 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),\r
1011 ExtraData = "[%s]" % VarAttribute)\r
2bc3256c 1012 ExceedMax = False\r
e4ac870f 1013 FormatCorrect = True\r
2bc3256c
LG
1014 if VariableOffset.isdigit():\r
1015 if int(VariableOffset,10) > 0xFFFF:\r
1016 ExceedMax = True\r
1017 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset):\r
1018 if int(VariableOffset,16) > 0xFFFF:\r
1019 ExceedMax = True\r
e4ac870f
LG
1020 # For Offset written in "A.B"\r
1021 elif VariableOffset.find('.') > -1:\r
1022 VariableOffsetList = VariableOffset.split(".")\r
1023 if not (len(VariableOffsetList) == 2\r
1024 and IsValidWord(VariableOffsetList[0])\r
1025 and IsValidWord(VariableOffsetList[1])):\r
1026 FormatCorrect = False\r
2bc3256c 1027 else:\r
e4ac870f
LG
1028 FormatCorrect = False\r
1029 if not FormatCorrect:\r
2bc3256c
LG
1030 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid,PcdCName)))\r
1031 \r
1032 if ExceedMax:\r
1033 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
1034 if (VariableName, VariableGuid) not in VariableAttrs:\r
1035 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute\r
1036 else:\r
1037 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):\r
1038 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 1039 \r
82a6a960
BF
1040 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute = VarAttribute)\r
1041 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]\r
e8a47801
LG
1042 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
1043 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
1044 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
1045 else:\r
1046 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
52302d4d
LG
1047 PcdCName,\r
1048 TokenSpaceGuid,\r
1049 self._PCD_TYPE_STRING_[Type],\r
1050 '',\r
1051 DefaultValue,\r
1052 '',\r
1053 '',\r
e8a47801 1054 {SkuName : SkuInfo},\r
e56468c0 1055 False,\r
82a6a960
BF
1056 None,\r
1057 pcdDecObject.validateranges,\r
1058 pcdDecObject.validlists,\r
1059 pcdDecObject.expressions\r
52302d4d 1060 )\r
e8a47801
LG
1061 \r
1062\r
1063 for pcd in Pcds.values():\r
1064 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
2bc3256c
LG
1065 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
1066 # Only fix the value while no value provided in DSC file.\r
1067 for sku in pcd.SkuInfoList.values():\r
1068 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue==None):\r
1069 sku.HiiDefaultValue = pcdDecObject.DefaultValue\r
1070 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): \r
e8a47801
LG
1071 valuefromDec = pcdDecObject.DefaultValue\r
1072 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)\r
1073 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1074 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1075 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1076 del(pcd.SkuInfoList['COMMON'])\r
1077 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1078 del(pcd.SkuInfoList['COMMON'])\r
1079 \r
1080 if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
1081 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
1082 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
1083 del(pcd.SkuInfoList['DEFAULT'])\r
2bc3256c
LG
1084 \r
1085 \r
1086 if pcd.MaxDatumSize.strip(): \r
1087 MaxSize = int(pcd.MaxDatumSize,0)\r
1088 else:\r
1089 MaxSize = 0\r
1090 if pcdDecObject.DatumType == 'VOID*':\r
1091 for (skuname,skuobj) in pcd.SkuInfoList.items():\r
1092 datalen = 0\r
1093 if skuobj.HiiDefaultValue.startswith("L"):\r
1094 datalen = (len(skuobj.HiiDefaultValue)- 3 + 1) * 2\r
1095 elif skuobj.HiiDefaultValue.startswith("{"):\r
1096 datalen = len(skuobj.HiiDefaultValue.split(","))\r
1097 else:\r
1098 datalen = len(skuobj.HiiDefaultValue) -2 + 1 \r
1099 if datalen>MaxSize:\r
1100 MaxSize = datalen\r
1101 pcd.MaxDatumSize = str(MaxSize)\r
52302d4d
LG
1102 return Pcds\r
1103\r
1104 ## Retrieve dynamic VPD PCD settings\r
1105 #\r
1106 # @param Type PCD type\r
1107 #\r
1108 # @retval a dict object contains settings of given PCD type\r
1109 #\r
1110 def _GetDynamicVpdPcd(self, Type):\r
e8a47801
LG
1111 \r
1112 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)\r
1113 \r
0d2711a6 1114 Pcds = sdict()\r
52302d4d
LG
1115 #\r
1116 # tdict is a special dict kind of type, used for selecting correct\r
1117 # PCD settings for certain ARCH and SKU\r
1118 #\r
1119 PcdDict = tdict(True, 4)\r
6780eef1 1120 PcdList = []\r
52302d4d
LG
1121 # Find out all possible PCD candidates for self._Arch\r
1122 RecordList = self._RawData[Type, self._Arch]\r
e8a47801
LG
1123 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()\r
1124 \r
1125 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})\r
52302d4d 1126 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:\r
e8a47801
LG
1127 if SkuName not in AvailableSkuIdSet:\r
1128 continue\r
1129\r
1130 PcdList.append((PcdCName, TokenSpaceGuid,SkuName, Dummy4))\r
52302d4d
LG
1131 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting\r
1132 # Remove redundant PCD candidates, per the ARCH and SKU\r
e8a47801
LG
1133 for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdList:\r
1134 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]\r
52302d4d
LG
1135 if Setting == None:\r
1136 continue\r
e56468c0 1137 #\r
1138 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue\r
1139 # For the Integer & Boolean type, the optional data can only be InitialValue.\r
1140 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype\r
1141 # until the DEC parser has been called.\r
1142 # \r
4afd3d04 1143 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)\r
e8a47801
LG
1144 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue)\r
1145 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): \r
1146 pcdObject = Pcds[PcdCName,TokenSpaceGuid]\r
1147 pcdObject.SkuInfoList[SkuName] = SkuInfo\r
2bc3256c
LG
1148 if MaxDatumSize.strip():\r
1149 CurrentMaxSize = int(MaxDatumSize.strip(),0)\r
1150 else:\r
1151 CurrentMaxSize = 0\r
1152 if pcdObject.MaxDatumSize:\r
1153 PcdMaxSize = int(pcdObject.MaxDatumSize,0)\r
1154 else:\r
1155 PcdMaxSize = 0\r
1156 if CurrentMaxSize > PcdMaxSize:\r
1157 pcdObject.MaxDatumSize = str(CurrentMaxSize)\r
e8a47801
LG
1158 else:\r
1159 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(\r
52302d4d
LG
1160 PcdCName,\r
1161 TokenSpaceGuid,\r
1162 self._PCD_TYPE_STRING_[Type],\r
1163 '',\r
37fe82ee 1164 InitialValue,\r
52302d4d
LG
1165 '',\r
1166 MaxDatumSize,\r
e8a47801 1167 {SkuName : SkuInfo},\r
e56468c0 1168 False,\r
52302d4d
LG
1169 None\r
1170 )\r
e8a47801
LG
1171 for pcd in Pcds.values():\r
1172 SkuInfoObj = pcd.SkuInfoList.values()[0]\r
2bc3256c 1173 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]\r
e8a47801 1174 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():\r
e8a47801
LG
1175 valuefromDec = pcdDecObject.DefaultValue\r
1176 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj.VpdOffset, valuefromDec)\r
1177 pcd.SkuInfoList['DEFAULT'] = SkuInfo\r
1178 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1179 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']\r
1180 del(pcd.SkuInfoList['COMMON'])\r
1181 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():\r
1182 del(pcd.SkuInfoList['COMMON'])\r
1183 if SkuObj.SkuUsageType == SkuObj.SINGLE:\r
1184 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():\r
1185 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']\r
1186 del(pcd.SkuInfoList['DEFAULT'])\r
1187 \r
52302d4d
LG
1188 return Pcds\r
1189\r
1190 ## Add external modules\r
1191 #\r
1192 # The external modules are mostly those listed in FDF file, which don't\r
1193 # need "build".\r
1194 #\r
1195 # @param FilePath The path of module description file\r
1196 #\r
1197 def AddModule(self, FilePath):\r
1198 FilePath = NormPath(FilePath)\r
1199 if FilePath not in self.Modules:\r
1200 Module = ModuleBuildClassObject()\r
1201 Module.MetaFile = FilePath\r
1202 self.Modules.append(Module)\r
1203\r
1204 ## Add external PCDs\r
1205 #\r
1206 # The external PCDs are mostly those listed in FDF file to specify address\r
1207 # or offset information.\r
1208 #\r
1209 # @param Name Name of the PCD\r
1210 # @param Guid Token space guid of the PCD\r
1211 # @param Value Value of the PCD\r
1212 #\r
1213 def AddPcd(self, Name, Guid, Value):\r
1214 if (Name, Guid) not in self.Pcds:\r
e56468c0 1215 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)\r
52302d4d
LG
1216 self.Pcds[Name, Guid].DefaultValue = Value\r
1217\r
0d2711a6 1218 _Macros = property(_GetMacros)\r
52302d4d
LG
1219 Arch = property(_GetArch, _SetArch)\r
1220 Platform = property(_GetPlatformName)\r
1221 PlatformName = property(_GetPlatformName)\r
1222 Guid = property(_GetFileGuid)\r
1223 Version = property(_GetVersion)\r
1224 DscSpecification = property(_GetDscSpec)\r
1225 OutputDirectory = property(_GetOutpuDir)\r
1226 SupArchList = property(_GetSupArch)\r
1227 BuildTargets = property(_GetBuildTarget)\r
1228 SkuName = property(_GetSkuName, _SetSkuName)\r
e8a47801 1229 SkuIdentifier = property(_GetSkuIdentifier)\r
1ae469b9 1230 AvilableSkuIds = property(_GetAviableSkuIds)\r
e8a47801 1231 PcdInfoFlag = property(_GetPcdInfoFlag)\r
82a6a960 1232 VarCheckFlag = property(_GetVarCheckFlag)\r
52302d4d 1233 FlashDefinition = property(_GetFdfFile)\r
f0dc69e6
YZ
1234 Prebuild = property(_GetPrebuild)\r
1235 Postbuild = property(_GetPostbuild)\r
52302d4d
LG
1236 BuildNumber = property(_GetBuildNumber)\r
1237 MakefileName = property(_GetMakefileName)\r
1238 BsBaseAddress = property(_GetBsBaseAddress)\r
1239 RtBaseAddress = property(_GetRtBaseAddress)\r
1240 LoadFixAddress = property(_GetLoadFixAddress)\r
6780eef1
LG
1241 RFCLanguages = property(_GetRFCLanguages)\r
1242 ISOLanguages = property(_GetISOLanguages)\r
08dd311f 1243 VpdToolGuid = property(_GetVpdToolGuid) \r
52302d4d
LG
1244 SkuIds = property(_GetSkuIds)\r
1245 Modules = property(_GetModules)\r
1246 LibraryInstances = property(_GetLibraryInstances)\r
1247 LibraryClasses = property(_GetLibraryClasses)\r
1248 Pcds = property(_GetPcds)\r
1249 BuildOptions = property(_GetBuildOptions)\r
1250\r
e56468c0 1251## Platform build information from DEC file\r
52302d4d
LG
1252#\r
1253# This class is used to retrieve information stored in database and convert them\r
1254# into PackageBuildClassObject form for easier use for AutoGen.\r
1255#\r
1256class DecBuildData(PackageBuildClassObject):\r
1257 # dict used to convert PCD type in database to string used by build tool\r
1258 _PCD_TYPE_STRING_ = {\r
1259 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
1260 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
1261 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
1262 MODEL_PCD_DYNAMIC : "Dynamic",\r
1263 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
1264 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
1265 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
1266 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
1267 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
1268 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
1269 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
1270 }\r
1271\r
1272 # dict used to convert part of [Defines] to members of DecBuildData directly\r
1273 _PROPERTY_ = {\r
1274 #\r
1275 # Required Fields\r
1276 #\r
1277 TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName",\r
1278 TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid",\r
1279 TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version",\r
e56468c0 1280 TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile",\r
52302d4d
LG
1281 }\r
1282\r
1283\r
1284 ## Constructor of DecBuildData\r
1285 #\r
1286 # Initialize object of DecBuildData\r
1287 #\r
1288 # @param FilePath The path of package description file\r
1289 # @param RawData The raw data of DEC file\r
1290 # @param BuildDataBase Database used to retrieve module information\r
1291 # @param Arch The target architecture\r
1292 # @param Platform (not used for DecBuildData)\r
1293 # @param Macros Macros used for replacement in DSC file\r
1294 #\r
0d2711a6 1295 def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):\r
52302d4d
LG
1296 self.MetaFile = File\r
1297 self._PackageDir = File.Dir\r
1298 self._RawData = RawData\r
1299 self._Bdb = BuildDataBase\r
1300 self._Arch = Arch\r
0d2711a6
LG
1301 self._Target = Target\r
1302 self._Toolchain = Toolchain\r
52302d4d
LG
1303 self._Clear()\r
1304\r
1305 ## XXX[key] = value\r
1306 def __setitem__(self, key, value):\r
1307 self.__dict__[self._PROPERTY_[key]] = value\r
1308\r
1309 ## value = XXX[key]\r
1310 def __getitem__(self, key):\r
1311 return self.__dict__[self._PROPERTY_[key]]\r
1312\r
1313 ## "in" test support\r
1314 def __contains__(self, key):\r
1315 return key in self._PROPERTY_\r
1316\r
1317 ## Set all internal used members of DecBuildData to None\r
1318 def _Clear(self):\r
1319 self._Header = None\r
1320 self._PackageName = None\r
1321 self._Guid = None\r
1322 self._Version = None\r
e56468c0 1323 self._PkgUniFile = None\r
52302d4d
LG
1324 self._Protocols = None\r
1325 self._Ppis = None\r
1326 self._Guids = None\r
1327 self._Includes = None\r
1328 self._LibraryClasses = None\r
1329 self._Pcds = None\r
0d2711a6 1330 self.__Macros = None\r
c28d2e10
YZ
1331 self._PrivateProtocols = None\r
1332 self._PrivatePpis = None\r
1333 self._PrivateGuids = None\r
1334 self._PrivateIncludes = None\r
0d2711a6
LG
1335\r
1336 ## Get current effective macros\r
1337 def _GetMacros(self):\r
1338 if self.__Macros == None:\r
1339 self.__Macros = {}\r
1340 self.__Macros.update(GlobalData.gGlobalDefines)\r
1341 return self.__Macros\r
52302d4d
LG
1342\r
1343 ## Get architecture\r
1344 def _GetArch(self):\r
1345 return self._Arch\r
1346\r
1347 ## Set architecture\r
1348 #\r
1349 # Changing the default ARCH to another may affect all other information\r
1350 # because all information in a platform may be ARCH-related. That's\r
1351 # why we need to clear all internal used members, in order to cause all\r
1352 # information to be re-retrieved.\r
1353 #\r
1354 # @param Value The value of ARCH\r
1355 #\r
1356 def _SetArch(self, Value):\r
1357 if self._Arch == Value:\r
1358 return\r
1359 self._Arch = Value\r
1360 self._Clear()\r
1361\r
1362 ## Retrieve all information in [Defines] section\r
1363 #\r
1364 # (Retriving all [Defines] information in one-shot is just to save time.)\r
1365 #\r
1366 def _GetHeaderInfo(self):\r
0d2711a6 1367 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]\r
52302d4d 1368 for Record in RecordList:\r
0d2711a6 1369 Name = Record[1]\r
52302d4d 1370 if Name in self:\r
0d2711a6 1371 self[Name] = Record[2]\r
52302d4d
LG
1372 self._Header = 'DUMMY'\r
1373\r
1374 ## Retrieve package name\r
1375 def _GetPackageName(self):\r
1376 if self._PackageName == None:\r
1377 if self._Header == None:\r
1378 self._GetHeaderInfo()\r
1379 if self._PackageName == None:\r
1380 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile)\r
1381 return self._PackageName\r
1382\r
1383 ## Retrieve file guid\r
1384 def _GetFileGuid(self):\r
1385 if self._Guid == None:\r
1386 if self._Header == None:\r
1387 self._GetHeaderInfo()\r
1388 if self._Guid == None:\r
1389 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile)\r
1390 return self._Guid\r
1391\r
1392 ## Retrieve package version\r
1393 def _GetVersion(self):\r
1394 if self._Version == None:\r
1395 if self._Header == None:\r
1396 self._GetHeaderInfo()\r
1397 if self._Version == None:\r
1398 self._Version = ''\r
1399 return self._Version\r
1400\r
1401 ## Retrieve protocol definitions (name/value pairs)\r
1402 def _GetProtocol(self):\r
1403 if self._Protocols == None:\r
1404 #\r
1405 # tdict is a special kind of dict, used for selecting correct\r
1406 # protocol defition for given ARCH\r
1407 #\r
1408 ProtocolDict = tdict(True)\r
c28d2e10 1409 PrivateProtocolDict = tdict(True)\r
52302d4d 1410 NameList = []\r
c28d2e10 1411 PrivateNameList = []\r
52302d4d
LG
1412 # find out all protocol definitions for specific and 'common' arch\r
1413 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]\r
c28d2e10
YZ
1414 for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
1415 if PrivateFlag == 'PRIVATE':\r
1416 if Name not in PrivateNameList:\r
1417 PrivateNameList.append(Name)\r
1418 PrivateProtocolDict[Arch, Name] = Guid\r
52302d4d
LG
1419 if Name not in NameList:\r
1420 NameList.append(Name)\r
1421 ProtocolDict[Arch, Name] = Guid\r
1422 # use sdict to keep the order\r
1423 self._Protocols = sdict()\r
c28d2e10 1424 self._PrivateProtocols = sdict()\r
52302d4d
LG
1425 for Name in NameList:\r
1426 #\r
1427 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1428 # will automatically turn to 'common' ARCH for trying\r
1429 #\r
1430 self._Protocols[Name] = ProtocolDict[self._Arch, Name]\r
c28d2e10
YZ
1431 for Name in PrivateNameList:\r
1432 self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]\r
52302d4d
LG
1433 return self._Protocols\r
1434\r
1435 ## Retrieve PPI definitions (name/value pairs)\r
1436 def _GetPpi(self):\r
1437 if self._Ppis == None:\r
1438 #\r
1439 # tdict is a special kind of dict, used for selecting correct\r
1440 # PPI defition for given ARCH\r
1441 #\r
1442 PpiDict = tdict(True)\r
c28d2e10 1443 PrivatePpiDict = tdict(True)\r
52302d4d 1444 NameList = []\r
c28d2e10 1445 PrivateNameList = []\r
52302d4d
LG
1446 # find out all PPI definitions for specific arch and 'common' arch\r
1447 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]\r
c28d2e10
YZ
1448 for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
1449 if PrivateFlag == 'PRIVATE':\r
1450 if Name not in PrivateNameList:\r
1451 PrivateNameList.append(Name)\r
1452 PrivatePpiDict[Arch, Name] = Guid\r
52302d4d
LG
1453 if Name not in NameList:\r
1454 NameList.append(Name)\r
1455 PpiDict[Arch, Name] = Guid\r
1456 # use sdict to keep the order\r
1457 self._Ppis = sdict()\r
c28d2e10 1458 self._PrivatePpis = sdict()\r
52302d4d
LG
1459 for Name in NameList:\r
1460 #\r
1461 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1462 # will automatically turn to 'common' ARCH for trying\r
1463 #\r
1464 self._Ppis[Name] = PpiDict[self._Arch, Name]\r
c28d2e10
YZ
1465 for Name in PrivateNameList:\r
1466 self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]\r
52302d4d
LG
1467 return self._Ppis\r
1468\r
1469 ## Retrieve GUID definitions (name/value pairs)\r
1470 def _GetGuid(self):\r
1471 if self._Guids == None:\r
1472 #\r
1473 # tdict is a special kind of dict, used for selecting correct\r
1474 # GUID defition for given ARCH\r
1475 #\r
1476 GuidDict = tdict(True)\r
c28d2e10 1477 PrivateGuidDict = tdict(True)\r
52302d4d 1478 NameList = []\r
c28d2e10 1479 PrivateNameList = []\r
52302d4d
LG
1480 # find out all protocol definitions for specific and 'common' arch\r
1481 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]\r
c28d2e10
YZ
1482 for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
1483 if PrivateFlag == 'PRIVATE':\r
1484 if Name not in PrivateNameList:\r
1485 PrivateNameList.append(Name)\r
1486 PrivateGuidDict[Arch, Name] = Guid\r
52302d4d
LG
1487 if Name not in NameList:\r
1488 NameList.append(Name)\r
1489 GuidDict[Arch, Name] = Guid\r
1490 # use sdict to keep the order\r
1491 self._Guids = sdict()\r
c28d2e10 1492 self._PrivateGuids = sdict()\r
52302d4d
LG
1493 for Name in NameList:\r
1494 #\r
1495 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1496 # will automatically turn to 'common' ARCH for trying\r
1497 #\r
1498 self._Guids[Name] = GuidDict[self._Arch, Name]\r
c28d2e10
YZ
1499 for Name in PrivateNameList:\r
1500 self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]\r
52302d4d
LG
1501 return self._Guids\r
1502\r
1503 ## Retrieve public include paths declared in this package\r
1504 def _GetInclude(self):\r
1505 if self._Includes == None:\r
1506 self._Includes = []\r
c28d2e10 1507 self._PrivateIncludes = []\r
52302d4d 1508 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]\r
0d2711a6
LG
1509 Macros = self._Macros\r
1510 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
52302d4d
LG
1511 for Record in RecordList:\r
1512 File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)\r
1513 LineNo = Record[-1]\r
1514 # validate the path\r
1515 ErrorCode, ErrorInfo = File.Validate()\r
1516 if ErrorCode != 0:\r
1517 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1518\r
1519 # avoid duplicate include path\r
1520 if File not in self._Includes:\r
1521 self._Includes.append(File)\r
c28d2e10
YZ
1522 if Record[4] == 'PRIVATE':\r
1523 if File not in self._PrivateIncludes:\r
1524 self._PrivateIncludes.append(File)\r
52302d4d
LG
1525 return self._Includes\r
1526\r
1527 ## Retrieve library class declarations (not used in build at present)\r
1528 def _GetLibraryClass(self):\r
1529 if self._LibraryClasses == None:\r
1530 #\r
1531 # tdict is a special kind of dict, used for selecting correct\r
1532 # library class declaration for given ARCH\r
1533 #\r
1534 LibraryClassDict = tdict(True)\r
1535 LibraryClassSet = set()\r
1536 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
0d2711a6 1537 Macros = self._Macros\r
c28d2e10 1538 for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
52302d4d
LG
1539 File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)\r
1540 # check the file validation\r
1541 ErrorCode, ErrorInfo = File.Validate()\r
1542 if ErrorCode != 0:\r
1543 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
1544 LibraryClassSet.add(LibraryClass)\r
1545 LibraryClassDict[Arch, LibraryClass] = File\r
1546 self._LibraryClasses = sdict()\r
1547 for LibraryClass in LibraryClassSet:\r
1548 self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass]\r
1549 return self._LibraryClasses\r
1550\r
1551 ## Retrieve PCD declarations\r
1552 def _GetPcds(self):\r
1553 if self._Pcds == None:\r
0d2711a6 1554 self._Pcds = sdict()\r
52302d4d
LG
1555 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
1556 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
1557 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
1558 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
1559 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
1560 return self._Pcds\r
1561\r
1562 ## Retrieve PCD declarations for given type\r
1563 def _GetPcd(self, Type):\r
0d2711a6 1564 Pcds = sdict()\r
52302d4d
LG
1565 #\r
1566 # tdict is a special kind of dict, used for selecting correct\r
1567 # PCD declaration for given ARCH\r
1568 #\r
1569 PcdDict = tdict(True, 3)\r
1570 # for summarizing PCD\r
1571 PcdSet = set()\r
1572 # find out all PCDs of the 'type'\r
1573 RecordList = self._RawData[Type, self._Arch]\r
c28d2e10 1574 for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:\r
52302d4d
LG
1575 PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
1576 PcdSet.add((PcdCName, TokenSpaceGuid))\r
1577\r
1578 for PcdCName, TokenSpaceGuid in PcdSet:\r
52302d4d
LG
1579 #\r
1580 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
1581 # will automatically turn to 'common' ARCH and try again\r
1582 #\r
1583 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]\r
1584 if Setting == None:\r
1585 continue\r
6780eef1
LG
1586\r
1587 DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)\r
1588 \r
82a6a960 1589 validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName) \r
52302d4d
LG
1590 Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(\r
1591 PcdCName,\r
1592 TokenSpaceGuid,\r
1593 self._PCD_TYPE_STRING_[Type],\r
1594 DatumType,\r
1595 DefaultValue,\r
1596 TokenNumber,\r
1597 '',\r
1598 {},\r
e56468c0 1599 False,\r
82a6a960
BF
1600 None,\r
1601 list(validateranges),\r
1602 list(validlists),\r
1603 list(expressions)\r
52302d4d
LG
1604 )\r
1605 return Pcds\r
1606\r
1607\r
0d2711a6 1608 _Macros = property(_GetMacros)\r
52302d4d
LG
1609 Arch = property(_GetArch, _SetArch)\r
1610 PackageName = property(_GetPackageName)\r
1611 Guid = property(_GetFileGuid)\r
1612 Version = property(_GetVersion)\r
1613\r
1614 Protocols = property(_GetProtocol)\r
1615 Ppis = property(_GetPpi)\r
1616 Guids = property(_GetGuid)\r
1617 Includes = property(_GetInclude)\r
1618 LibraryClasses = property(_GetLibraryClass)\r
1619 Pcds = property(_GetPcds)\r
1620\r
1621## Module build information from INF file\r
1622#\r
1623# This class is used to retrieve information stored in database and convert them\r
1624# into ModuleBuildClassObject form for easier use for AutoGen.\r
1625#\r
1626class InfBuildData(ModuleBuildClassObject):\r
1627 # dict used to convert PCD type in database to string used by build tool\r
1628 _PCD_TYPE_STRING_ = {\r
1629 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild",\r
1630 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule",\r
1631 MODEL_PCD_FEATURE_FLAG : "FeatureFlag",\r
1632 MODEL_PCD_DYNAMIC : "Dynamic",\r
1633 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic",\r
1634 MODEL_PCD_DYNAMIC_HII : "DynamicHii",\r
1635 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd",\r
1636 MODEL_PCD_DYNAMIC_EX : "DynamicEx",\r
1637 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx",\r
1638 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii",\r
1639 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd",\r
1640 }\r
1641\r
1642 # dict used to convert part of [Defines] to members of InfBuildData directly\r
1643 _PROPERTY_ = {\r
1644 #\r
1645 # Required Fields\r
1646 #\r
1647 TAB_INF_DEFINES_BASE_NAME : "_BaseName",\r
1648 TAB_INF_DEFINES_FILE_GUID : "_Guid",\r
1649 TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType",\r
1650 #\r
1651 # Optional Fields\r
1652 #\r
0d2711a6 1653 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",\r
52302d4d
LG
1654 TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",\r
1655 TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",\r
1656 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",\r
b36d134f 1657 TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",\r
52302d4d
LG
1658 TAB_INF_DEFINES_VERSION_NUMBER : "_Version",\r
1659 TAB_INF_DEFINES_VERSION_STRING : "_Version",\r
1660 TAB_INF_DEFINES_VERSION : "_Version",\r
1661 TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver",\r
1662 TAB_INF_DEFINES_SHADOW : "_Shadow",\r
1663\r
1664 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath",\r
1665 }\r
1666\r
1667 # dict used to convert Component type to Module type\r
1668 _MODULE_TYPE_ = {\r
1669 "LIBRARY" : "BASE",\r
1670 "SECURITY_CORE" : "SEC",\r
1671 "PEI_CORE" : "PEI_CORE",\r
1672 "COMBINED_PEIM_DRIVER" : "PEIM",\r
1673 "PIC_PEIM" : "PEIM",\r
1674 "RELOCATABLE_PEIM" : "PEIM",\r
1675 "PE32_PEIM" : "PEIM",\r
1676 "BS_DRIVER" : "DXE_DRIVER",\r
1677 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",\r
1678 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",\r
1679 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",\r
1680 # "SMM_DRIVER" : "DXE_SMM_DRIVER",\r
1681 # "BS_DRIVER" : "DXE_SMM_DRIVER",\r
1682 # "BS_DRIVER" : "UEFI_DRIVER",\r
1683 "APPLICATION" : "UEFI_APPLICATION",\r
1684 "LOGO" : "BASE",\r
1685 }\r
1686\r
1687 # regular expression for converting XXX_FLAGS in [nmake] section to new type\r
1688 _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE)\r
1689 # dict used to convert old tool name used in [nmake] section to new ones\r
1690 _TOOL_CODE_ = {\r
1691 "C" : "CC",\r
1692 "LIB" : "SLINK",\r
1693 "LINK" : "DLINK",\r
1694 }\r
1695\r
1696\r
1697 ## Constructor of DscBuildData\r
1698 #\r
1699 # Initialize object of DscBuildData\r
1700 #\r
1701 # @param FilePath The path of platform description file\r
1702 # @param RawData The raw data of DSC file\r
1703 # @param BuildDataBase Database used to retrieve module/package information\r
1704 # @param Arch The target architecture\r
1705 # @param Platform The name of platform employing this module\r
1706 # @param Macros Macros used for replacement in DSC file\r
1707 #\r
0d2711a6 1708 def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):\r
52302d4d
LG
1709 self.MetaFile = FilePath\r
1710 self._ModuleDir = FilePath.Dir\r
1711 self._RawData = RawData\r
1712 self._Bdb = BuildDatabase\r
1713 self._Arch = Arch\r
0d2711a6
LG
1714 self._Target = Target\r
1715 self._Toolchain = Toolchain\r
52302d4d 1716 self._Platform = 'COMMON'\r
52302d4d
LG
1717 self._SourceOverridePath = None\r
1718 if FilePath.Key in GlobalData.gOverrideDir:\r
1719 self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]\r
1720 self._Clear()\r
1721\r
1722 ## XXX[key] = value\r
1723 def __setitem__(self, key, value):\r
1724 self.__dict__[self._PROPERTY_[key]] = value\r
1725\r
1726 ## value = XXX[key]\r
1727 def __getitem__(self, key):\r
1728 return self.__dict__[self._PROPERTY_[key]]\r
1729\r
1730 ## "in" test support\r
1731 def __contains__(self, key):\r
1732 return key in self._PROPERTY_\r
1733\r
1734 ## Set all internal used members of InfBuildData to None\r
1735 def _Clear(self):\r
e8a47801 1736 self._HeaderComments = None\r
2bc3256c 1737 self._TailComments = None\r
52302d4d
LG
1738 self._Header_ = None\r
1739 self._AutoGenVersion = None\r
1740 self._BaseName = None\r
b36d134f 1741 self._DxsFile = None\r
52302d4d
LG
1742 self._ModuleType = None\r
1743 self._ComponentType = None\r
1744 self._BuildType = None\r
1745 self._Guid = None\r
1746 self._Version = None\r
1747 self._PcdIsDriver = None\r
1748 self._BinaryModule = None\r
1749 self._Shadow = None\r
1750 self._MakefileName = None\r
1751 self._CustomMakefile = None\r
1752 self._Specification = None\r
1753 self._LibraryClass = None\r
1754 self._ModuleEntryPointList = None\r
1755 self._ModuleUnloadImageList = None\r
1756 self._ConstructorList = None\r
1757 self._DestructorList = None\r
1758 self._Defs = None\r
1759 self._Binaries = None\r
1760 self._Sources = None\r
1761 self._LibraryClasses = None\r
1762 self._Libraries = None\r
1763 self._Protocols = None\r
e8a47801 1764 self._ProtocolComments = None\r
52302d4d 1765 self._Ppis = None\r
e8a47801 1766 self._PpiComments = None\r
52302d4d 1767 self._Guids = None\r
e8a47801
LG
1768 self._GuidsUsedByPcd = sdict()\r
1769 self._GuidComments = None\r
52302d4d
LG
1770 self._Includes = None\r
1771 self._Packages = None\r
1772 self._Pcds = None\r
e8a47801 1773 self._PcdComments = None\r
52302d4d
LG
1774 self._BuildOptions = None\r
1775 self._Depex = None\r
1776 self._DepexExpression = None\r
0d2711a6
LG
1777 self.__Macros = None\r
1778\r
1779 ## Get current effective macros\r
1780 def _GetMacros(self):\r
1781 if self.__Macros == None:\r
1782 self.__Macros = {}\r
d0acc87a 1783 # EDK_GLOBAL defined macros can be applied to EDK module\r
0d2711a6
LG
1784 if self.AutoGenVersion < 0x00010005:\r
1785 self.__Macros.update(GlobalData.gEdkGlobal)\r
d0acc87a 1786 self.__Macros.update(GlobalData.gGlobalDefines)\r
0d2711a6 1787 return self.__Macros\r
52302d4d
LG
1788\r
1789 ## Get architecture\r
1790 def _GetArch(self):\r
1791 return self._Arch\r
1792\r
1793 ## Set architecture\r
1794 #\r
1795 # Changing the default ARCH to another may affect all other information\r
1796 # because all information in a platform may be ARCH-related. That's\r
1797 # why we need to clear all internal used members, in order to cause all\r
1798 # information to be re-retrieved.\r
1799 #\r
1800 # @param Value The value of ARCH\r
1801 #\r
1802 def _SetArch(self, Value):\r
1803 if self._Arch == Value:\r
1804 return\r
1805 self._Arch = Value\r
1806 self._Clear()\r
1807\r
1808 ## Return the name of platform employing this module\r
1809 def _GetPlatform(self):\r
1810 return self._Platform\r
1811\r
1812 ## Change the name of platform employing this module\r
1813 #\r
1814 # Changing the default name of platform to another may affect some information\r
1815 # because they may be PLATFORM-related. That's why we need to clear all internal\r
1816 # used members, in order to cause all information to be re-retrieved.\r
1817 #\r
1818 def _SetPlatform(self, Value):\r
1819 if self._Platform == Value:\r
1820 return\r
1821 self._Platform = Value\r
1822 self._Clear()\r
e8a47801
LG
1823 def _GetHeaderComments(self):\r
1824 if not self._HeaderComments:\r
1825 self._HeaderComments = []\r
1826 RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]\r
1827 for Record in RecordList:\r
1828 self._HeaderComments.append(Record[0])\r
1829 return self._HeaderComments\r
2bc3256c
LG
1830 def _GetTailComments(self):\r
1831 if not self._TailComments:\r
1832 self._TailComments = []\r
1833 RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]\r
1834 for Record in RecordList:\r
1835 self._TailComments.append(Record[0])\r
1836 return self._TailComments\r
52302d4d
LG
1837 ## Retrieve all information in [Defines] section\r
1838 #\r
1839 # (Retriving all [Defines] information in one-shot is just to save time.)\r
1840 #\r
1841 def _GetHeaderInfo(self):\r
1842 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
1843 for Record in RecordList:\r
0d2711a6 1844 Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)\r
52302d4d
LG
1845 # items defined _PROPERTY_ don't need additional processing\r
1846 if Name in self:\r
0d2711a6 1847 self[Name] = Value\r
97fa0ee9
YL
1848 if self._Defs == None:\r
1849 self._Defs = sdict()\r
1850 self._Defs[Name] = Value\r
52302d4d 1851 # some special items in [Defines] section need special treatment\r
08dd311f
LG
1852 elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):\r
1853 if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):\r
1854 Name = 'UEFI_SPECIFICATION_VERSION'\r
52302d4d
LG
1855 if self._Specification == None:\r
1856 self._Specification = sdict()\r
0d2711a6 1857 self._Specification[Name] = GetHexVerValue(Value)\r
08dd311f
LG
1858 if self._Specification[Name] == None:\r
1859 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
0d2711a6 1860 "'%s' format is not supported for %s" % (Value, Name),\r
08dd311f 1861 File=self.MetaFile, Line=Record[-1])\r
52302d4d
LG
1862 elif Name == 'LIBRARY_CLASS':\r
1863 if self._LibraryClass == None:\r
1864 self._LibraryClass = []\r
0d2711a6 1865 ValueList = GetSplitValueList(Value)\r
52302d4d
LG
1866 LibraryClass = ValueList[0]\r
1867 if len(ValueList) > 1:\r
1868 SupModuleList = GetSplitValueList(ValueList[1], ' ')\r
1869 else:\r
1870 SupModuleList = SUP_MODULE_LIST\r
1871 self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList))\r
1872 elif Name == 'ENTRY_POINT':\r
1873 if self._ModuleEntryPointList == None:\r
1874 self._ModuleEntryPointList = []\r
0d2711a6 1875 self._ModuleEntryPointList.append(Value)\r
52302d4d
LG
1876 elif Name == 'UNLOAD_IMAGE':\r
1877 if self._ModuleUnloadImageList == None:\r
1878 self._ModuleUnloadImageList = []\r
0d2711a6 1879 if not Value:\r
52302d4d 1880 continue\r
0d2711a6 1881 self._ModuleUnloadImageList.append(Value)\r
52302d4d
LG
1882 elif Name == 'CONSTRUCTOR':\r
1883 if self._ConstructorList == None:\r
1884 self._ConstructorList = []\r
0d2711a6 1885 if not Value:\r
52302d4d 1886 continue\r
0d2711a6 1887 self._ConstructorList.append(Value)\r
52302d4d
LG
1888 elif Name == 'DESTRUCTOR':\r
1889 if self._DestructorList == None:\r
1890 self._DestructorList = []\r
0d2711a6 1891 if not Value:\r
52302d4d 1892 continue\r
0d2711a6 1893 self._DestructorList.append(Value)\r
52302d4d 1894 elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:\r
0d2711a6 1895 TokenList = GetSplitValueList(Value)\r
52302d4d
LG
1896 if self._CustomMakefile == None:\r
1897 self._CustomMakefile = {}\r
1898 if len(TokenList) < 2:\r
1899 self._CustomMakefile['MSFT'] = TokenList[0]\r
1900 self._CustomMakefile['GCC'] = TokenList[0]\r
1901 else:\r
1902 if TokenList[0] not in ['MSFT', 'GCC']:\r
1903 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
1904 "No supported family [%s]" % TokenList[0],\r
1905 File=self.MetaFile, Line=Record[-1])\r
1906 self._CustomMakefile[TokenList[0]] = TokenList[1]\r
1907 else:\r
1908 if self._Defs == None:\r
1909 self._Defs = sdict()\r
0d2711a6 1910 self._Defs[Name] = Value\r
52302d4d
LG
1911\r
1912 #\r
0d2711a6 1913 # Retrieve information in sections specific to Edk.x modules\r
52302d4d 1914 #\r
0d2711a6 1915 if self.AutoGenVersion >= 0x00010005:\r
52302d4d
LG
1916 if not self._ModuleType:\r
1917 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
1918 "MODULE_TYPE is not given", File=self.MetaFile)\r
da92f276
LG
1919 if self._ModuleType not in SUP_MODULE_LIST:\r
1920 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
1921 for Record in RecordList:\r
0d2711a6 1922 Name = Record[1]\r
da92f276
LG
1923 if Name == "MODULE_TYPE":\r
1924 LineNo = Record[6]\r
1925 break\r
1926 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
47fea6af 1927 "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 1928 File=self.MetaFile, Line=LineNo)\r
da92f276 1929 if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):\r
52302d4d 1930 if self._ModuleType == SUP_MODULE_SMM_CORE:\r
47fea6af 1931 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 1932 if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
9ccb26bc 1933 and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:\r
52302d4d 1934 self._BuildType = 'UEFI_OPTIONROM'\r
9ccb26bc
YZ
1935 if 'PCI_COMPRESS' in self._Defs:\r
1936 if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):\r
1937 EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" %self.MetaFile)\r
1938\r
52302d4d
LG
1939 elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \\r
1940 and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':\r
1941 self._BuildType = 'UEFI_HII'\r
1942 else:\r
1943 self._BuildType = self._ModuleType.upper()\r
47fea6af 1944\r
b36d134f
LG
1945 if self._DxsFile:\r
1946 File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
1947 # check the file validation\r
1948 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
1949 if ErrorCode != 0:\r
1950 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
1951 File=self.MetaFile, Line=LineNo)\r
1952 if self.Sources == None:\r
1953 self._Sources = []\r
1954 self._Sources.append(File)\r
0d2711a6 1955 else: \r
52302d4d
LG
1956 if not self._ComponentType:\r
1957 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
1958 "COMPONENT_TYPE is not given", File=self.MetaFile)\r
47fea6af 1959 self._BuildType = self._ComponentType.upper()\r
52302d4d
LG
1960 if self._ComponentType in self._MODULE_TYPE_:\r
1961 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
1962 if self._ComponentType == 'LIBRARY':\r
1963 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]\r
1964 # make use some [nmake] section macros\r
0d2711a6
LG
1965 Macros = self._Macros\r
1966 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
1967 Macros['PROCESSOR'] = self._Arch\r
52302d4d 1968 RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
47fea6af 1969 for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:\r
0d2711a6 1970 Value = ReplaceMacro(Value, Macros, True)\r
52302d4d
LG
1971 if Name == "IMAGE_ENTRY_POINT":\r
1972 if self._ModuleEntryPointList == None:\r
1973 self._ModuleEntryPointList = []\r
1974 self._ModuleEntryPointList.append(Value)\r
1975 elif Name == "DPX_SOURCE":\r
0d2711a6 1976 File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)\r
52302d4d
LG
1977 # check the file validation\r
1978 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)\r
1979 if ErrorCode != 0:\r
1980 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,\r
1981 File=self.MetaFile, Line=LineNo)\r
1982 if self.Sources == None:\r
1983 self._Sources = []\r
1984 self._Sources.append(File)\r
1985 else:\r
1986 ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name)\r
1987 if len(ToolList) == 0 or len(ToolList) != 1:\r
1988 pass\r
1989# EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,\r
1990# File=self.MetaFile, Line=LineNo)\r
1991 else:\r
1992 if self._BuildOptions == None:\r
1993 self._BuildOptions = sdict()\r
1994\r
1995 if ToolList[0] in self._TOOL_CODE_:\r
1996 Tool = self._TOOL_CODE_[ToolList[0]]\r
1997 else:\r
1998 Tool = ToolList[0]\r
1999 ToolChain = "*_*_*_%s_FLAGS" % Tool\r
f51461c8 2000 ToolChainFamily = 'MSFT' # Edk.x only support MSFT tool chain\r
52302d4d 2001 #ignore not replaced macros in value\r
0d2711a6 2002 ValueList = GetSplitList(' ' + Value, '/D')\r
52302d4d
LG
2003 Dummy = ValueList[0]\r
2004 for Index in range(1, len(ValueList)):\r
2005 if ValueList[Index][-1] == '=' or ValueList[Index] == '':\r
2006 continue\r
2007 Dummy = Dummy + ' /D ' + ValueList[Index]\r
2008 Value = Dummy.strip()\r
2009 if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
2010 self._BuildOptions[ToolChainFamily, ToolChain] = Value\r
2011 else:\r
2012 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
2013 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value\r
2014 # set _Header to non-None in order to avoid database re-querying\r
2015 self._Header_ = 'DUMMY'\r
2016\r
2017 ## Retrieve file version\r
2018 def _GetInfVersion(self):\r
2019 if self._AutoGenVersion == None:\r
0d2711a6
LG
2020 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
2021 for Record in RecordList:\r
2022 if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
3ab1434a
YZ
2023 if '.' in Record[2]:\r
2024 ValueList = Record[2].split('.')\r
2025 Major = '%04o' % int(ValueList[0], 0)\r
2026 Minor = '%04o' % int(ValueList[1], 0)\r
2027 self._AutoGenVersion = int('0x' + Major + Minor, 0)\r
2028 else:\r
2029 self._AutoGenVersion = int(Record[2], 0)\r
0d2711a6 2030 break\r
52302d4d
LG
2031 if self._AutoGenVersion == None:\r
2032 self._AutoGenVersion = 0x00010000\r
2033 return self._AutoGenVersion\r
2034\r
2035 ## Retrieve BASE_NAME\r
2036 def _GetBaseName(self):\r
2037 if self._BaseName == None:\r
2038 if self._Header_ == None:\r
2039 self._GetHeaderInfo()\r
2040 if self._BaseName == None:\r
2041 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)\r
2042 return self._BaseName\r
2043\r
b36d134f
LG
2044 ## Retrieve DxsFile\r
2045 def _GetDxsFile(self):\r
2046 if self._DxsFile == None:\r
2047 if self._Header_ == None:\r
2048 self._GetHeaderInfo()\r
2049 if self._DxsFile == None:\r
2050 self._DxsFile = ''\r
2051 return self._DxsFile\r
2052\r
52302d4d
LG
2053 ## Retrieve MODULE_TYPE\r
2054 def _GetModuleType(self):\r
2055 if self._ModuleType == None:\r
2056 if self._Header_ == None:\r
2057 self._GetHeaderInfo()\r
2058 if self._ModuleType == None:\r
2059 self._ModuleType = 'BASE'\r
2060 if self._ModuleType not in SUP_MODULE_LIST:\r
2061 self._ModuleType = "USER_DEFINED"\r
2062 return self._ModuleType\r
2063\r
2064 ## Retrieve COMPONENT_TYPE\r
2065 def _GetComponentType(self):\r
2066 if self._ComponentType == None:\r
2067 if self._Header_ == None:\r
2068 self._GetHeaderInfo()\r
2069 if self._ComponentType == None:\r
2070 self._ComponentType = 'USER_DEFINED'\r
2071 return self._ComponentType\r
2072\r
2073 ## Retrieve "BUILD_TYPE"\r
2074 def _GetBuildType(self):\r
2075 if self._BuildType == None:\r
2076 if self._Header_ == None:\r
2077 self._GetHeaderInfo()\r
2078 if not self._BuildType:\r
2079 self._BuildType = "BASE"\r
2080 return self._BuildType\r
2081\r
2082 ## Retrieve file guid\r
2083 def _GetFileGuid(self):\r
2084 if self._Guid == None:\r
2085 if self._Header_ == None:\r
2086 self._GetHeaderInfo()\r
2087 if self._Guid == None:\r
1ba5124e 2088 self._Guid = '00000000-0000-0000-0000-000000000000'\r
52302d4d
LG
2089 return self._Guid\r
2090\r
2091 ## Retrieve module version\r
2092 def _GetVersion(self):\r
2093 if self._Version == None:\r
2094 if self._Header_ == None:\r
2095 self._GetHeaderInfo()\r
2096 if self._Version == None:\r
2097 self._Version = '0.0'\r
2098 return self._Version\r
2099\r
2100 ## Retrieve PCD_IS_DRIVER\r
2101 def _GetPcdIsDriver(self):\r
2102 if self._PcdIsDriver == None:\r
2103 if self._Header_ == None:\r
2104 self._GetHeaderInfo()\r
2105 if self._PcdIsDriver == None:\r
2106 self._PcdIsDriver = ''\r
2107 return self._PcdIsDriver\r
2108\r
2109 ## Retrieve SHADOW\r
2110 def _GetShadow(self):\r
2111 if self._Shadow == None:\r
2112 if self._Header_ == None:\r
2113 self._GetHeaderInfo()\r
2114 if self._Shadow != None and self._Shadow.upper() == 'TRUE':\r
2115 self._Shadow = True\r
2116 else:\r
2117 self._Shadow = False\r
2118 return self._Shadow\r
2119\r
2120 ## Retrieve CUSTOM_MAKEFILE\r
2121 def _GetMakefile(self):\r
2122 if self._CustomMakefile == None:\r
2123 if self._Header_ == None:\r
2124 self._GetHeaderInfo()\r
2125 if self._CustomMakefile == None:\r
2126 self._CustomMakefile = {}\r
2127 return self._CustomMakefile\r
2128\r
2129 ## Retrieve EFI_SPECIFICATION_VERSION\r
2130 def _GetSpec(self):\r
2131 if self._Specification == None:\r
2132 if self._Header_ == None:\r
2133 self._GetHeaderInfo()\r
2134 if self._Specification == None:\r
2135 self._Specification = {}\r
2136 return self._Specification\r
2137\r
2138 ## Retrieve LIBRARY_CLASS\r
2139 def _GetLibraryClass(self):\r
2140 if self._LibraryClass == None:\r
2141 if self._Header_ == None:\r
2142 self._GetHeaderInfo()\r
2143 if self._LibraryClass == None:\r
2144 self._LibraryClass = []\r
2145 return self._LibraryClass\r
2146\r
2147 ## Retrieve ENTRY_POINT\r
2148 def _GetEntryPoint(self):\r
2149 if self._ModuleEntryPointList == None:\r
2150 if self._Header_ == None:\r
2151 self._GetHeaderInfo()\r
2152 if self._ModuleEntryPointList == None:\r
2153 self._ModuleEntryPointList = []\r
2154 return self._ModuleEntryPointList\r
2155\r
2156 ## Retrieve UNLOAD_IMAGE\r
2157 def _GetUnloadImage(self):\r
2158 if self._ModuleUnloadImageList == None:\r
2159 if self._Header_ == None:\r
2160 self._GetHeaderInfo()\r
2161 if self._ModuleUnloadImageList == None:\r
2162 self._ModuleUnloadImageList = []\r
2163 return self._ModuleUnloadImageList\r
2164\r
2165 ## Retrieve CONSTRUCTOR\r
2166 def _GetConstructor(self):\r
2167 if self._ConstructorList == None:\r
2168 if self._Header_ == None:\r
2169 self._GetHeaderInfo()\r
2170 if self._ConstructorList == None:\r
2171 self._ConstructorList = []\r
2172 return self._ConstructorList\r
2173\r
2174 ## Retrieve DESTRUCTOR\r
2175 def _GetDestructor(self):\r
2176 if self._DestructorList == None:\r
2177 if self._Header_ == None:\r
2178 self._GetHeaderInfo()\r
2179 if self._DestructorList == None:\r
2180 self._DestructorList = []\r
2181 return self._DestructorList\r
2182\r
2183 ## Retrieve definies other than above ones\r
2184 def _GetDefines(self):\r
2185 if self._Defs == None:\r
2186 if self._Header_ == None:\r
2187 self._GetHeaderInfo()\r
2188 if self._Defs == None:\r
2189 self._Defs = sdict()\r
2190 return self._Defs\r
2191\r
2192 ## Retrieve binary files\r
a0a2cd1e 2193 def _GetBinaries(self):\r
52302d4d
LG
2194 if self._Binaries == None:\r
2195 self._Binaries = []\r
2196 RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]\r
0d2711a6
LG
2197 Macros = self._Macros\r
2198 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
2199 Macros['PROCESSOR'] = self._Arch\r
52302d4d 2200 for Record in RecordList:\r
52302d4d
LG
2201 FileType = Record[0]\r
2202 LineNo = Record[-1]\r
2203 Target = 'COMMON'\r
2204 FeatureFlag = []\r
2205 if Record[2]:\r
2206 TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
2207 if TokenList:\r
2208 Target = TokenList[0]\r
2209 if len(TokenList) > 1:\r
2210 FeatureFlag = Record[1:]\r
2211\r
2212 File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target)\r
2213 # check the file validation\r
2214 ErrorCode, ErrorInfo = File.Validate()\r
2215 if ErrorCode != 0:\r
2216 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
2217 self._Binaries.append(File)\r
2218 return self._Binaries\r
2219\r
a0a2cd1e
FB
2220 ## Retrieve binary files with error check.\r
2221 def _GetBinaryFiles(self):\r
2222 Binaries = self._GetBinaries()\r
2223 if GlobalData.gIgnoreSource and Binaries == []:\r
2224 ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"\r
2225 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)\r
2226\r
2227 return Binaries\r
2228 ## Check whether it exists the binaries with current ARCH in AsBuild INF\r
2229 def _IsSupportedArch(self):\r
2230 if self._GetBinaries() and not self._GetSourceFiles():\r
2231 return True\r
2232 else:\r
2233 return False\r
52302d4d
LG
2234 ## Retrieve source files\r
2235 def _GetSourceFiles(self):\r
fae62ff2
HC
2236 #Ignore all source files in a binary build mode\r
2237 if GlobalData.gIgnoreSource:\r
2238 self._Sources = []\r
2239 return self._Sources\r
2240\r
52302d4d
LG
2241 if self._Sources == None:\r
2242 self._Sources = []\r
2243 RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]\r
0d2711a6 2244 Macros = self._Macros\r
52302d4d 2245 for Record in RecordList:\r
52302d4d
LG
2246 LineNo = Record[-1]\r
2247 ToolChainFamily = Record[1]\r
2248 TagName = Record[2]\r
2249 ToolCode = Record[3]\r
2250 FeatureFlag = Record[4]\r
0d2711a6 2251 if self.AutoGenVersion < 0x00010005:\r
d0acc87a
LG
2252 Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
2253 Macros['PROCESSOR'] = self._Arch\r
05cc51ad
LY
2254 SourceFile = NormPath(Record[0], Macros)\r
2255 if SourceFile[0] == os.path.sep:\r
2256 SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])\r
0d2711a6 2257 # old module source files (Edk)\r
05cc51ad 2258 File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,\r
52302d4d
LG
2259 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
2260 # check the file validation\r
2261 ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
2262 if ErrorCode != 0:\r
2263 if File.Ext.lower() == '.h':\r
2264 EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo,\r
2265 File=self.MetaFile, Line=LineNo)\r
2266 continue\r
2267 else:\r
2268 EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo)\r
2269 else:\r
2270 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '',\r
2271 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
2272 # check the file validation\r
2273 ErrorCode, ErrorInfo = File.Validate()\r
2274 if ErrorCode != 0:\r
2275 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
2276\r
2277 self._Sources.append(File)\r
2278 return self._Sources\r
2279\r
2280 ## Retrieve library classes employed by this module\r
2281 def _GetLibraryClassUses(self):\r
2282 if self._LibraryClasses == None:\r
2283 self._LibraryClasses = sdict()\r
2284 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]\r
2285 for Record in RecordList:\r
52302d4d
LG
2286 Lib = Record[0]\r
2287 Instance = Record[1]\r
0d2711a6 2288 if Instance:\r
52302d4d
LG
2289 Instance = NormPath(Instance, self._Macros)\r
2290 self._LibraryClasses[Lib] = Instance\r
2291 return self._LibraryClasses\r
2292\r
0d2711a6 2293 ## Retrieve library names (for Edk.x style of modules)\r
52302d4d
LG
2294 def _GetLibraryNames(self):\r
2295 if self._Libraries == None:\r
2296 self._Libraries = []\r
2297 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]\r
2298 for Record in RecordList:\r
0d2711a6
LG
2299 LibraryName = ReplaceMacro(Record[0], self._Macros, False)\r
2300 # in case of name with '.lib' extension, which is unusual in Edk.x inf\r
2301 LibraryName = os.path.splitext(LibraryName)[0]\r
52302d4d
LG
2302 if LibraryName not in self._Libraries:\r
2303 self._Libraries.append(LibraryName)\r
2304 return self._Libraries\r
2305\r
e8a47801
LG
2306 def _GetProtocolComments(self):\r
2307 self._GetProtocols()\r
2308 return self._ProtocolComments\r
52302d4d
LG
2309 ## Retrieve protocols consumed/produced by this module\r
2310 def _GetProtocols(self):\r
2311 if self._Protocols == None:\r
2312 self._Protocols = sdict()\r
e8a47801 2313 self._ProtocolComments = sdict()\r
52302d4d
LG
2314 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
2315 for Record in RecordList:\r
2316 CName = Record[0]\r
c28d2e10 2317 Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)\r
52302d4d
LG
2318 if Value == None:\r
2319 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2320 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2321 "Value of Protocol [%s] is not found under [Protocols] section in" % CName,\r
2322 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2323 self._Protocols[CName] = Value\r
e8a47801
LG
2324 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
2325 Comments = []\r
2326 for CmtRec in CommentRecords:\r
2327 Comments.append(CmtRec[0])\r
2328 self._ProtocolComments[CName] = Comments\r
52302d4d
LG
2329 return self._Protocols\r
2330\r
e8a47801
LG
2331 def _GetPpiComments(self):\r
2332 self._GetPpis()\r
2333 return self._PpiComments\r
52302d4d
LG
2334 ## Retrieve PPIs consumed/produced by this module\r
2335 def _GetPpis(self):\r
2336 if self._Ppis == None:\r
2337 self._Ppis = sdict()\r
e8a47801 2338 self._PpiComments = sdict()\r
52302d4d
LG
2339 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
2340 for Record in RecordList:\r
2341 CName = Record[0]\r
c28d2e10 2342 Value = PpiValue(CName, self.Packages, self.MetaFile.Path)\r
52302d4d
LG
2343 if Value == None:\r
2344 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2345 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2346 "Value of PPI [%s] is not found under [Ppis] section in " % CName,\r
2347 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2348 self._Ppis[CName] = Value\r
e8a47801
LG
2349 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
2350 Comments = []\r
2351 for CmtRec in CommentRecords:\r
2352 Comments.append(CmtRec[0])\r
2353 self._PpiComments[CName] = Comments\r
52302d4d
LG
2354 return self._Ppis\r
2355\r
e8a47801
LG
2356 def _GetGuidComments(self):\r
2357 self._GetGuids()\r
2358 return self._GuidComments\r
52302d4d
LG
2359 ## Retrieve GUIDs consumed/produced by this module\r
2360 def _GetGuids(self):\r
2361 if self._Guids == None:\r
2362 self._Guids = sdict()\r
e8a47801 2363 self._GuidComments = sdict()\r
52302d4d
LG
2364 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
2365 for Record in RecordList:\r
2366 CName = Record[0]\r
c28d2e10 2367 Value = GuidValue(CName, self.Packages, self.MetaFile.Path)\r
52302d4d
LG
2368 if Value == None:\r
2369 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2370 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2371 "Value of Guid [%s] is not found under [Guids] section in" % CName,\r
2372 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2373 self._Guids[CName] = Value\r
e8a47801
LG
2374 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]\r
2375 Comments = []\r
2376 for CmtRec in CommentRecords:\r
2377 Comments.append(CmtRec[0])\r
2378 self._GuidComments[CName] = Comments\r
52302d4d
LG
2379 return self._Guids\r
2380\r
0d2711a6 2381 ## Retrieve include paths necessary for this module (for Edk.x style of modules)\r
52302d4d
LG
2382 def _GetIncludes(self):\r
2383 if self._Includes == None:\r
2384 self._Includes = []\r
2385 if self._SourceOverridePath:\r
2386 self._Includes.append(self._SourceOverridePath)\r
0d2711a6
LG
2387\r
2388 Macros = self._Macros\r
2389 if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():\r
2390 Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']\r
2391 else:\r
2392 Macros['PROCESSOR'] = self._Arch\r
52302d4d 2393 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]\r
52302d4d 2394 for Record in RecordList:\r
52302d4d 2395 if Record[0].find('EDK_SOURCE') > -1:\r
0d2711a6
LG
2396 Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
2397 File = NormPath(Record[0], self._Macros)\r
52302d4d
LG
2398 if File[0] == '.':\r
2399 File = os.path.join(self._ModuleDir, File)\r
2400 else:\r
2401 File = os.path.join(GlobalData.gWorkspace, File)\r
2402 File = RealPath(os.path.normpath(File))\r
2403 if File:\r
2404 self._Includes.append(File)\r
2405\r
2406 #TRICK: let compiler to choose correct header file\r
0d2711a6
LG
2407 Macros['EDK_SOURCE'] = GlobalData.gEdkSource\r
2408 File = NormPath(Record[0], self._Macros)\r
52302d4d
LG
2409 if File[0] == '.':\r
2410 File = os.path.join(self._ModuleDir, File)\r
2411 else:\r
2412 File = os.path.join(GlobalData.gWorkspace, File)\r
2413 File = RealPath(os.path.normpath(File))\r
2414 if File:\r
2415 self._Includes.append(File)\r
2416 else:\r
0d2711a6 2417 File = NormPath(Record[0], Macros)\r
52302d4d
LG
2418 if File[0] == '.':\r
2419 File = os.path.join(self._ModuleDir, File)\r
2420 else:\r
05cc51ad 2421 File = mws.join(GlobalData.gWorkspace, File)\r
52302d4d
LG
2422 File = RealPath(os.path.normpath(File))\r
2423 if File:\r
2424 self._Includes.append(File)\r
05cc51ad
LY
2425 if not File and Record[0].find('EFI_SOURCE') > -1:\r
2426 # tricky to regard WorkSpace as EFI_SOURCE\r
2427 Macros['EFI_SOURCE'] = GlobalData.gWorkspace\r
2428 File = NormPath(Record[0], Macros)\r
2429 if File[0] == '.':\r
2430 File = os.path.join(self._ModuleDir, File)\r
2431 else:\r
2432 File = os.path.join(GlobalData.gWorkspace, File)\r
2433 File = RealPath(os.path.normpath(File))\r
2434 if File:\r
2435 self._Includes.append(File)\r
52302d4d
LG
2436 return self._Includes\r
2437\r
2438 ## Retrieve packages this module depends on\r
2439 def _GetPackages(self):\r
2440 if self._Packages == None:\r
2441 self._Packages = []\r
2442 RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]\r
0d2711a6
LG
2443 Macros = self._Macros\r
2444 Macros['EDK_SOURCE'] = GlobalData.gEcpSource\r
52302d4d
LG
2445 for Record in RecordList:\r
2446 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)\r
2447 LineNo = Record[-1]\r
2448 # check the file validation\r
2449 ErrorCode, ErrorInfo = File.Validate('.dec')\r
2450 if ErrorCode != 0:\r
2451 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)\r
2452 # parse this package now. we need it to get protocol/ppi/guid value\r
0d2711a6 2453 Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]\r
52302d4d
LG
2454 self._Packages.append(Package)\r
2455 return self._Packages\r
2456\r
e8a47801
LG
2457 ## Retrieve PCD comments\r
2458 def _GetPcdComments(self):\r
2459 self._GetPcds()\r
2460 return self._PcdComments\r
52302d4d
LG
2461 ## Retrieve PCDs used in this module\r
2462 def _GetPcds(self):\r
2463 if self._Pcds == None:\r
79b74a03 2464 self._Pcds = sdict()\r
e8a47801 2465 self._PcdComments = sdict()\r
52302d4d
LG
2466 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))\r
2467 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))\r
2468 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))\r
2469 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC))\r
2470 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX))\r
2471 return self._Pcds\r
2472\r
2473 ## Retrieve build options specific to this module\r
2474 def _GetBuildOptions(self):\r
2475 if self._BuildOptions == None:\r
2476 self._BuildOptions = sdict()\r
2477 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform]\r
2478 for Record in RecordList:\r
2479 ToolChainFamily = Record[0]\r
2480 ToolChain = Record[1]\r
2481 Option = Record[2]\r
5015bee2 2482 if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):\r
52302d4d
LG
2483 self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
2484 else:\r
2485 # concatenate the option string if they're for the same tool\r
2486 OptionString = self._BuildOptions[ToolChainFamily, ToolChain]\r
2487 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option\r
2488 return self._BuildOptions\r
2489\r
0d2711a6 2490 ## Retrieve dependency expression\r
52302d4d
LG
2491 def _GetDepex(self):\r
2492 if self._Depex == None:\r
2493 self._Depex = tdict(False, 2)\r
2494 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
da92f276
LG
2495 \r
2496 # If the module has only Binaries and no Sources, then ignore [Depex] \r
2497 if self.Sources == None or self.Sources == []:\r
0d2711a6
LG
2498 if self.Binaries != None and self.Binaries != []:\r
2499 return self._Depex\r
da92f276 2500 \r
52302d4d
LG
2501 # PEIM and DXE drivers must have a valid [Depex] section\r
2502 if len(self.LibraryClass) == 0 and len(RecordList) == 0:\r
2503 if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \\r
2504 self.ModuleType == 'DXE_SAL_DRIVER' or self.ModuleType == 'DXE_RUNTIME_DRIVER':\r
2505 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \\r
2506 % self.ModuleType, File=self.MetaFile)\r
2507\r
97fa0ee9
YL
2508 if len(RecordList) != 0 and self.ModuleType == 'USER_DEFINED':\r
2509 for Record in RecordList:\r
2510 if Record[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:\r
2511 EdkLogger.error('build', FORMAT_INVALID,\r
2512 "'%s' module must specify the type of [Depex] section" % self.ModuleType,\r
2513 File=self.MetaFile)\r
2514\r
0d2711a6 2515 Depex = sdict()\r
52302d4d 2516 for Record in RecordList:\r
0d2711a6 2517 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
52302d4d
LG
2518 Arch = Record[3]\r
2519 ModuleType = Record[4]\r
0d2711a6 2520 TokenList = DepexStr.split()\r
52302d4d
LG
2521 if (Arch, ModuleType) not in Depex:\r
2522 Depex[Arch, ModuleType] = []\r
2523 DepexList = Depex[Arch, ModuleType]\r
2524 for Token in TokenList:\r
2525 if Token in DEPEX_SUPPORTED_OPCODE:\r
2526 DepexList.append(Token)\r
2527 elif Token.endswith(".inf"): # module file name\r
2528 ModuleFile = os.path.normpath(Token)\r
2529 Module = self.BuildDatabase[ModuleFile]\r
2530 if Module == None:\r
2531 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform",\r
2532 ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
2533 DepexList.append(Module.Guid)\r
2534 else:\r
2535 # get the GUID value now\r
c28d2e10 2536 Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)\r
52302d4d 2537 if Value == None:\r
c28d2e10 2538 Value = PpiValue(Token, self.Packages, self.MetaFile.Path)\r
52302d4d 2539 if Value == None:\r
c28d2e10 2540 Value = GuidValue(Token, self.Packages, self.MetaFile.Path)\r
52302d4d
LG
2541 if Value == None:\r
2542 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2543 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2544 "Value of [%s] is not found in" % Token,\r
2545 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])\r
2546 DepexList.append(Value)\r
2547 for Arch, ModuleType in Depex:\r
2548 self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType]\r
2549 return self._Depex\r
2550\r
2551 ## Retrieve depedency expression\r
2552 def _GetDepexExpression(self):\r
2553 if self._DepexExpression == None:\r
2554 self._DepexExpression = tdict(False, 2)\r
2555 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]\r
0d2711a6 2556 DepexExpression = sdict()\r
52302d4d 2557 for Record in RecordList:\r
0d2711a6 2558 DepexStr = ReplaceMacro(Record[0], self._Macros, False)\r
52302d4d
LG
2559 Arch = Record[3]\r
2560 ModuleType = Record[4]\r
0d2711a6 2561 TokenList = DepexStr.split()\r
52302d4d
LG
2562 if (Arch, ModuleType) not in DepexExpression:\r
2563 DepexExpression[Arch, ModuleType] = ''\r
2564 for Token in TokenList:\r
2565 DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' '\r
2566 for Arch, ModuleType in DepexExpression:\r
2567 self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]\r
2568 return self._DepexExpression\r
2569\r
e8a47801
LG
2570 def GetGuidsUsedByPcd(self):\r
2571 return self._GuidsUsedByPcd\r
52302d4d
LG
2572 ## Retrieve PCD for given type\r
2573 def _GetPcd(self, Type):\r
79b74a03 2574 Pcds = sdict()\r
52302d4d 2575 PcdDict = tdict(True, 4)\r
6780eef1 2576 PcdList = []\r
52302d4d 2577 RecordList = self._RawData[Type, self._Arch, self._Platform]\r
e8a47801 2578 for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:\r
52302d4d 2579 PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)\r
6780eef1 2580 PcdList.append((PcdCName, TokenSpaceGuid))\r
52302d4d
LG
2581 # get the guid value\r
2582 if TokenSpaceGuid not in self.Guids:\r
c28d2e10 2583 Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)\r
52302d4d
LG
2584 if Value == None:\r
2585 PackageList = "\n\t".join([str(P) for P in self.Packages])\r
2586 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
2587 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,\r
2588 ExtraData=PackageList, File=self.MetaFile, Line=LineNo)\r
2589 self.Guids[TokenSpaceGuid] = Value\r
e8a47801
LG
2590 self._GuidsUsedByPcd[TokenSpaceGuid] = Value\r
2591 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]\r
2592 Comments = []\r
2593 for CmtRec in CommentRecords:\r
2594 Comments.append(CmtRec[0])\r
2595 self._PcdComments[TokenSpaceGuid, PcdCName] = Comments\r
52302d4d
LG
2596\r
2597 # resolve PCD type, value, datum info, etc. by getting its definition from package\r
6780eef1 2598 for PcdCName, TokenSpaceGuid in PcdList:\r
2a29017e 2599 PcdRealName = PcdCName\r
52302d4d
LG
2600 Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]\r
2601 if Setting == None:\r
2602 continue\r
6780eef1 2603 ValueList = AnalyzePcdData(Setting)\r
52302d4d
LG
2604 DefaultValue = ValueList[0]\r
2605 Pcd = PcdClassObject(\r
2606 PcdCName,\r
2607 TokenSpaceGuid,\r
2608 '',\r
2609 '',\r
2610 DefaultValue,\r
2611 '',\r
2612 '',\r
2613 {},\r
e56468c0 2614 False,\r
52302d4d
LG
2615 self.Guids[TokenSpaceGuid]\r
2616 )\r
e8a47801
LG
2617 if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:\r
2618 # Patch PCD: TokenSpace.PcdCName|Value|Offset\r
2619 Pcd.Offset = ValueList[1]\r
52302d4d 2620\r
2a29017e
YZ
2621 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
2622 for Package in self.Packages:\r
2623 for key in Package.Pcds:\r
2624 if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):\r
2625 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
2626 Pcd_Type = item[0].split('_')[-1]\r
2627 if Pcd_Type == Package.Pcds[key].Type:\r
2628 Value = Package.Pcds[key]\r
2629 Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type\r
2630 if len(key) == 2:\r
2631 newkey = (Value.TokenCName, key[1])\r
2632 elif len(key) == 3:\r
2633 newkey = (Value.TokenCName, key[1], key[2])\r
2634 del Package.Pcds[key]\r
2635 Package.Pcds[newkey] = Value\r
2636 break\r
2637 else:\r
2638 pass\r
2639 else:\r
2640 pass\r
2641\r
52302d4d
LG
2642 # get necessary info from package declaring this PCD\r
2643 for Package in self.Packages:\r
2644 #\r
2645 # 'dynamic' in INF means its type is determined by platform;\r
2646 # if platform doesn't give its type, use 'lowest' one in the\r
2647 # following order, if any\r
2648 #\r
2649 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"\r
2650 #\r
2651 PcdType = self._PCD_TYPE_STRING_[Type]\r
e56468c0 2652 if Type == MODEL_PCD_DYNAMIC:\r
52302d4d
LG
2653 Pcd.Pending = True\r
2654 for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:\r
2a29017e
YZ
2655 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
2656 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
2657 if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:\r
2658 PcdType = T\r
2659 PcdCName = item[0]\r
2660 break\r
2661 else:\r
2662 pass\r
52302d4d 2663 break\r
2a29017e
YZ
2664 else:\r
2665 if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:\r
2666 PcdType = T\r
2667 break\r
2668\r
52302d4d
LG
2669 else:\r
2670 Pcd.Pending = False\r
2a29017e
YZ
2671 if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:\r
2672 for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:\r
2673 Pcd_Type = item[0].split('_')[-1]\r
2674 if Pcd_Type == PcdType:\r
2675 PcdCName = item[0]\r
2676 break\r
2677 else:\r
2678 pass\r
2679 else:\r
2680 pass\r
52302d4d
LG
2681\r
2682 if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:\r
2683 PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]\r
2684 Pcd.Type = PcdType\r
2685 Pcd.TokenValue = PcdInPackage.TokenValue\r
6780eef1
LG
2686 \r
2687 #\r
2688 # Check whether the token value exist or not.\r
2689 #\r
2690 if Pcd.TokenValue == None or Pcd.TokenValue == "":\r
2691 EdkLogger.error(\r
2692 'build',\r
2693 FORMAT_INVALID,\r
2a29017e 2694 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdRealName, str(Package)),\r
47fea6af 2695 File=self.MetaFile, Line=LineNo,\r
6780eef1
LG
2696 ExtraData=None\r
2697 ) \r
2698 #\r
2699 # Check hexadecimal token value length and format.\r
2700 #\r
79b74a03 2701 ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)\r
6780eef1 2702 if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):\r
79b74a03 2703 if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:\r
6780eef1
LG
2704 EdkLogger.error(\r
2705 'build',\r
2706 FORMAT_INVALID,\r
2a29017e 2707 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),\r
47fea6af 2708 File=self.MetaFile, Line=LineNo,\r
6780eef1
LG
2709 ExtraData=None\r
2710 )\r
2711 \r
2712 #\r
2713 # Check decimal token value length and format.\r
2714 # \r
2715 else:\r
2716 try:\r
2717 TokenValueInt = int (Pcd.TokenValue, 10)\r
2718 if (TokenValueInt < 0 or TokenValueInt > 4294967295):\r
2719 EdkLogger.error(\r
2720 'build',\r
2721 FORMAT_INVALID,\r
2a29017e 2722 "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 2723 File=self.MetaFile, Line=LineNo,\r
6780eef1 2724 ExtraData=None\r
47fea6af 2725 )\r
6780eef1
LG
2726 except:\r
2727 EdkLogger.error(\r
2728 'build',\r
2729 FORMAT_INVALID,\r
2a29017e 2730 "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 2731 File=self.MetaFile, Line=LineNo,\r
6780eef1
LG
2732 ExtraData=None\r
2733 )\r
47fea6af 2734\r
52302d4d
LG
2735 Pcd.DatumType = PcdInPackage.DatumType\r
2736 Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
2737 Pcd.InfDefaultValue = Pcd.DefaultValue\r
2738 if Pcd.DefaultValue in [None, '']:\r
2739 Pcd.DefaultValue = PcdInPackage.DefaultValue\r
2740 break\r
2741 else:\r
2742 EdkLogger.error(\r
2743 'build',\r
6780eef1 2744 FORMAT_INVALID,\r
2a29017e 2745 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, self.MetaFile),\r
47fea6af 2746 File=self.MetaFile, Line=LineNo,\r
52302d4d
LG
2747 ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])\r
2748 )\r
2749 Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
6780eef1 2750\r
52302d4d
LG
2751 return Pcds\r
2752\r
e8a47801
LG
2753 ## check whether current module is binary module\r
2754 def _IsBinaryModule(self):\r
2755 if self.Binaries and not self.Sources:\r
2756 return True\r
2757 elif GlobalData.gIgnoreSource:\r
2758 return True\r
2759 else:\r
2760 return False\r
2761\r
2762 _Macros = property(_GetMacros)\r
2763 Arch = property(_GetArch, _SetArch)\r
2764 Platform = property(_GetPlatform, _SetPlatform)\r
52302d4d 2765\r
e8a47801 2766 HeaderComments = property(_GetHeaderComments)\r
2bc3256c 2767 TailComments = property(_GetTailComments)\r
52302d4d
LG
2768 AutoGenVersion = property(_GetInfVersion)\r
2769 BaseName = property(_GetBaseName)\r
2770 ModuleType = property(_GetModuleType)\r
2771 ComponentType = property(_GetComponentType)\r
2772 BuildType = property(_GetBuildType)\r
2773 Guid = property(_GetFileGuid)\r
2774 Version = property(_GetVersion)\r
2775 PcdIsDriver = property(_GetPcdIsDriver)\r
2776 Shadow = property(_GetShadow)\r
2777 CustomMakefile = property(_GetMakefile)\r
2778 Specification = property(_GetSpec)\r
2779 LibraryClass = property(_GetLibraryClass)\r
2780 ModuleEntryPointList = property(_GetEntryPoint)\r
2781 ModuleUnloadImageList = property(_GetUnloadImage)\r
2782 ConstructorList = property(_GetConstructor)\r
2783 DestructorList = property(_GetDestructor)\r
2784 Defines = property(_GetDefines)\r
b36d134f
LG
2785 DxsFile = property(_GetDxsFile)\r
2786 \r
52302d4d
LG
2787 Binaries = property(_GetBinaryFiles)\r
2788 Sources = property(_GetSourceFiles)\r
2789 LibraryClasses = property(_GetLibraryClassUses)\r
2790 Libraries = property(_GetLibraryNames)\r
2791 Protocols = property(_GetProtocols)\r
e8a47801 2792 ProtocolComments = property(_GetProtocolComments)\r
52302d4d 2793 Ppis = property(_GetPpis)\r
e8a47801 2794 PpiComments = property(_GetPpiComments)\r
52302d4d 2795 Guids = property(_GetGuids)\r
e8a47801 2796 GuidComments = property(_GetGuidComments)\r
52302d4d
LG
2797 Includes = property(_GetIncludes)\r
2798 Packages = property(_GetPackages)\r
2799 Pcds = property(_GetPcds)\r
e8a47801 2800 PcdComments = property(_GetPcdComments)\r
52302d4d
LG
2801 BuildOptions = property(_GetBuildOptions)\r
2802 Depex = property(_GetDepex)\r
2803 DepexExpression = property(_GetDepexExpression)\r
e8a47801 2804 IsBinaryModule = property(_IsBinaryModule)\r
a0a2cd1e 2805 IsSupportedArch = property(_IsSupportedArch)\r
52302d4d
LG
2806\r
2807## Database\r
2808#\r
e56468c0 2809# This class defined the build database for all modules, packages and platform.\r
52302d4d
LG
2810# It will call corresponding parser for the given file if it cannot find it in\r
2811# the database.\r
2812#\r
2813# @param DbPath Path of database file\r
2814# @param GlobalMacros Global macros used for replacement during file parsing\r
2815# @prarm RenewDb=False Create new database file if it's already there\r
2816#\r
2817class WorkspaceDatabase(object):\r
52302d4d 2818\r
52302d4d
LG
2819\r
2820 #\r
2821 # internal class used for call corresponding file parser and caching the result\r
2822 # to avoid unnecessary re-parsing\r
2823 #\r
2824 class BuildObjectFactory(object):\r
0d2711a6 2825\r
52302d4d
LG
2826 _FILE_TYPE_ = {\r
2827 ".inf" : MODEL_FILE_INF,\r
2828 ".dec" : MODEL_FILE_DEC,\r
2829 ".dsc" : MODEL_FILE_DSC,\r
0d2711a6
LG
2830 }\r
2831\r
2832 # file parser\r
2833 _FILE_PARSER_ = {\r
2834 MODEL_FILE_INF : InfParser,\r
2835 MODEL_FILE_DEC : DecParser,\r
2836 MODEL_FILE_DSC : DscParser,\r
52302d4d
LG
2837 }\r
2838\r
2839 # convert to xxxBuildData object\r
2840 _GENERATOR_ = {\r
2841 MODEL_FILE_INF : InfBuildData,\r
2842 MODEL_FILE_DEC : DecBuildData,\r
2843 MODEL_FILE_DSC : DscBuildData,\r
52302d4d
LG
2844 }\r
2845\r
2846 _CACHE_ = {} # (FilePath, Arch) : <object>\r
2847\r
2848 # constructor\r
2849 def __init__(self, WorkspaceDb):\r
2850 self.WorkspaceDb = WorkspaceDb\r
2851\r
0d2711a6 2852 # key = (FilePath, Arch=None)\r
52302d4d
LG
2853 def __contains__(self, Key):\r
2854 FilePath = Key[0]\r
52302d4d
LG
2855 if len(Key) > 1:\r
2856 Arch = Key[1]\r
0d2711a6
LG
2857 else:\r
2858 Arch = None\r
52302d4d
LG
2859 return (FilePath, Arch) in self._CACHE_\r
2860\r
0d2711a6 2861 # key = (FilePath, Arch=None, Target=None, Toochain=None)\r
52302d4d
LG
2862 def __getitem__(self, Key):\r
2863 FilePath = Key[0]\r
0d2711a6
LG
2864 KeyLength = len(Key)\r
2865 if KeyLength > 1:\r
52302d4d 2866 Arch = Key[1]\r
0d2711a6
LG
2867 else:\r
2868 Arch = None\r
2869 if KeyLength > 2:\r
2870 Target = Key[2]\r
2871 else:\r
2872 Target = None\r
2873 if KeyLength > 3:\r
2874 Toolchain = Key[3]\r
2875 else:\r
2876 Toolchain = None\r
52302d4d
LG
2877\r
2878 # if it's generated before, just return the cached one\r
0d2711a6 2879 Key = (FilePath, Arch, Target, Toolchain)\r
52302d4d
LG
2880 if Key in self._CACHE_:\r
2881 return self._CACHE_[Key]\r
2882\r
2883 # check file type\r
0d2711a6 2884 Ext = FilePath.Type\r
52302d4d
LG
2885 if Ext not in self._FILE_TYPE_:\r
2886 return None\r
2887 FileType = self._FILE_TYPE_[Ext]\r
2888 if FileType not in self._GENERATOR_:\r
2889 return None\r
2890\r
0d2711a6
LG
2891 # get the parser ready for this file\r
2892 MetaFile = self._FILE_PARSER_[FileType](\r
2893 FilePath, \r
2894 FileType, \r
cdd1b5e5 2895 Arch,\r
0d2711a6
LG
2896 MetaFileStorage(self.WorkspaceDb.Cur, FilePath, FileType)\r
2897 )\r
2898 # alwasy do post-process, in case of macros change\r
2899 MetaFile.DoPostProcess()\r
2900 # object the build is based on\r
52302d4d
LG
2901 BuildObject = self._GENERATOR_[FileType](\r
2902 FilePath,\r
2903 MetaFile,\r
2904 self,\r
2905 Arch,\r
0d2711a6
LG
2906 Target,\r
2907 Toolchain\r
52302d4d
LG
2908 )\r
2909 self._CACHE_[Key] = BuildObject\r
2910 return BuildObject\r
2911\r
2912 # placeholder for file format conversion\r
2913 class TransformObjectFactory:\r
2914 def __init__(self, WorkspaceDb):\r
2915 self.WorkspaceDb = WorkspaceDb\r
2916\r
2917 # key = FilePath, Arch\r
2918 def __getitem__(self, Key):\r
2919 pass\r
2920\r
2921 ## Constructor of WorkspaceDatabase\r
2922 #\r
2923 # @param DbPath Path of database file\r
2924 # @param GlobalMacros Global macros used for replacement during file parsing\r
2925 # @prarm RenewDb=False Create new database file if it's already there\r
2926 #\r
0d2711a6 2927 def __init__(self, DbPath, RenewDb=False):\r
4234283c 2928 self._DbClosedFlag = False\r
0d2711a6 2929 if not DbPath:\r
05cc51ad 2930 DbPath = os.path.normpath(mws.join(GlobalData.gWorkspace, 'Conf', GlobalData.gDatabasePath))\r
52302d4d
LG
2931\r
2932 # don't create necessary path for db in memory\r
2933 if DbPath != ':memory:':\r
2934 DbDir = os.path.split(DbPath)[0]\r
2935 if not os.path.exists(DbDir):\r
2936 os.makedirs(DbDir)\r
2937\r
2938 # remove db file in case inconsistency between db and file in file system\r
2939 if self._CheckWhetherDbNeedRenew(RenewDb, DbPath):\r
2940 os.remove(DbPath)\r
2941 \r
2942 # create db with optimized parameters\r
2943 self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED')\r
2944 self.Conn.execute("PRAGMA synchronous=OFF")\r
2945 self.Conn.execute("PRAGMA temp_store=MEMORY")\r
2946 self.Conn.execute("PRAGMA count_changes=OFF")\r
2947 self.Conn.execute("PRAGMA cache_size=8192")\r
2948 #self.Conn.execute("PRAGMA page_size=8192")\r
2949\r
2950 # to avoid non-ascii character conversion issue\r
2951 self.Conn.text_factory = str\r
2952 self.Cur = self.Conn.cursor()\r
2953\r
2954 # create table for internal uses\r
2955 self.TblDataModel = TableDataModel(self.Cur)\r
2956 self.TblFile = TableFile(self.Cur)\r
0d2711a6 2957 self.Platform = None\r
52302d4d
LG
2958\r
2959 # conversion object for build or file format conversion purpose\r
2960 self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self)\r
2961 self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self)\r
2962\r
2963 ## Check whether workspace database need to be renew.\r
2964 # The renew reason maybe:\r
2965 # 1) If user force to renew;\r
2966 # 2) If user do not force renew, and\r
2967 # a) If the time of last modified python source is newer than database file;\r
2968 # b) If the time of last modified frozen executable file is newer than database file;\r
2969 #\r
2970 # @param force User force renew database\r
2971 # @param DbPath The absolute path of workspace database file\r
2972 #\r
2973 # @return Bool value for whether need renew workspace databse\r
2974 #\r
2975 def _CheckWhetherDbNeedRenew (self, force, DbPath):\r
52302d4d
LG
2976 # if database does not exist, we need do nothing\r
2977 if not os.path.exists(DbPath): return False\r
2978 \r
2979 # if user force to renew database, then not check whether database is out of date\r
2980 if force: return True\r
2981 \r
2982 # \r
2983 # Check the time of last modified source file or build.exe\r
2984 # if is newer than time of database, then database need to be re-created.\r
2985 #\r
2986 timeOfToolModified = 0\r
2987 if hasattr(sys, "frozen"):\r
2988 exePath = os.path.abspath(sys.executable)\r
2989 timeOfToolModified = os.stat(exePath).st_mtime\r
2990 else:\r
2991 curPath = os.path.dirname(__file__) # curPath is the path of WorkspaceDatabase.py\r
2992 rootPath = os.path.split(curPath)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python\r
2993 if rootPath == "" or rootPath == None:\r
2994 EdkLogger.verbose("\nFail to find the root path of build.exe or python sources, so can not \\r
2995determine whether database file is out of date!\n")\r
2996 \r
2997 # walk the root path of source or build's binary to get the time last modified.\r
2998 \r
2999 for root, dirs, files in os.walk (rootPath):\r
3000 for dir in dirs:\r
3001 # bypass source control folder \r
3002 if dir.lower() in [".svn", "_svn", "cvs"]:\r
3003 dirs.remove(dir)\r
3004 \r
3005 for file in files:\r
3006 ext = os.path.splitext(file)[1]\r
3007 if ext.lower() == ".py": # only check .py files\r
3008 fd = os.stat(os.path.join(root, file))\r
3009 if timeOfToolModified < fd.st_mtime:\r
3010 timeOfToolModified = fd.st_mtime\r
3011 if timeOfToolModified > os.stat(DbPath).st_mtime:\r
3012 EdkLogger.verbose("\nWorkspace database is out of data!")\r
3013 return True\r
3014 \r
3015 return False\r
3016 \r
3017 ## Initialize build database\r
3018 def InitDatabase(self):\r
3019 EdkLogger.verbose("\nInitialize build database started ...")\r
3020\r
3021 #\r
3022 # Create new tables\r
3023 #\r
3024 self.TblDataModel.Create(False)\r
3025 self.TblFile.Create(False)\r
3026\r
3027 #\r
3028 # Initialize table DataModel\r
3029 #\r
3030 self.TblDataModel.InitTable()\r
3031 EdkLogger.verbose("Initialize build database ... DONE!")\r
3032\r
3033 ## Query a table\r
3034 #\r
3035 # @param Table: The instance of the table to be queried\r
3036 #\r
3037 def QueryTable(self, Table):\r
3038 Table.Query()\r
3039\r
0d2711a6
LG
3040 def __del__(self):\r
3041 self.Close()\r
3042\r
52302d4d
LG
3043 ## Close entire database\r
3044 #\r
3045 # Commit all first\r
3046 # Close the connection and cursor\r
3047 #\r
3048 def Close(self):\r
4234283c
LG
3049 if not self._DbClosedFlag:\r
3050 self.Conn.commit()\r
3051 self.Cur.close()\r
3052 self.Conn.close()\r
3053 self._DbClosedFlag = True\r
52302d4d 3054\r
52302d4d 3055 ## Summarize all packages in the database\r
0d2711a6
LG
3056 def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):\r
3057 self.Platform = Platform\r
47fea6af 3058 PackageList = []\r
0d2711a6
LG
3059 Pa = self.BuildObject[self.Platform, 'COMMON']\r
3060 #\r
3061 # Get Package related to Modules\r
3062 #\r
3063 for Module in Pa.Modules:\r
3064 ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag]\r
3065 for Package in ModuleObj.Packages:\r
52302d4d
LG
3066 if Package not in PackageList:\r
3067 PackageList.append(Package)\r
0d2711a6
LG
3068 #\r
3069 # Get Packages related to Libraries\r
3070 #\r
3071 for Lib in Pa.LibraryInstances:\r
3072 LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]\r
3073 for Package in LibObj.Packages:\r
3074 if Package not in PackageList:\r
47fea6af
YZ
3075 PackageList.append(Package)\r
3076\r
52302d4d
LG
3077 return PackageList\r
3078\r
3079 ## Summarize all platforms in the database\r
3080 def _GetPlatformList(self):\r
3081 PlatformList = []\r
3082 for PlatformFile in self.TblFile.GetFileList(MODEL_FILE_DSC):\r
3083 try:\r
3084 Platform = self.BuildObject[PathClass(PlatformFile), 'COMMON']\r
3085 except:\r
3086 Platform = None\r
3087 if Platform != None:\r
3088 PlatformList.append(Platform)\r
3089 return PlatformList\r
3090\r
f0dc69e6 3091 def _MapPlatform(self, Dscfile):\r
d429fcd0
YZ
3092 Platform = self.BuildObject[PathClass(Dscfile), 'COMMON']\r
3093 if Platform == None:\r
3094 EdkLogger.error('build', PARSER_ERROR, "Failed to parser DSC file: %s" % Dscfile)\r
f0dc69e6
YZ
3095 return Platform\r
3096\r
52302d4d 3097 PlatformList = property(_GetPlatformList)\r
52302d4d
LG
3098\r
3099##\r
3100#\r
3101# This acts like the main() function for the script, unless it is 'import'ed into another\r
3102# script.\r
3103#\r
3104if __name__ == '__main__':\r
3105 pass\r
3106\r