2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
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.
23 import Common
.EdkLogger
as EdkLogger
24 import Common
.GlobalData
as GlobalData
26 from Common
.String
import *
27 from Common
.DataType
import *
28 from Common
.Misc
import *
31 from CommonDataClass
.CommonClass
import SkuInfoClass
33 from MetaDataTable
import *
34 from MetaFileTable
import *
35 from MetaFileParser
import *
36 from BuildClassObject
import *
38 ## Platform build information from DSC file
40 # This class is used to retrieve information stored in database and convert them
41 # into PlatformBuildClassObject form for easier use for AutoGen.
43 class DscBuildData(PlatformBuildClassObject
):
44 # dict used to convert PCD type in database to string used by build tool
46 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
47 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
48 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
49 MODEL_PCD_DYNAMIC
: "Dynamic",
50 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
51 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
52 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
53 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
54 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
55 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
56 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
59 # dict used to convert part of [Defines] to members of DscBuildData directly
64 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
65 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
66 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
67 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
68 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
69 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
70 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
71 #TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
72 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
73 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
74 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
75 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
76 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
79 # used to compose dummy library class name for those forced library instances
80 _NullLibraryNumber
= 0
82 ## Constructor of DscBuildData
84 # Initialize object of DscBuildData
86 # @param FilePath The path of platform description file
87 # @param RawData The raw data of DSC file
88 # @param BuildDataBase Database used to retrieve module/package information
89 # @param Arch The target architecture
90 # @param Platform (not used for DscBuildData)
91 # @param Macros Macros used for replacement in DSC file
93 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Platform
='DUMMY', Macros
={}):
94 self
.MetaFile
= FilePath
95 self
._RawData
= RawData
96 self
._Bdb
= BuildDataBase
100 RecordList
= self
._RawData
[MODEL_META_DATA_DEFINE
, self
._Arch
]
101 for Record
in RecordList
:
102 GlobalData
.gEdkGlobal
[Record
[0]] = Record
[1]
104 RecordList
= self
._RawData
[MODEL_META_DATA_GLOBAL_DEFINE
, self
._Arch
]
105 for Record
in RecordList
:
106 GlobalData
.gGlobalDefines
[Record
[0]] = Record
[1]
109 def __setitem__(self
, key
, value
):
110 self
.__dict
__[self
._PROPERTY
_[key
]] = value
113 def __getitem__(self
, key
):
114 return self
.__dict
__[self
._PROPERTY
_[key
]]
117 def __contains__(self
, key
):
118 return key
in self
._PROPERTY
_
120 ## Set all internal used members of DscBuildData to None
123 self
._PlatformName
= None
126 self
._DscSpecification
= None
127 self
._OutputDirectory
= None
128 self
._SupArchList
= None
129 self
._BuildTargets
= None
131 self
._FlashDefinition
= None
132 self
._BuildNumber
= None
133 self
._MakefileName
= None
134 self
._BsBaseAddress
= None
135 self
._RtBaseAddress
= None
138 self
._LibraryInstances
= None
139 self
._LibraryClasses
= None
141 self
._BuildOptions
= None
142 self
._LoadFixAddress
= None
143 self
._VpdToolGuid
= None
144 self
._VpdFileName
= None
152 # Changing the default ARCH to another may affect all other information
153 # because all information in a platform may be ARCH-related. That's
154 # why we need to clear all internal used members, in order to cause all
155 # information to be re-retrieved.
157 # @param Value The value of ARCH
159 def _SetArch(self
, Value
):
160 if self
._Arch
== Value
:
165 ## Retrieve all information in [Defines] section
167 # (Retriving all [Defines] information in one-shot is just to save time.)
169 def _GetHeaderInfo(self
):
170 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
171 for Record
in RecordList
:
173 # items defined _PROPERTY_ don't need additional processing
175 self
[Name
] = Record
[1]
176 # some special items in [Defines] section need special treatment
177 elif Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
178 self
._OutputDirectory
= NormPath(Record
[1], self
._Macros
)
179 if ' ' in self
._OutputDirectory
:
180 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
181 File
=self
.MetaFile
, Line
=Record
[-1],
182 ExtraData
=self
._OutputDirectory
)
183 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
184 self
._FlashDefinition
= PathClass(NormPath(Record
[1], self
._Macros
), GlobalData
.gWorkspace
)
185 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
187 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
189 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
190 self
._SupArchList
= GetSplitValueList(Record
[1], TAB_VALUE_SPLIT
)
191 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
192 self
._BuildTargets
= GetSplitValueList(Record
[1])
193 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
194 if self
._SkuName
== None:
195 self
._SkuName
= Record
[1]
196 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
197 self
._LoadFixAddress
= Record
[1]
198 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
200 # try to convert GUID to a real UUID value to see whether the GUID is format
201 # for VPD_TOOL_GUID is correct.
206 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
207 self
._VpdToolGuid
= Record
[1]
208 elif Name
== TAB_DSC_DEFINES_VPD_FILENAME
:
209 self
._VpdFileName
= Record
[1]
210 # set _Header to non-None in order to avoid database re-querying
211 self
._Header
= 'DUMMY'
213 ## Retrieve platform name
214 def _GetPlatformName(self
):
215 if self
._PlatformName
== None:
216 if self
._Header
== None:
217 self
._GetHeaderInfo
()
218 if self
._PlatformName
== None:
219 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
220 return self
._PlatformName
222 ## Retrieve file guid
223 def _GetFileGuid(self
):
224 if self
._Guid
== None:
225 if self
._Header
== None:
226 self
._GetHeaderInfo
()
227 if self
._Guid
== None:
228 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No FILE_GUID", File
=self
.MetaFile
)
231 ## Retrieve platform version
232 def _GetVersion(self
):
233 if self
._Version
== None:
234 if self
._Header
== None:
235 self
._GetHeaderInfo
()
236 if self
._Version
== None:
240 ## Retrieve platform description file version
241 def _GetDscSpec(self
):
242 if self
._DscSpecification
== None:
243 if self
._Header
== None:
244 self
._GetHeaderInfo
()
245 if self
._DscSpecification
== None:
246 self
._DscSpecification
= ''
247 return self
._DscSpecification
249 ## Retrieve OUTPUT_DIRECTORY
250 def _GetOutpuDir(self
):
251 if self
._OutputDirectory
== None:
252 if self
._Header
== None:
253 self
._GetHeaderInfo
()
254 if self
._OutputDirectory
== None:
255 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
256 return self
._OutputDirectory
258 ## Retrieve SUPPORTED_ARCHITECTURES
259 def _GetSupArch(self
):
260 if self
._SupArchList
== None:
261 if self
._Header
== None:
262 self
._GetHeaderInfo
()
263 if self
._SupArchList
== None:
264 self
._SupArchList
= ARCH_LIST
265 return self
._SupArchList
267 ## Retrieve BUILD_TARGETS
268 def _GetBuildTarget(self
):
269 if self
._BuildTargets
== None:
270 if self
._Header
== None:
271 self
._GetHeaderInfo
()
272 if self
._BuildTargets
== None:
273 self
._BuildTargets
= ['DEBUG', 'RELEASE']
274 return self
._BuildTargets
276 ## Retrieve SKUID_IDENTIFIER
277 def _GetSkuName(self
):
278 if self
._SkuName
== None:
279 if self
._Header
== None:
280 self
._GetHeaderInfo
()
281 if self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
:
282 self
._SkuName
= 'DEFAULT'
285 ## Override SKUID_IDENTIFIER
286 def _SetSkuName(self
, Value
):
287 if Value
in self
.SkuIds
:
288 self
._SkuName
= Value
289 # Needs to re-retrieve the PCD information
292 def _GetFdfFile(self
):
293 if self
._FlashDefinition
== None:
294 if self
._Header
== None:
295 self
._GetHeaderInfo
()
296 if self
._FlashDefinition
== None:
297 self
._FlashDefinition
= ''
298 return self
._FlashDefinition
300 ## Retrieve FLASH_DEFINITION
301 def _GetBuildNumber(self
):
302 if self
._BuildNumber
== None:
303 if self
._Header
== None:
304 self
._GetHeaderInfo
()
305 if self
._BuildNumber
== None:
306 self
._BuildNumber
= ''
307 return self
._BuildNumber
309 ## Retrieve MAKEFILE_NAME
310 def _GetMakefileName(self
):
311 if self
._MakefileName
== None:
312 if self
._Header
== None:
313 self
._GetHeaderInfo
()
314 if self
._MakefileName
== None:
315 self
._MakefileName
= ''
316 return self
._MakefileName
318 ## Retrieve BsBaseAddress
319 def _GetBsBaseAddress(self
):
320 if self
._BsBaseAddress
== None:
321 if self
._Header
== None:
322 self
._GetHeaderInfo
()
323 if self
._BsBaseAddress
== None:
324 self
._BsBaseAddress
= ''
325 return self
._BsBaseAddress
327 ## Retrieve RtBaseAddress
328 def _GetRtBaseAddress(self
):
329 if self
._RtBaseAddress
== None:
330 if self
._Header
== None:
331 self
._GetHeaderInfo
()
332 if self
._RtBaseAddress
== None:
333 self
._RtBaseAddress
= ''
334 return self
._RtBaseAddress
336 ## Retrieve the top address for the load fix address
337 def _GetLoadFixAddress(self
):
338 if self
._LoadFixAddress
== None:
339 if self
._Header
== None:
340 self
._GetHeaderInfo
()
341 if self
._LoadFixAddress
== None:
342 self
._LoadFixAddress
= ''
343 return self
._LoadFixAddress
345 ## Retrieve the GUID string for VPD tool
346 def _GetVpdToolGuid(self
):
347 if self
._VpdToolGuid
== None:
348 if self
._Header
== None:
349 self
._GetHeaderInfo
()
350 if self
._VpdToolGuid
== None:
351 self
._VpdToolGuid
= ''
352 return self
._VpdToolGuid
354 ## Retrieve the VPD file Name, this is optional in DSC file
355 def _GetVpdFileName(self
):
356 if self
._VpdFileName
== None:
357 if self
._Header
== None:
358 self
._GetHeaderInfo
()
359 if self
._VpdFileName
== None:
360 self
._VpdFileName
= ''
361 return self
._VpdFileName
363 ## Retrieve [SkuIds] section information
364 def _GetSkuIds(self
):
365 if self
._SkuIds
== None:
367 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
]
368 for Record
in RecordList
:
369 if Record
[0] in [None, '']:
370 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
371 File
=self
.MetaFile
, Line
=Record
[-1])
372 if Record
[1] in [None, '']:
373 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
374 File
=self
.MetaFile
, Line
=Record
[-1])
375 self
._SkuIds
[Record
[1]] = Record
[0]
376 if 'DEFAULT' not in self
._SkuIds
:
377 self
._SkuIds
['DEFAULT'] = 0
380 ## Retrieve [Components] section information
381 def _GetModules(self
):
382 if self
._Modules
!= None:
385 self
._Modules
= sdict()
386 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
387 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
388 Macros
.update(self
._Macros
)
389 for Record
in RecordList
:
390 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
394 # check the file validation
395 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
397 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
400 if ModuleFile
in self
._Modules
:
401 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
403 Module
= ModuleBuildClassObject()
404 Module
.MetaFile
= ModuleFile
406 # get module override path
407 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
409 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
411 # Check if the source override path exists
412 if not os
.path
.isdir(Module
.SourceOverridePath
):
413 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
415 #Add to GlobalData Variables
416 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
418 # get module private library instance
419 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
420 for Record
in RecordList
:
421 LibraryClass
= Record
[0]
422 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
425 # check the file validation
426 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
428 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
431 if LibraryClass
== '' or LibraryClass
== 'NULL':
432 self
._NullLibraryNumber
+= 1
433 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
434 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
435 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
436 if LibraryPath
not in self
.LibraryInstances
:
437 self
.LibraryInstances
.append(LibraryPath
)
439 # get module private PCD setting
440 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
441 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
442 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
443 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
444 TokenList
= GetSplitValueList(Setting
)
445 DefaultValue
= TokenList
[0]
446 if len(TokenList
) > 1:
447 MaxDatumSize
= TokenList
[1]
450 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
451 Pcd
= PcdClassObject(
463 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
465 # get module private build options
466 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
467 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
468 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
469 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
471 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
472 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
474 self
._Modules
[ModuleFile
] = Module
477 ## Retrieve all possible library instances used in this platform
478 def _GetLibraryInstances(self
):
479 if self
._LibraryInstances
== None:
480 self
._GetLibraryClasses
()
481 return self
._LibraryInstances
483 ## Retrieve [LibraryClasses] information
484 def _GetLibraryClasses(self
):
485 if self
._LibraryClasses
== None:
486 self
._LibraryInstances
= []
488 # tdict is a special dict kind of type, used for selecting correct
489 # library instance for given library class and module type
491 LibraryClassDict
= tdict(True, 3)
492 # track all library class names
493 LibraryClassSet
= set()
494 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
495 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
496 Macros
.update(self
._Macros
)
497 for Record
in RecordList
:
498 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
499 if LibraryClass
== '' or LibraryClass
== 'NULL':
500 self
._NullLibraryNumber
+= 1
501 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
502 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
503 LibraryClassSet
.add(LibraryClass
)
504 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
505 # check the file validation
506 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
508 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
511 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
512 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
513 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
514 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
515 if LibraryInstance
not in self
._LibraryInstances
:
516 self
._LibraryInstances
.append(LibraryInstance
)
518 # resolve the specific library instance for each class and each module type
519 self
._LibraryClasses
= tdict(True)
520 for LibraryClass
in LibraryClassSet
:
521 # try all possible module types
522 for ModuleType
in SUP_MODULE_LIST
:
523 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
524 if LibraryInstance
== None:
526 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
528 # for R8 style library instances, which are listed in different section
529 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
530 for Record
in RecordList
:
531 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
533 # check the file validation
534 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
536 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
538 if File
not in self
._LibraryInstances
:
539 self
._LibraryInstances
.append(File
)
541 # we need the module name as the library class name, so we have
542 # to parse it here. (self._Bdb[] will trigger a file parse if it
543 # hasn't been parsed)
545 Library
= self
._Bdb
[File
, self
._Arch
]
546 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
547 return self
._LibraryClasses
549 ## Retrieve all PCD settings in platform
551 if self
._Pcds
== None:
553 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
554 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
555 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
556 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
557 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
558 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
559 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
560 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
561 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
564 ## Retrieve [BuildOptions]
565 def _GetBuildOptions(self
):
566 if self
._BuildOptions
== None:
567 self
._BuildOptions
= {}
569 # Retrieve build option for EDKII style module
571 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, 'COMMON', EDKII_NAME
]
572 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
573 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
575 # Retrieve build option for EDK style module
577 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, 'COMMON', EDK_NAME
]
578 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
579 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
580 return self
._BuildOptions
582 ## Retrieve non-dynamic PCD settings
584 # @param Type PCD type
586 # @retval a dict object contains settings of given PCD type
588 def _GetPcd(self
, Type
):
591 # tdict is a special dict kind of type, used for selecting correct
592 # PCD settings for certain ARCH
594 PcdDict
= tdict(True, 3)
596 # Find out all possible PCD candidates for self._Arch
597 RecordList
= self
._RawData
[Type
, self
._Arch
]
598 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
599 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
600 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
601 # Remove redundant PCD candidates
602 for PcdCName
, TokenSpaceGuid
in PcdSet
:
603 ValueList
= ['', '', '']
604 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
607 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
608 ValueList
[0:len(TokenList
)] = TokenList
609 PcdValue
, DatumType
, MaxDatumSize
= ValueList
610 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
613 self
._PCD
_TYPE
_STRING
_[Type
],
624 ## Retrieve dynamic PCD settings
626 # @param Type PCD type
628 # @retval a dict object contains settings of given PCD type
630 def _GetDynamicPcd(self
, Type
):
633 # tdict is a special dict kind of type, used for selecting correct
634 # PCD settings for certain ARCH and SKU
636 PcdDict
= tdict(True, 4)
638 # Find out all possible PCD candidates for self._Arch
639 RecordList
= self
._RawData
[Type
, self
._Arch
]
640 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
641 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
642 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
643 # Remove redundant PCD candidates, per the ARCH and SKU
644 for PcdCName
, TokenSpaceGuid
in PcdSet
:
645 ValueList
= ['', '', '']
646 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
649 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
650 ValueList
[0:len(TokenList
)] = TokenList
651 PcdValue
, DatumType
, MaxDatumSize
= ValueList
653 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', '', PcdValue
)
654 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
657 self
._PCD
_TYPE
_STRING
_[Type
],
662 {self
.SkuName
: SkuInfo
},
668 ## Retrieve dynamic HII PCD settings
670 # @param Type PCD type
672 # @retval a dict object contains settings of given PCD type
674 def _GetDynamicHiiPcd(self
, Type
):
677 # tdict is a special dict kind of type, used for selecting correct
678 # PCD settings for certain ARCH and SKU
680 PcdDict
= tdict(True, 4)
682 RecordList
= self
._RawData
[Type
, self
._Arch
]
683 # Find out all possible PCD candidates for self._Arch
684 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
685 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
686 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
687 # Remove redundant PCD candidates, per the ARCH and SKU
688 for PcdCName
, TokenSpaceGuid
in PcdSet
:
689 ValueList
= ['', '', '', '']
690 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
693 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
694 ValueList
[0:len(TokenList
)] = TokenList
695 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= ValueList
696 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
697 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
700 self
._PCD
_TYPE
_STRING
_[Type
],
705 {self
.SkuName
: SkuInfo
},
711 ## Retrieve dynamic VPD PCD settings
713 # @param Type PCD type
715 # @retval a dict object contains settings of given PCD type
717 def _GetDynamicVpdPcd(self
, Type
):
720 # tdict is a special dict kind of type, used for selecting correct
721 # PCD settings for certain ARCH and SKU
723 PcdDict
= tdict(True, 4)
725 # Find out all possible PCD candidates for self._Arch
726 RecordList
= self
._RawData
[Type
, self
._Arch
]
727 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
728 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
729 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
730 # Remove redundant PCD candidates, per the ARCH and SKU
731 for PcdCName
, TokenSpaceGuid
in PcdSet
:
732 ValueList
= ['', '', '']
733 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
736 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
737 ValueList
[0:len(TokenList
)] = TokenList
739 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
740 # For the Integer & Boolean type, the optional data can only be InitialValue.
741 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
742 # until the DEC parser has been called.
744 VpdOffset
, MaxDatumSize
, InitialValue
= ValueList
746 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
747 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
750 self
._PCD
_TYPE
_STRING
_[Type
],
755 {self
.SkuName
: SkuInfo
},
761 ## Add external modules
763 # The external modules are mostly those listed in FDF file, which don't
766 # @param FilePath The path of module description file
768 def AddModule(self
, FilePath
):
769 FilePath
= NormPath(FilePath
)
770 if FilePath
not in self
.Modules
:
771 Module
= ModuleBuildClassObject()
772 Module
.MetaFile
= FilePath
773 self
.Modules
.append(Module
)
777 # The external PCDs are mostly those listed in FDF file to specify address
778 # or offset information.
780 # @param Name Name of the PCD
781 # @param Guid Token space guid of the PCD
782 # @param Value Value of the PCD
784 def AddPcd(self
, Name
, Guid
, Value
):
785 if (Name
, Guid
) not in self
.Pcds
:
786 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
787 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
789 Arch
= property(_GetArch
, _SetArch
)
790 Platform
= property(_GetPlatformName
)
791 PlatformName
= property(_GetPlatformName
)
792 Guid
= property(_GetFileGuid
)
793 Version
= property(_GetVersion
)
794 DscSpecification
= property(_GetDscSpec
)
795 OutputDirectory
= property(_GetOutpuDir
)
796 SupArchList
= property(_GetSupArch
)
797 BuildTargets
= property(_GetBuildTarget
)
798 SkuName
= property(_GetSkuName
, _SetSkuName
)
799 FlashDefinition
= property(_GetFdfFile
)
800 BuildNumber
= property(_GetBuildNumber
)
801 MakefileName
= property(_GetMakefileName
)
802 BsBaseAddress
= property(_GetBsBaseAddress
)
803 RtBaseAddress
= property(_GetRtBaseAddress
)
804 LoadFixAddress
= property(_GetLoadFixAddress
)
805 VpdToolGuid
= property(_GetVpdToolGuid
)
806 VpdFileName
= property(_GetVpdFileName
)
807 SkuIds
= property(_GetSkuIds
)
808 Modules
= property(_GetModules
)
809 LibraryInstances
= property(_GetLibraryInstances
)
810 LibraryClasses
= property(_GetLibraryClasses
)
811 Pcds
= property(_GetPcds
)
812 BuildOptions
= property(_GetBuildOptions
)
814 ## Platform build information from DEC file
816 # This class is used to retrieve information stored in database and convert them
817 # into PackageBuildClassObject form for easier use for AutoGen.
819 class DecBuildData(PackageBuildClassObject
):
820 # dict used to convert PCD type in database to string used by build tool
821 _PCD_TYPE_STRING_
= {
822 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
823 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
824 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
825 MODEL_PCD_DYNAMIC
: "Dynamic",
826 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
827 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
828 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
829 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
830 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
831 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
832 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
835 # dict used to convert part of [Defines] to members of DecBuildData directly
840 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
841 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
842 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
843 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
847 ## Constructor of DecBuildData
849 # Initialize object of DecBuildData
851 # @param FilePath The path of package description file
852 # @param RawData The raw data of DEC file
853 # @param BuildDataBase Database used to retrieve module information
854 # @param Arch The target architecture
855 # @param Platform (not used for DecBuildData)
856 # @param Macros Macros used for replacement in DSC file
858 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Platform
='DUMMY', Macros
={}):
860 self
._PackageDir
= File
.Dir
861 self
._RawData
= RawData
862 self
._Bdb
= BuildDataBase
864 self
._Macros
= Macros
868 def __setitem__(self
, key
, value
):
869 self
.__dict
__[self
._PROPERTY
_[key
]] = value
872 def __getitem__(self
, key
):
873 return self
.__dict
__[self
._PROPERTY
_[key
]]
876 def __contains__(self
, key
):
877 return key
in self
._PROPERTY
_
879 ## Set all internal used members of DecBuildData to None
882 self
._PackageName
= None
885 self
._PkgUniFile
= None
886 self
._Protocols
= None
889 self
._Includes
= None
890 self
._LibraryClasses
= None
899 # Changing the default ARCH to another may affect all other information
900 # because all information in a platform may be ARCH-related. That's
901 # why we need to clear all internal used members, in order to cause all
902 # information to be re-retrieved.
904 # @param Value The value of ARCH
906 def _SetArch(self
, Value
):
907 if self
._Arch
== Value
:
912 ## Retrieve all information in [Defines] section
914 # (Retriving all [Defines] information in one-shot is just to save time.)
916 def _GetHeaderInfo(self
):
917 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
]
918 for Record
in RecordList
:
921 self
[Name
] = Record
[1]
922 self
._Header
= 'DUMMY'
924 ## Retrieve package name
925 def _GetPackageName(self
):
926 if self
._PackageName
== None:
927 if self
._Header
== None:
928 self
._GetHeaderInfo
()
929 if self
._PackageName
== None:
930 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
931 return self
._PackageName
933 ## Retrieve file guid
934 def _GetFileGuid(self
):
935 if self
._Guid
== None:
936 if self
._Header
== None:
937 self
._GetHeaderInfo
()
938 if self
._Guid
== None:
939 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
942 ## Retrieve package version
943 def _GetVersion(self
):
944 if self
._Version
== None:
945 if self
._Header
== None:
946 self
._GetHeaderInfo
()
947 if self
._Version
== None:
951 ## Retrieve protocol definitions (name/value pairs)
952 def _GetProtocol(self
):
953 if self
._Protocols
== None:
955 # tdict is a special kind of dict, used for selecting correct
956 # protocol defition for given ARCH
958 ProtocolDict
= tdict(True)
960 # find out all protocol definitions for specific and 'common' arch
961 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
962 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
963 if Name
not in NameList
:
964 NameList
.append(Name
)
965 ProtocolDict
[Arch
, Name
] = Guid
966 # use sdict to keep the order
967 self
._Protocols
= sdict()
968 for Name
in NameList
:
970 # limit the ARCH to self._Arch, if no self._Arch found, tdict
971 # will automatically turn to 'common' ARCH for trying
973 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
974 return self
._Protocols
976 ## Retrieve PPI definitions (name/value pairs)
978 if self
._Ppis
== None:
980 # tdict is a special kind of dict, used for selecting correct
981 # PPI defition for given ARCH
983 PpiDict
= tdict(True)
985 # find out all PPI definitions for specific arch and 'common' arch
986 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
987 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
988 if Name
not in NameList
:
989 NameList
.append(Name
)
990 PpiDict
[Arch
, Name
] = Guid
991 # use sdict to keep the order
993 for Name
in NameList
:
995 # limit the ARCH to self._Arch, if no self._Arch found, tdict
996 # will automatically turn to 'common' ARCH for trying
998 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1001 ## Retrieve GUID definitions (name/value pairs)
1003 if self
._Guids
== None:
1005 # tdict is a special kind of dict, used for selecting correct
1006 # GUID defition for given ARCH
1008 GuidDict
= tdict(True)
1010 # find out all protocol definitions for specific and 'common' arch
1011 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1012 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1013 if Name
not in NameList
:
1014 NameList
.append(Name
)
1015 GuidDict
[Arch
, Name
] = Guid
1016 # use sdict to keep the order
1017 self
._Guids
= sdict()
1018 for Name
in NameList
:
1020 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1021 # will automatically turn to 'common' ARCH for trying
1023 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1026 ## Retrieve public include paths declared in this package
1027 def _GetInclude(self
):
1028 if self
._Includes
== None:
1030 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1031 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1032 Macros
.update(self
._Macros
)
1033 for Record
in RecordList
:
1034 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1037 ErrorCode
, ErrorInfo
= File
.Validate()
1039 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1041 # avoid duplicate include path
1042 if File
not in self
._Includes
:
1043 self
._Includes
.append(File
)
1044 return self
._Includes
1046 ## Retrieve library class declarations (not used in build at present)
1047 def _GetLibraryClass(self
):
1048 if self
._LibraryClasses
== None:
1050 # tdict is a special kind of dict, used for selecting correct
1051 # library class declaration for given ARCH
1053 LibraryClassDict
= tdict(True)
1054 LibraryClassSet
= set()
1055 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1056 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1057 Macros
.update(self
._Macros
)
1058 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1059 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1060 # check the file validation
1061 ErrorCode
, ErrorInfo
= File
.Validate()
1063 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1064 LibraryClassSet
.add(LibraryClass
)
1065 LibraryClassDict
[Arch
, LibraryClass
] = File
1066 self
._LibraryClasses
= sdict()
1067 for LibraryClass
in LibraryClassSet
:
1068 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1069 return self
._LibraryClasses
1071 ## Retrieve PCD declarations
1073 if self
._Pcds
== None:
1075 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1076 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1077 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1078 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1079 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1082 ## Retrieve PCD declarations for given type
1083 def _GetPcd(self
, Type
):
1086 # tdict is a special kind of dict, used for selecting correct
1087 # PCD declaration for given ARCH
1089 PcdDict
= tdict(True, 3)
1090 # for summarizing PCD
1092 # find out all PCDs of the 'type'
1093 RecordList
= self
._RawData
[Type
, self
._Arch
]
1094 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1095 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1096 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1098 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1099 ValueList
= ['', '', '']
1101 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1102 # will automatically turn to 'common' ARCH and try again
1104 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1107 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
1108 ValueList
[0:len(TokenList
)] = TokenList
1109 DefaultValue
, DatumType
, TokenNumber
= ValueList
1110 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1113 self
._PCD
_TYPE
_STRING
_[Type
],
1125 Arch
= property(_GetArch
, _SetArch
)
1126 PackageName
= property(_GetPackageName
)
1127 Guid
= property(_GetFileGuid
)
1128 Version
= property(_GetVersion
)
1130 Protocols
= property(_GetProtocol
)
1131 Ppis
= property(_GetPpi
)
1132 Guids
= property(_GetGuid
)
1133 Includes
= property(_GetInclude
)
1134 LibraryClasses
= property(_GetLibraryClass
)
1135 Pcds
= property(_GetPcds
)
1137 ## Module build information from INF file
1139 # This class is used to retrieve information stored in database and convert them
1140 # into ModuleBuildClassObject form for easier use for AutoGen.
1142 class InfBuildData(ModuleBuildClassObject
):
1143 # dict used to convert PCD type in database to string used by build tool
1144 _PCD_TYPE_STRING_
= {
1145 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1146 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1147 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1148 MODEL_PCD_DYNAMIC
: "Dynamic",
1149 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1150 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1151 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1152 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1153 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1154 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1155 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1158 # dict used to convert part of [Defines] to members of InfBuildData directly
1163 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1164 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1165 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1169 TAB_INF_DEFINES_INF_VERSION
: "_AutoGenVersion",
1170 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1171 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1172 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1173 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1174 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1175 TAB_INF_DEFINES_VERSION
: "_Version",
1176 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1177 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1179 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1182 # dict used to convert Component type to Module type
1185 "SECURITY_CORE" : "SEC",
1186 "PEI_CORE" : "PEI_CORE",
1187 "COMBINED_PEIM_DRIVER" : "PEIM",
1188 "PIC_PEIM" : "PEIM",
1189 "RELOCATABLE_PEIM" : "PEIM",
1190 "PE32_PEIM" : "PEIM",
1191 "BS_DRIVER" : "DXE_DRIVER",
1192 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1193 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1194 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1195 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1196 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1197 # "BS_DRIVER" : "UEFI_DRIVER",
1198 "APPLICATION" : "UEFI_APPLICATION",
1202 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1203 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1204 # dict used to convert old tool name used in [nmake] section to new ones
1212 ## Constructor of DscBuildData
1214 # Initialize object of DscBuildData
1216 # @param FilePath The path of platform description file
1217 # @param RawData The raw data of DSC file
1218 # @param BuildDataBase Database used to retrieve module/package information
1219 # @param Arch The target architecture
1220 # @param Platform The name of platform employing this module
1221 # @param Macros Macros used for replacement in DSC file
1223 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Platform
='COMMON', Macros
={}):
1224 self
.MetaFile
= FilePath
1225 self
._ModuleDir
= FilePath
.Dir
1226 self
._RawData
= RawData
1227 self
._Bdb
= BuildDatabase
1229 self
._Platform
= 'COMMON'
1230 self
._Macros
= Macros
1231 self
._SourceOverridePath
= None
1232 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1233 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1237 def __setitem__(self
, key
, value
):
1238 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1241 def __getitem__(self
, key
):
1242 return self
.__dict
__[self
._PROPERTY
_[key
]]
1244 ## "in" test support
1245 def __contains__(self
, key
):
1246 return key
in self
._PROPERTY
_
1248 ## Set all internal used members of InfBuildData to None
1250 self
._Header
_ = None
1251 self
._AutoGenVersion
= None
1252 self
._BaseName
= None
1253 self
._ModuleType
= None
1254 self
._ComponentType
= None
1255 self
._BuildType
= None
1257 self
._Version
= None
1258 self
._PcdIsDriver
= None
1259 self
._BinaryModule
= None
1261 self
._MakefileName
= None
1262 self
._CustomMakefile
= None
1263 self
._Specification
= None
1264 self
._LibraryClass
= None
1265 self
._ModuleEntryPointList
= None
1266 self
._ModuleUnloadImageList
= None
1267 self
._ConstructorList
= None
1268 self
._DestructorList
= None
1270 self
._Binaries
= None
1271 self
._Sources
= None
1272 self
._LibraryClasses
= None
1273 self
._Libraries
= None
1274 self
._Protocols
= None
1277 self
._Includes
= None
1278 self
._Packages
= None
1280 self
._BuildOptions
= None
1282 self
._DepexExpression
= None
1283 #self._SourceOverridePath = None
1291 # Changing the default ARCH to another may affect all other information
1292 # because all information in a platform may be ARCH-related. That's
1293 # why we need to clear all internal used members, in order to cause all
1294 # information to be re-retrieved.
1296 # @param Value The value of ARCH
1298 def _SetArch(self
, Value
):
1299 if self
._Arch
== Value
:
1304 ## Return the name of platform employing this module
1305 def _GetPlatform(self
):
1306 return self
._Platform
1308 ## Change the name of platform employing this module
1310 # Changing the default name of platform to another may affect some information
1311 # because they may be PLATFORM-related. That's why we need to clear all internal
1312 # used members, in order to cause all information to be re-retrieved.
1314 def _SetPlatform(self
, Value
):
1315 if self
._Platform
== Value
:
1317 self
._Platform
= Value
1320 ## Retrieve all information in [Defines] section
1322 # (Retriving all [Defines] information in one-shot is just to save time.)
1324 def _GetHeaderInfo(self
):
1325 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1326 for Record
in RecordList
:
1327 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1329 # items defined _PROPERTY_ don't need additional processing
1331 self
[Name
] = Record
[1]
1332 # some special items in [Defines] section need special treatment
1333 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1334 if self
._Specification
== None:
1335 self
._Specification
= sdict()
1336 self
._Specification
['UEFI_SPECIFICATION_VERSION'] = Record
[1]
1337 elif Name
== 'EDK_RELEASE_VERSION':
1338 if self
._Specification
== None:
1339 self
._Specification
= sdict()
1340 self
._Specification
[Name
] = Record
[1]
1341 elif Name
== 'PI_SPECIFICATION_VERSION':
1342 if self
._Specification
== None:
1343 self
._Specification
= sdict()
1344 self
._Specification
[Name
] = Record
[1]
1345 elif Name
== 'LIBRARY_CLASS':
1346 if self
._LibraryClass
== None:
1347 self
._LibraryClass
= []
1348 ValueList
= GetSplitValueList(Record
[1])
1349 LibraryClass
= ValueList
[0]
1350 if len(ValueList
) > 1:
1351 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1353 SupModuleList
= SUP_MODULE_LIST
1354 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1355 elif Name
== 'ENTRY_POINT':
1356 if self
._ModuleEntryPointList
== None:
1357 self
._ModuleEntryPointList
= []
1358 self
._ModuleEntryPointList
.append(Record
[1])
1359 elif Name
== 'UNLOAD_IMAGE':
1360 if self
._ModuleUnloadImageList
== None:
1361 self
._ModuleUnloadImageList
= []
1364 self
._ModuleUnloadImageList
.append(Record
[1])
1365 elif Name
== 'CONSTRUCTOR':
1366 if self
._ConstructorList
== None:
1367 self
._ConstructorList
= []
1370 self
._ConstructorList
.append(Record
[1])
1371 elif Name
== 'DESTRUCTOR':
1372 if self
._DestructorList
== None:
1373 self
._DestructorList
= []
1376 self
._DestructorList
.append(Record
[1])
1377 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1378 TokenList
= GetSplitValueList(Record
[1])
1379 if self
._CustomMakefile
== None:
1380 self
._CustomMakefile
= {}
1381 if len(TokenList
) < 2:
1382 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1383 self
._CustomMakefile
['GCC'] = TokenList
[0]
1385 if TokenList
[0] not in ['MSFT', 'GCC']:
1386 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1387 "No supported family [%s]" % TokenList
[0],
1388 File
=self
.MetaFile
, Line
=Record
[-1])
1389 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1391 if self
._Defs
== None:
1392 self
._Defs
= sdict()
1393 self
._Defs
[Name
] = Record
[1]
1396 # Retrieve information in sections specific to R8.x modules
1398 if self
._AutoGenVersion
>= 0x00010005: # _AutoGenVersion may be None, which is less than anything
1399 if not self
._ModuleType
:
1400 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1401 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1402 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (self
._Specification
['PI_SPECIFICATION_VERSION'] < 0x0001000A):
1403 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1404 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
)
1405 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1406 and 'PCI_CLASS_CODE' in self
._Defs
:
1407 self
._BuildType
= 'UEFI_OPTIONROM'
1408 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1409 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1410 self
._BuildType
= 'UEFI_HII'
1412 self
._BuildType
= self
._ModuleType
.upper()
1414 self
._BuildType
= self
._ComponentType
.upper()
1415 if not self
._ComponentType
:
1416 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1417 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1418 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1419 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1420 if self
._ComponentType
== 'LIBRARY':
1421 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1422 # make use some [nmake] section macros
1423 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1424 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1425 Value
= Value
.replace('$(PROCESSOR)', self
._Arch
)
1426 Name
= Name
.replace('$(PROCESSOR)', self
._Arch
)
1427 Name
, Value
= ReplaceMacros((Name
, Value
), GlobalData
.gEdkGlobal
, True)
1428 if Name
== "IMAGE_ENTRY_POINT":
1429 if self
._ModuleEntryPointList
== None:
1430 self
._ModuleEntryPointList
= []
1431 self
._ModuleEntryPointList
.append(Value
)
1432 elif Name
== "DPX_SOURCE":
1433 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1434 Macros
.update(self
._Macros
)
1435 File
= PathClass(NormPath(Value
, Macros
), self
._ModuleDir
, Arch
=self
._Arch
)
1436 # check the file validation
1437 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1439 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1440 File
=self
.MetaFile
, Line
=LineNo
)
1441 if self
.Sources
== None:
1443 self
._Sources
.append(File
)
1445 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1446 if len(ToolList
) == 0 or len(ToolList
) != 1:
1448 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1449 # File=self.MetaFile, Line=LineNo)
1451 if self
._BuildOptions
== None:
1452 self
._BuildOptions
= sdict()
1454 if ToolList
[0] in self
._TOOL
_CODE
_:
1455 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1458 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1459 ToolChainFamily
= 'MSFT' # R8.x only support MSFT tool chain
1460 #ignore not replaced macros in value
1461 ValueList
= GetSplitValueList(' ' + Value
, '/D')
1462 Dummy
= ValueList
[0]
1463 for Index
in range(1, len(ValueList
)):
1464 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1466 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1467 Value
= Dummy
.strip()
1468 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1469 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1471 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1472 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1473 # set _Header to non-None in order to avoid database re-querying
1474 self
._Header
_ = 'DUMMY'
1476 ## Retrieve file version
1477 def _GetInfVersion(self
):
1478 if self
._AutoGenVersion
== None:
1479 if self
._Header
_ == None:
1480 self
._GetHeaderInfo
()
1481 if self
._AutoGenVersion
== None:
1482 self
._AutoGenVersion
= 0x00010000
1483 return self
._AutoGenVersion
1485 ## Retrieve BASE_NAME
1486 def _GetBaseName(self
):
1487 if self
._BaseName
== None:
1488 if self
._Header
_ == None:
1489 self
._GetHeaderInfo
()
1490 if self
._BaseName
== None:
1491 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1492 return self
._BaseName
1494 ## Retrieve MODULE_TYPE
1495 def _GetModuleType(self
):
1496 if self
._ModuleType
== None:
1497 if self
._Header
_ == None:
1498 self
._GetHeaderInfo
()
1499 if self
._ModuleType
== None:
1500 self
._ModuleType
= 'BASE'
1501 if self
._ModuleType
not in SUP_MODULE_LIST
:
1502 self
._ModuleType
= "USER_DEFINED"
1503 return self
._ModuleType
1505 ## Retrieve COMPONENT_TYPE
1506 def _GetComponentType(self
):
1507 if self
._ComponentType
== None:
1508 if self
._Header
_ == None:
1509 self
._GetHeaderInfo
()
1510 if self
._ComponentType
== None:
1511 self
._ComponentType
= 'USER_DEFINED'
1512 return self
._ComponentType
1514 ## Retrieve "BUILD_TYPE"
1515 def _GetBuildType(self
):
1516 if self
._BuildType
== None:
1517 if self
._Header
_ == None:
1518 self
._GetHeaderInfo
()
1519 if not self
._BuildType
:
1520 self
._BuildType
= "BASE"
1521 return self
._BuildType
1523 ## Retrieve file guid
1524 def _GetFileGuid(self
):
1525 if self
._Guid
== None:
1526 if self
._Header
_ == None:
1527 self
._GetHeaderInfo
()
1528 if self
._Guid
== None:
1529 self
._Guid
= '00000000-0000-0000-000000000000'
1532 ## Retrieve module version
1533 def _GetVersion(self
):
1534 if self
._Version
== None:
1535 if self
._Header
_ == None:
1536 self
._GetHeaderInfo
()
1537 if self
._Version
== None:
1538 self
._Version
= '0.0'
1539 return self
._Version
1541 ## Retrieve PCD_IS_DRIVER
1542 def _GetPcdIsDriver(self
):
1543 if self
._PcdIsDriver
== None:
1544 if self
._Header
_ == None:
1545 self
._GetHeaderInfo
()
1546 if self
._PcdIsDriver
== None:
1547 self
._PcdIsDriver
= ''
1548 return self
._PcdIsDriver
1551 def _GetShadow(self
):
1552 if self
._Shadow
== None:
1553 if self
._Header
_ == None:
1554 self
._GetHeaderInfo
()
1555 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1558 self
._Shadow
= False
1561 ## Retrieve CUSTOM_MAKEFILE
1562 def _GetMakefile(self
):
1563 if self
._CustomMakefile
== None:
1564 if self
._Header
_ == None:
1565 self
._GetHeaderInfo
()
1566 if self
._CustomMakefile
== None:
1567 self
._CustomMakefile
= {}
1568 return self
._CustomMakefile
1570 ## Retrieve EFI_SPECIFICATION_VERSION
1572 if self
._Specification
== None:
1573 if self
._Header
_ == None:
1574 self
._GetHeaderInfo
()
1575 if self
._Specification
== None:
1576 self
._Specification
= {}
1577 return self
._Specification
1579 ## Retrieve LIBRARY_CLASS
1580 def _GetLibraryClass(self
):
1581 if self
._LibraryClass
== None:
1582 if self
._Header
_ == None:
1583 self
._GetHeaderInfo
()
1584 if self
._LibraryClass
== None:
1585 self
._LibraryClass
= []
1586 return self
._LibraryClass
1588 ## Retrieve ENTRY_POINT
1589 def _GetEntryPoint(self
):
1590 if self
._ModuleEntryPointList
== None:
1591 if self
._Header
_ == None:
1592 self
._GetHeaderInfo
()
1593 if self
._ModuleEntryPointList
== None:
1594 self
._ModuleEntryPointList
= []
1595 return self
._ModuleEntryPointList
1597 ## Retrieve UNLOAD_IMAGE
1598 def _GetUnloadImage(self
):
1599 if self
._ModuleUnloadImageList
== None:
1600 if self
._Header
_ == None:
1601 self
._GetHeaderInfo
()
1602 if self
._ModuleUnloadImageList
== None:
1603 self
._ModuleUnloadImageList
= []
1604 return self
._ModuleUnloadImageList
1606 ## Retrieve CONSTRUCTOR
1607 def _GetConstructor(self
):
1608 if self
._ConstructorList
== None:
1609 if self
._Header
_ == None:
1610 self
._GetHeaderInfo
()
1611 if self
._ConstructorList
== None:
1612 self
._ConstructorList
= []
1613 return self
._ConstructorList
1615 ## Retrieve DESTRUCTOR
1616 def _GetDestructor(self
):
1617 if self
._DestructorList
== None:
1618 if self
._Header
_ == None:
1619 self
._GetHeaderInfo
()
1620 if self
._DestructorList
== None:
1621 self
._DestructorList
= []
1622 return self
._DestructorList
1624 ## Retrieve definies other than above ones
1625 def _GetDefines(self
):
1626 if self
._Defs
== None:
1627 if self
._Header
_ == None:
1628 self
._GetHeaderInfo
()
1629 if self
._Defs
== None:
1630 self
._Defs
= sdict()
1633 ## Retrieve binary files
1634 def _GetBinaryFiles(self
):
1635 if self
._Binaries
== None:
1637 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
1638 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
, 'PROCESSOR':self
._Arch
}
1639 Macros
.update(self
._Macros
)
1640 for Record
in RecordList
:
1641 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1642 FileType
= Record
[0]
1647 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
1649 Target
= TokenList
[0]
1650 if len(TokenList
) > 1:
1651 FeatureFlag
= Record
[1:]
1653 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
1654 # check the file validation
1655 ErrorCode
, ErrorInfo
= File
.Validate()
1657 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1658 self
._Binaries
.append(File
)
1659 return self
._Binaries
1661 ## Retrieve source files
1662 def _GetSourceFiles(self
):
1663 if self
._Sources
== None:
1665 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
1666 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
, 'PROCESSOR':self
._Arch
}
1667 Macros
.update(self
._Macros
)
1668 for Record
in RecordList
:
1669 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1671 ToolChainFamily
= Record
[1]
1673 ToolCode
= Record
[3]
1674 FeatureFlag
= Record
[4]
1675 if self
._AutoGenVersion
< 0x00010005:
1676 # old module source files (R8)
1677 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
1678 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1679 # check the file validation
1680 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
1682 if File
.Ext
.lower() == '.h':
1683 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
1684 File
=self
.MetaFile
, Line
=LineNo
)
1687 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
1689 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
1690 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1691 # check the file validation
1692 ErrorCode
, ErrorInfo
= File
.Validate()
1694 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1696 self
._Sources
.append(File
)
1697 return self
._Sources
1699 ## Retrieve library classes employed by this module
1700 def _GetLibraryClassUses(self
):
1701 if self
._LibraryClasses
== None:
1702 self
._LibraryClasses
= sdict()
1703 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
1704 for Record
in RecordList
:
1705 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1707 Instance
= Record
[1]
1708 if Instance
!= None and Instance
!= '':
1709 Instance
= NormPath(Instance
, self
._Macros
)
1710 self
._LibraryClasses
[Lib
] = Instance
1711 return self
._LibraryClasses
1713 ## Retrieve library names (for R8.x style of modules)
1714 def _GetLibraryNames(self
):
1715 if self
._Libraries
== None:
1716 self
._Libraries
= []
1717 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
1718 for Record
in RecordList
:
1719 # in case of name with '.lib' extension, which is unusual in R8.x inf
1720 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1721 LibraryName
= os
.path
.splitext(Record
[0])[0]
1722 if LibraryName
not in self
._Libraries
:
1723 self
._Libraries
.append(LibraryName
)
1724 return self
._Libraries
1726 ## Retrieve protocols consumed/produced by this module
1727 def _GetProtocols(self
):
1728 if self
._Protocols
== None:
1729 self
._Protocols
= sdict()
1730 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
1731 for Record
in RecordList
:
1733 Value
= ProtocolValue(CName
, self
.Packages
)
1735 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1736 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1737 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
1738 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1739 self
._Protocols
[CName
] = Value
1740 return self
._Protocols
1742 ## Retrieve PPIs consumed/produced by this module
1744 if self
._Ppis
== None:
1745 self
._Ppis
= sdict()
1746 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
1747 for Record
in RecordList
:
1749 Value
= PpiValue(CName
, self
.Packages
)
1751 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1752 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1753 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
1754 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1755 self
._Ppis
[CName
] = Value
1758 ## Retrieve GUIDs consumed/produced by this module
1759 def _GetGuids(self
):
1760 if self
._Guids
== None:
1761 self
._Guids
= sdict()
1762 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
1763 for Record
in RecordList
:
1765 Value
= GuidValue(CName
, self
.Packages
)
1767 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1768 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1769 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
1770 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1771 self
._Guids
[CName
] = Value
1774 ## Retrieve include paths necessary for this module (for R8.x style of modules)
1775 def _GetIncludes(self
):
1776 if self
._Includes
== None:
1778 if self
._SourceOverridePath
:
1779 self
._Includes
.append(self
._SourceOverridePath
)
1780 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
1781 # [includes] section must be used only in old (R8.x) inf file
1782 if self
.AutoGenVersion
>= 0x00010005 and len(RecordList
) > 0:
1783 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, "No [include] section allowed",
1784 File
=self
.MetaFile
, Line
=RecordList
[0][-1]-1)
1785 for Record
in RecordList
:
1786 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1787 Record
[0] = Record
[0].replace('$(PROCESSOR)', self
._Arch
)
1788 Record
[0] = ReplaceMacro(Record
[0], {'EFI_SOURCE' : GlobalData
.gEfiSource
}, False)
1789 if Record
[0].find('EDK_SOURCE') > -1:
1790 File
= NormPath(ReplaceMacro(Record
[0], {'EDK_SOURCE' : GlobalData
.gEcpSource
}, False), self
._Macros
)
1792 File
= os
.path
.join(self
._ModuleDir
, File
)
1794 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1795 File
= RealPath(os
.path
.normpath(File
))
1797 self
._Includes
.append(File
)
1799 #TRICK: let compiler to choose correct header file
1800 File
= NormPath(ReplaceMacro(Record
[0], {'EDK_SOURCE' : GlobalData
.gEdkSource
}, False), self
._Macros
)
1802 File
= os
.path
.join(self
._ModuleDir
, File
)
1804 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1805 File
= RealPath(os
.path
.normpath(File
))
1807 self
._Includes
.append(File
)
1809 File
= NormPath(Record
[0], self
._Macros
)
1811 File
= os
.path
.join(self
._ModuleDir
, File
)
1813 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1814 File
= RealPath(os
.path
.normpath(File
))
1816 self
._Includes
.append(File
)
1817 return self
._Includes
1819 ## Retrieve packages this module depends on
1820 def _GetPackages(self
):
1821 if self
._Packages
== None:
1823 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
1824 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1825 Macros
.update(self
._Macros
)
1826 for Record
in RecordList
:
1827 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
1829 # check the file validation
1830 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
1832 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1833 # parse this package now. we need it to get protocol/ppi/guid value
1834 Package
= self
._Bdb
[File
, self
._Arch
]
1835 self
._Packages
.append(Package
)
1836 return self
._Packages
1838 ## Retrieve PCDs used in this module
1840 if self
._Pcds
== None:
1842 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1843 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1844 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1845 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1846 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1849 ## Retrieve build options specific to this module
1850 def _GetBuildOptions(self
):
1851 if self
._BuildOptions
== None:
1852 self
._BuildOptions
= sdict()
1853 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
1854 for Record
in RecordList
:
1855 ToolChainFamily
= Record
[0]
1856 ToolChain
= Record
[1]
1858 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1859 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
1861 # concatenate the option string if they're for the same tool
1862 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1863 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
1864 return self
._BuildOptions
1866 ## Retrieve depedency expression
1867 def _GetDepex(self
):
1868 if self
._Depex
== None:
1869 self
._Depex
= tdict(False, 2)
1870 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1872 # PEIM and DXE drivers must have a valid [Depex] section
1873 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
1874 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
1875 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
1876 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
1877 % self
.ModuleType
, File
=self
.MetaFile
)
1880 for Record
in RecordList
:
1881 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1883 ModuleType
= Record
[4]
1884 TokenList
= Record
[0].split()
1885 if (Arch
, ModuleType
) not in Depex
:
1886 Depex
[Arch
, ModuleType
] = []
1887 DepexList
= Depex
[Arch
, ModuleType
]
1888 for Token
in TokenList
:
1889 if Token
in DEPEX_SUPPORTED_OPCODE
:
1890 DepexList
.append(Token
)
1891 elif Token
.endswith(".inf"): # module file name
1892 ModuleFile
= os
.path
.normpath(Token
)
1893 Module
= self
.BuildDatabase
[ModuleFile
]
1895 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
1896 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
1897 DepexList
.append(Module
.Guid
)
1899 # get the GUID value now
1900 Value
= ProtocolValue(Token
, self
.Packages
)
1902 Value
= PpiValue(Token
, self
.Packages
)
1904 Value
= GuidValue(Token
, self
.Packages
)
1906 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1907 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1908 "Value of [%s] is not found in" % Token
,
1909 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1910 DepexList
.append(Value
)
1911 for Arch
, ModuleType
in Depex
:
1912 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
1915 ## Retrieve depedency expression
1916 def _GetDepexExpression(self
):
1917 if self
._DepexExpression
== None:
1918 self
._DepexExpression
= tdict(False, 2)
1919 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1920 DepexExpression
= {}
1921 for Record
in RecordList
:
1922 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1924 ModuleType
= Record
[4]
1925 TokenList
= Record
[0].split()
1926 if (Arch
, ModuleType
) not in DepexExpression
:
1927 DepexExpression
[Arch
, ModuleType
] = ''
1928 for Token
in TokenList
:
1929 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
1930 for Arch
, ModuleType
in DepexExpression
:
1931 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
1932 return self
._DepexExpression
1934 ## Retrieve PCD for given type
1935 def _GetPcd(self
, Type
):
1937 PcdDict
= tdict(True, 4)
1939 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
1940 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Dummy1
, LineNo
in RecordList
:
1941 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
1942 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1943 # get the guid value
1944 if TokenSpaceGuid
not in self
.Guids
:
1945 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
1947 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1948 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1949 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
1950 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
1951 self
.Guids
[TokenSpaceGuid
] = Value
1953 # resolve PCD type, value, datum info, etc. by getting its definition from package
1954 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1955 ValueList
= ['', '']
1956 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
1959 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
1960 ValueList
[0:len(TokenList
)] = TokenList
1961 DefaultValue
= ValueList
[0]
1962 Pcd
= PcdClassObject(
1972 self
.Guids
[TokenSpaceGuid
]
1975 # get necessary info from package declaring this PCD
1976 for Package
in self
.Packages
:
1978 # 'dynamic' in INF means its type is determined by platform;
1979 # if platform doesn't give its type, use 'lowest' one in the
1980 # following order, if any
1982 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
1984 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
1985 if Type
== MODEL_PCD_DYNAMIC
:
1987 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
1988 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
1994 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
1995 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
1997 Pcd
.TokenValue
= PcdInPackage
.TokenValue
1998 Pcd
.DatumType
= PcdInPackage
.DatumType
1999 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2000 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2001 if Pcd
.DefaultValue
in [None, '']:
2002 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2008 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2009 File
=self
.MetaFile
, Line
=LineNo
,
2010 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2012 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2015 Arch
= property(_GetArch
, _SetArch
)
2016 Platform
= property(_GetPlatform
, _SetPlatform
)
2018 AutoGenVersion
= property(_GetInfVersion
)
2019 BaseName
= property(_GetBaseName
)
2020 ModuleType
= property(_GetModuleType
)
2021 ComponentType
= property(_GetComponentType
)
2022 BuildType
= property(_GetBuildType
)
2023 Guid
= property(_GetFileGuid
)
2024 Version
= property(_GetVersion
)
2025 PcdIsDriver
= property(_GetPcdIsDriver
)
2026 Shadow
= property(_GetShadow
)
2027 CustomMakefile
= property(_GetMakefile
)
2028 Specification
= property(_GetSpec
)
2029 LibraryClass
= property(_GetLibraryClass
)
2030 ModuleEntryPointList
= property(_GetEntryPoint
)
2031 ModuleUnloadImageList
= property(_GetUnloadImage
)
2032 ConstructorList
= property(_GetConstructor
)
2033 DestructorList
= property(_GetDestructor
)
2034 Defines
= property(_GetDefines
)
2036 Binaries
= property(_GetBinaryFiles
)
2037 Sources
= property(_GetSourceFiles
)
2038 LibraryClasses
= property(_GetLibraryClassUses
)
2039 Libraries
= property(_GetLibraryNames
)
2040 Protocols
= property(_GetProtocols
)
2041 Ppis
= property(_GetPpis
)
2042 Guids
= property(_GetGuids
)
2043 Includes
= property(_GetIncludes
)
2044 Packages
= property(_GetPackages
)
2045 Pcds
= property(_GetPcds
)
2046 BuildOptions
= property(_GetBuildOptions
)
2047 Depex
= property(_GetDepex
)
2048 DepexExpression
= property(_GetDepexExpression
)
2052 # This class defined the build database for all modules, packages and platform.
2053 # It will call corresponding parser for the given file if it cannot find it in
2056 # @param DbPath Path of database file
2057 # @param GlobalMacros Global macros used for replacement during file parsing
2058 # @prarm RenewDb=False Create new database file if it's already there
2060 class WorkspaceDatabase(object):
2063 MODEL_FILE_INF
: InfParser
,
2064 MODEL_FILE_DEC
: DecParser
,
2065 MODEL_FILE_DSC
: DscParser
,
2066 MODEL_FILE_FDF
: None, #FdfParser,
2067 MODEL_FILE_CIF
: None
2072 MODEL_FILE_INF
: ModuleTable
,
2073 MODEL_FILE_DEC
: PackageTable
,
2074 MODEL_FILE_DSC
: PlatformTable
,
2077 # default database file path
2078 _DB_PATH_
= "Conf/.cache/build.db"
2081 # internal class used for call corresponding file parser and caching the result
2082 # to avoid unnecessary re-parsing
2084 class BuildObjectFactory(object):
2086 ".inf" : MODEL_FILE_INF
,
2087 ".dec" : MODEL_FILE_DEC
,
2088 ".dsc" : MODEL_FILE_DSC
,
2089 ".fdf" : MODEL_FILE_FDF
,
2092 # convert to xxxBuildData object
2094 MODEL_FILE_INF
: InfBuildData
,
2095 MODEL_FILE_DEC
: DecBuildData
,
2096 MODEL_FILE_DSC
: DscBuildData
,
2097 MODEL_FILE_FDF
: None #FlashDefTable,
2100 _CACHE_
= {} # (FilePath, Arch) : <object>
2103 def __init__(self
, WorkspaceDb
):
2104 self
.WorkspaceDb
= WorkspaceDb
2106 # key = (FilePath, Arch='COMMON')
2107 def __contains__(self
, Key
):
2112 return (FilePath
, Arch
) in self
._CACHE
_
2114 # key = (FilePath, Arch='COMMON')
2115 def __getitem__(self
, Key
):
2124 # if it's generated before, just return the cached one
2125 Key
= (FilePath
, Arch
)
2126 if Key
in self
._CACHE
_:
2127 return self
._CACHE
_[Key
]
2130 Ext
= FilePath
.Ext
.lower()
2131 if Ext
not in self
._FILE
_TYPE
_:
2133 FileType
= self
._FILE
_TYPE
_[Ext
]
2134 if FileType
not in self
._GENERATOR
_:
2137 # get table for current file
2138 MetaFile
= self
.WorkspaceDb
[FilePath
, FileType
, self
.WorkspaceDb
._GlobalMacros
]
2139 BuildObject
= self
._GENERATOR
_[FileType
](
2145 self
.WorkspaceDb
._GlobalMacros
,
2147 self
._CACHE
_[Key
] = BuildObject
2150 # placeholder for file format conversion
2151 class TransformObjectFactory
:
2152 def __init__(self
, WorkspaceDb
):
2153 self
.WorkspaceDb
= WorkspaceDb
2155 # key = FilePath, Arch
2156 def __getitem__(self
, Key
):
2159 ## Constructor of WorkspaceDatabase
2161 # @param DbPath Path of database file
2162 # @param GlobalMacros Global macros used for replacement during file parsing
2163 # @prarm RenewDb=False Create new database file if it's already there
2165 def __init__(self
, DbPath
, GlobalMacros
={}, RenewDb
=False):
2166 self
._GlobalMacros
= GlobalMacros
2168 if DbPath
== None or DbPath
== '':
2169 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2171 # don't create necessary path for db in memory
2172 if DbPath
!= ':memory:':
2173 DbDir
= os
.path
.split(DbPath
)[0]
2174 if not os
.path
.exists(DbDir
):
2177 # remove db file in case inconsistency between db and file in file system
2178 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2181 # create db with optimized parameters
2182 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2183 self
.Conn
.execute("PRAGMA synchronous=OFF")
2184 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2185 self
.Conn
.execute("PRAGMA count_changes=OFF")
2186 self
.Conn
.execute("PRAGMA cache_size=8192")
2187 #self.Conn.execute("PRAGMA page_size=8192")
2189 # to avoid non-ascii character conversion issue
2190 self
.Conn
.text_factory
= str
2191 self
.Cur
= self
.Conn
.cursor()
2193 # create table for internal uses
2194 self
.TblDataModel
= TableDataModel(self
.Cur
)
2195 self
.TblFile
= TableFile(self
.Cur
)
2197 # conversion object for build or file format conversion purpose
2198 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2199 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2201 ## Check whether workspace database need to be renew.
2202 # The renew reason maybe:
2203 # 1) If user force to renew;
2204 # 2) If user do not force renew, and
2205 # a) If the time of last modified python source is newer than database file;
2206 # b) If the time of last modified frozen executable file is newer than database file;
2208 # @param force User force renew database
2209 # @param DbPath The absolute path of workspace database file
2211 # @return Bool value for whether need renew workspace databse
2213 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2214 DbDir
= os
.path
.split(DbPath
)[0]
2215 MacroFilePath
= os
.path
.normpath(os
.path
.join(DbDir
, "build.mac"))
2217 if os
.path
.exists(MacroFilePath
) and os
.path
.isfile(MacroFilePath
):
2220 f
= open(MacroFilePath
,'r')
2221 LastMacros
= pickle
.load(f
)
2228 if LastMacros
!= None and type(LastMacros
) is DictType
:
2229 if LastMacros
== self
._GlobalMacros
:
2231 for Macro
in LastMacros
.keys():
2232 if not (Macro
in self
._GlobalMacros
and LastMacros
[Macro
] == self
._GlobalMacros
[Macro
]):
2237 # save command line macros to file
2239 f
= open(MacroFilePath
,'w')
2240 pickle
.dump(self
._GlobalMacros
, f
, 2)
2249 # if database does not exist, we need do nothing
2250 if not os
.path
.exists(DbPath
): return False
2252 # if user force to renew database, then not check whether database is out of date
2253 if force
: return True
2256 # Check the time of last modified source file or build.exe
2257 # if is newer than time of database, then database need to be re-created.
2259 timeOfToolModified
= 0
2260 if hasattr(sys
, "frozen"):
2261 exePath
= os
.path
.abspath(sys
.executable
)
2262 timeOfToolModified
= os
.stat(exePath
).st_mtime
2264 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2265 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2266 if rootPath
== "" or rootPath
== None:
2267 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2268 determine whether database file is out of date!\n")
2270 # walk the root path of source or build's binary to get the time last modified.
2272 for root
, dirs
, files
in os
.walk (rootPath
):
2274 # bypass source control folder
2275 if dir.lower() in [".svn", "_svn", "cvs"]:
2279 ext
= os
.path
.splitext(file)[1]
2280 if ext
.lower() == ".py": # only check .py files
2281 fd
= os
.stat(os
.path
.join(root
, file))
2282 if timeOfToolModified
< fd
.st_mtime
:
2283 timeOfToolModified
= fd
.st_mtime
2284 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2285 EdkLogger
.verbose("\nWorkspace database is out of data!")
2290 ## Initialize build database
2291 def InitDatabase(self
):
2292 EdkLogger
.verbose("\nInitialize build database started ...")
2297 self
.TblDataModel
.Create(False)
2298 self
.TblFile
.Create(False)
2301 # Initialize table DataModel
2303 self
.TblDataModel
.InitTable()
2304 EdkLogger
.verbose("Initialize build database ... DONE!")
2308 # @param Table: The instance of the table to be queried
2310 def QueryTable(self
, Table
):
2313 ## Close entire database
2316 # Close the connection and cursor
2323 ## Get unique file ID for the gvien file
2324 def GetFileId(self
, FilePath
):
2325 return self
.TblFile
.GetFileId(FilePath
)
2327 ## Get file type value for the gvien file ID
2328 def GetFileType(self
, FileId
):
2329 return self
.TblFile
.GetFileType(FileId
)
2331 ## Get time stamp stored in file table
2332 def GetTimeStamp(self
, FileId
):
2333 return self
.TblFile
.GetFileTimeStamp(FileId
)
2335 ## Update time stamp in file table
2336 def SetTimeStamp(self
, FileId
, TimeStamp
):
2337 return self
.TblFile
.SetFileTimeStamp(FileId
, TimeStamp
)
2339 ## Check if a table integrity flag exists or not
2340 def CheckIntegrity(self
, TableName
):
2342 Result
= self
.Cur
.execute("select min(ID) from %s" % (TableName
)).fetchall()
2343 if Result
[0][0] != -1:
2346 # Check whether the meta data file has external dependency by comparing the time stamp
2348 Sql
= "select Value1, Value2 from %s where Model=%d" % (TableName
, MODEL_EXTERNAL_DEPENDENCY
)
2349 for Dependency
in self
.Cur
.execute(Sql
).fetchall():
2350 if str(os
.stat(Dependency
[0])[8]) != Dependency
[1]:
2356 ## Compose table name for given file type and file ID
2357 def GetTableName(self
, FileType
, FileId
):
2358 return "_%s_%s" % (FileType
, FileId
)
2360 ## Return a temp table containing all content of the given file
2362 # @param FileInfo The tuple containing path and type of a file
2364 def __getitem__(self
, FileInfo
):
2365 FilePath
, FileType
, Macros
= FileInfo
2366 if FileType
not in self
._FILE
_TABLE
_:
2369 # flag used to indicate if it's parsed or not
2370 FilePath
= str(FilePath
)
2372 FileId
= self
.GetFileId(FilePath
)
2374 TimeStamp
= os
.stat(FilePath
)[8]
2375 TableName
= self
.GetTableName(FileType
, FileId
)
2376 if TimeStamp
!= self
.GetTimeStamp(FileId
):
2377 # update the timestamp in database
2378 self
.SetTimeStamp(FileId
, TimeStamp
)
2380 # if the table exists and is integrity, don't parse it
2381 Parsed
= self
.CheckIntegrity(TableName
)
2383 FileId
= self
.TblFile
.InsertFile(FilePath
, FileType
)
2384 TableName
= self
.GetTableName(FileType
, FileId
)
2386 FileTable
= self
._FILE
_TABLE
_[FileType
](self
.Cur
, TableName
, FileId
)
2387 FileTable
.Create(not Parsed
)
2388 Parser
= self
._FILE
_PARSER
_[FileType
](FilePath
, FileType
, FileTable
, Macros
)
2389 # set the "Finished" flag in parser in order to avoid re-parsing (if parsed)
2390 Parser
.Finished
= Parsed
2393 ## Summarize all packages in the database
2394 def _GetPackageList(self
):
2396 for Module
in self
.ModuleList
:
2397 for Package
in Module
.Packages
:
2398 if Package
not in PackageList
:
2399 PackageList
.append(Package
)
2402 ## Summarize all platforms in the database
2403 def _GetPlatformList(self
):
2405 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2407 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2410 if Platform
!= None:
2411 PlatformList
.append(Platform
)
2414 ## Summarize all modules in the database
2415 def _GetModuleList(self
):
2417 for ModuleFile
in self
.TblFile
.GetFileList(MODEL_FILE_INF
):
2419 Module
= self
.BuildObject
[PathClass(ModuleFile
), 'COMMON']
2423 ModuleList
.append(Module
)
2426 PlatformList
= property(_GetPlatformList
)
2427 PackageList
= property(_GetPackageList
)
2428 ModuleList
= property(_GetModuleList
)
2432 # This acts like the main() function for the script, unless it is 'import'ed into another
2435 if __name__
== '__main__':