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