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