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