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