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