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