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