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