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
151 # Changing the default ARCH to another may affect all other information
152 # because all information in a platform may be ARCH-related. That's
153 # why we need to clear all internal used members, in order to cause all
154 # information to be re-retrieved.
156 # @param Value The value of ARCH
158 def _SetArch(self
, Value
):
159 if self
._Arch
== Value
:
164 ## Retrieve all information in [Defines] section
166 # (Retriving all [Defines] information in one-shot is just to save time.)
168 def _GetHeaderInfo(self
):
169 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
170 for Record
in RecordList
:
172 # items defined _PROPERTY_ don't need additional processing
174 self
[Name
] = Record
[1]
175 # some special items in [Defines] section need special treatment
176 elif Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
177 self
._OutputDirectory
= NormPath(Record
[1], self
._Macros
)
178 if ' ' in self
._OutputDirectory
:
179 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
180 File
=self
.MetaFile
, Line
=Record
[-1],
181 ExtraData
=self
._OutputDirectory
)
182 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
183 self
._FlashDefinition
= PathClass(NormPath(Record
[1], self
._Macros
), GlobalData
.gWorkspace
)
184 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
186 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
188 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
189 self
._SupArchList
= GetSplitValueList(Record
[1], TAB_VALUE_SPLIT
)
190 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
191 self
._BuildTargets
= GetSplitValueList(Record
[1])
192 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
193 if self
._SkuName
== None:
194 self
._SkuName
= Record
[1]
195 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
196 self
._LoadFixAddress
= Record
[1]
197 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
199 # try to convert GUID to a real UUID value to see whether the GUID is format
200 # for VPD_TOOL_GUID is correct.
205 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
206 self
._VpdToolGuid
= Record
[1]
207 # set _Header to non-None in order to avoid database re-querying
208 self
._Header
= 'DUMMY'
210 ## Retrieve platform name
211 def _GetPlatformName(self
):
212 if self
._PlatformName
== None:
213 if self
._Header
== None:
214 self
._GetHeaderInfo
()
215 if self
._PlatformName
== None:
216 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
217 return self
._PlatformName
219 ## Retrieve file guid
220 def _GetFileGuid(self
):
221 if self
._Guid
== None:
222 if self
._Header
== None:
223 self
._GetHeaderInfo
()
224 if self
._Guid
== None:
225 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No FILE_GUID", File
=self
.MetaFile
)
228 ## Retrieve platform version
229 def _GetVersion(self
):
230 if self
._Version
== None:
231 if self
._Header
== None:
232 self
._GetHeaderInfo
()
233 if self
._Version
== None:
237 ## Retrieve platform description file version
238 def _GetDscSpec(self
):
239 if self
._DscSpecification
== None:
240 if self
._Header
== None:
241 self
._GetHeaderInfo
()
242 if self
._DscSpecification
== None:
243 self
._DscSpecification
= ''
244 return self
._DscSpecification
246 ## Retrieve OUTPUT_DIRECTORY
247 def _GetOutpuDir(self
):
248 if self
._OutputDirectory
== None:
249 if self
._Header
== None:
250 self
._GetHeaderInfo
()
251 if self
._OutputDirectory
== None:
252 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
253 return self
._OutputDirectory
255 ## Retrieve SUPPORTED_ARCHITECTURES
256 def _GetSupArch(self
):
257 if self
._SupArchList
== None:
258 if self
._Header
== None:
259 self
._GetHeaderInfo
()
260 if self
._SupArchList
== None:
261 self
._SupArchList
= ARCH_LIST
262 return self
._SupArchList
264 ## Retrieve BUILD_TARGETS
265 def _GetBuildTarget(self
):
266 if self
._BuildTargets
== None:
267 if self
._Header
== None:
268 self
._GetHeaderInfo
()
269 if self
._BuildTargets
== None:
270 self
._BuildTargets
= ['DEBUG', 'RELEASE']
271 return self
._BuildTargets
273 ## Retrieve SKUID_IDENTIFIER
274 def _GetSkuName(self
):
275 if self
._SkuName
== None:
276 if self
._Header
== None:
277 self
._GetHeaderInfo
()
278 if self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
:
279 self
._SkuName
= 'DEFAULT'
282 ## Override SKUID_IDENTIFIER
283 def _SetSkuName(self
, Value
):
284 if Value
in self
.SkuIds
:
285 self
._SkuName
= Value
286 # Needs to re-retrieve the PCD information
289 def _GetFdfFile(self
):
290 if self
._FlashDefinition
== None:
291 if self
._Header
== None:
292 self
._GetHeaderInfo
()
293 if self
._FlashDefinition
== None:
294 self
._FlashDefinition
= ''
295 return self
._FlashDefinition
297 ## Retrieve FLASH_DEFINITION
298 def _GetBuildNumber(self
):
299 if self
._BuildNumber
== None:
300 if self
._Header
== None:
301 self
._GetHeaderInfo
()
302 if self
._BuildNumber
== None:
303 self
._BuildNumber
= ''
304 return self
._BuildNumber
306 ## Retrieve MAKEFILE_NAME
307 def _GetMakefileName(self
):
308 if self
._MakefileName
== None:
309 if self
._Header
== None:
310 self
._GetHeaderInfo
()
311 if self
._MakefileName
== None:
312 self
._MakefileName
= ''
313 return self
._MakefileName
315 ## Retrieve BsBaseAddress
316 def _GetBsBaseAddress(self
):
317 if self
._BsBaseAddress
== None:
318 if self
._Header
== None:
319 self
._GetHeaderInfo
()
320 if self
._BsBaseAddress
== None:
321 self
._BsBaseAddress
= ''
322 return self
._BsBaseAddress
324 ## Retrieve RtBaseAddress
325 def _GetRtBaseAddress(self
):
326 if self
._RtBaseAddress
== None:
327 if self
._Header
== None:
328 self
._GetHeaderInfo
()
329 if self
._RtBaseAddress
== None:
330 self
._RtBaseAddress
= ''
331 return self
._RtBaseAddress
333 ## Retrieve the top address for the load fix address
334 def _GetLoadFixAddress(self
):
335 if self
._LoadFixAddress
== None:
336 if self
._Header
== None:
337 self
._GetHeaderInfo
()
338 if self
._LoadFixAddress
== None:
339 self
._LoadFixAddress
= ''
340 return self
._LoadFixAddress
342 ## Retrieve the GUID string for VPD tool
343 def _GetVpdToolGuid(self
):
344 if self
._VpdToolGuid
== None:
345 if self
._Header
== None:
346 self
._GetHeaderInfo
()
347 if self
._VpdToolGuid
== None:
348 self
._VpdToolGuid
= ''
349 return self
._VpdToolGuid
351 ## Retrieve [SkuIds] section information
352 def _GetSkuIds(self
):
353 if self
._SkuIds
== None:
355 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
]
356 for Record
in RecordList
:
357 if Record
[0] in [None, '']:
358 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
359 File
=self
.MetaFile
, Line
=Record
[-1])
360 if Record
[1] in [None, '']:
361 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
362 File
=self
.MetaFile
, Line
=Record
[-1])
363 self
._SkuIds
[Record
[1]] = Record
[0]
364 if 'DEFAULT' not in self
._SkuIds
:
365 self
._SkuIds
['DEFAULT'] = 0
368 ## Retrieve [Components] section information
369 def _GetModules(self
):
370 if self
._Modules
!= None:
373 self
._Modules
= sdict()
374 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
375 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
376 Macros
.update(self
._Macros
)
377 for Record
in RecordList
:
378 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
382 # check the file validation
383 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
385 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
388 if ModuleFile
in self
._Modules
:
389 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
391 Module
= ModuleBuildClassObject()
392 Module
.MetaFile
= ModuleFile
394 # get module override path
395 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
397 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
399 # Check if the source override path exists
400 if not os
.path
.isdir(Module
.SourceOverridePath
):
401 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
403 #Add to GlobalData Variables
404 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
406 # get module private library instance
407 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
408 for Record
in RecordList
:
409 LibraryClass
= Record
[0]
410 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
413 # check the file validation
414 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
416 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
419 if LibraryClass
== '' or LibraryClass
== 'NULL':
420 self
._NullLibraryNumber
+= 1
421 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
422 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
423 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
424 if LibraryPath
not in self
.LibraryInstances
:
425 self
.LibraryInstances
.append(LibraryPath
)
427 # get module private PCD setting
428 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
429 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
430 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
431 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
432 TokenList
= GetSplitValueList(Setting
)
433 DefaultValue
= TokenList
[0]
434 if len(TokenList
) > 1:
435 MaxDatumSize
= TokenList
[1]
438 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
439 Pcd
= PcdClassObject(
451 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
453 # get module private build options
454 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
455 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
456 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
457 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
459 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
460 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
462 self
._Modules
[ModuleFile
] = Module
465 ## Retrieve all possible library instances used in this platform
466 def _GetLibraryInstances(self
):
467 if self
._LibraryInstances
== None:
468 self
._GetLibraryClasses
()
469 return self
._LibraryInstances
471 ## Retrieve [LibraryClasses] information
472 def _GetLibraryClasses(self
):
473 if self
._LibraryClasses
== None:
474 self
._LibraryInstances
= []
476 # tdict is a special dict kind of type, used for selecting correct
477 # library instance for given library class and module type
479 LibraryClassDict
= tdict(True, 3)
480 # track all library class names
481 LibraryClassSet
= set()
482 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
483 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
484 Macros
.update(self
._Macros
)
485 for Record
in RecordList
:
486 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
487 if LibraryClass
== '' or LibraryClass
== 'NULL':
488 self
._NullLibraryNumber
+= 1
489 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
490 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
491 LibraryClassSet
.add(LibraryClass
)
492 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
493 # check the file validation
494 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
496 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
499 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
500 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
501 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
502 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
503 if LibraryInstance
not in self
._LibraryInstances
:
504 self
._LibraryInstances
.append(LibraryInstance
)
506 # resolve the specific library instance for each class and each module type
507 self
._LibraryClasses
= tdict(True)
508 for LibraryClass
in LibraryClassSet
:
509 # try all possible module types
510 for ModuleType
in SUP_MODULE_LIST
:
511 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
512 if LibraryInstance
== None:
514 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
516 # for R8 style library instances, which are listed in different section
517 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
518 for Record
in RecordList
:
519 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
521 # check the file validation
522 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
524 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
526 if File
not in self
._LibraryInstances
:
527 self
._LibraryInstances
.append(File
)
529 # we need the module name as the library class name, so we have
530 # to parse it here. (self._Bdb[] will trigger a file parse if it
531 # hasn't been parsed)
533 Library
= self
._Bdb
[File
, self
._Arch
]
534 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
535 return self
._LibraryClasses
537 ## Retrieve all PCD settings in platform
539 if self
._Pcds
== None:
541 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
542 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
543 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
544 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
545 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
546 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
547 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
548 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
549 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
552 ## Retrieve [BuildOptions]
553 def _GetBuildOptions(self
):
554 if self
._BuildOptions
== None:
555 self
._BuildOptions
= {}
557 # Retrieve build option for EDKII style module
559 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, 'COMMON', EDKII_NAME
]
560 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
561 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
563 # Retrieve build option for EDK style module
565 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, 'COMMON', EDK_NAME
]
566 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
567 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
568 return self
._BuildOptions
570 ## Retrieve non-dynamic PCD settings
572 # @param Type PCD type
574 # @retval a dict object contains settings of given PCD type
576 def _GetPcd(self
, Type
):
579 # tdict is a special dict kind of type, used for selecting correct
580 # PCD settings for certain ARCH
582 PcdDict
= tdict(True, 3)
584 # Find out all possible PCD candidates for self._Arch
585 RecordList
= self
._RawData
[Type
, self
._Arch
]
586 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
587 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
588 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
589 # Remove redundant PCD candidates
590 for PcdCName
, TokenSpaceGuid
in PcdSet
:
591 ValueList
= ['', '', '']
592 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
595 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
596 ValueList
[0:len(TokenList
)] = TokenList
597 PcdValue
, DatumType
, MaxDatumSize
= ValueList
598 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
601 self
._PCD
_TYPE
_STRING
_[Type
],
612 ## Retrieve dynamic PCD settings
614 # @param Type PCD type
616 # @retval a dict object contains settings of given PCD type
618 def _GetDynamicPcd(self
, Type
):
621 # tdict is a special dict kind of type, used for selecting correct
622 # PCD settings for certain ARCH and SKU
624 PcdDict
= tdict(True, 4)
626 # Find out all possible PCD candidates for self._Arch
627 RecordList
= self
._RawData
[Type
, self
._Arch
]
628 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
629 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
630 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
631 # Remove redundant PCD candidates, per the ARCH and SKU
632 for PcdCName
, TokenSpaceGuid
in PcdSet
:
633 ValueList
= ['', '', '']
634 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
637 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
638 ValueList
[0:len(TokenList
)] = TokenList
639 PcdValue
, DatumType
, MaxDatumSize
= ValueList
641 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', '', PcdValue
)
642 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
645 self
._PCD
_TYPE
_STRING
_[Type
],
650 {self
.SkuName
: SkuInfo
},
656 ## Retrieve dynamic HII PCD settings
658 # @param Type PCD type
660 # @retval a dict object contains settings of given PCD type
662 def _GetDynamicHiiPcd(self
, Type
):
665 # tdict is a special dict kind of type, used for selecting correct
666 # PCD settings for certain ARCH and SKU
668 PcdDict
= tdict(True, 4)
670 RecordList
= self
._RawData
[Type
, self
._Arch
]
671 # Find out all possible PCD candidates for self._Arch
672 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
673 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
674 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
675 # Remove redundant PCD candidates, per the ARCH and SKU
676 for PcdCName
, TokenSpaceGuid
in PcdSet
:
677 ValueList
= ['', '', '', '']
678 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
681 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
682 ValueList
[0:len(TokenList
)] = TokenList
683 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= ValueList
684 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
685 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
688 self
._PCD
_TYPE
_STRING
_[Type
],
693 {self
.SkuName
: SkuInfo
},
699 ## Retrieve dynamic VPD PCD settings
701 # @param Type PCD type
703 # @retval a dict object contains settings of given PCD type
705 def _GetDynamicVpdPcd(self
, Type
):
708 # tdict is a special dict kind of type, used for selecting correct
709 # PCD settings for certain ARCH and SKU
711 PcdDict
= tdict(True, 4)
713 # Find out all possible PCD candidates for self._Arch
714 RecordList
= self
._RawData
[Type
, self
._Arch
]
715 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
716 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
717 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
718 # Remove redundant PCD candidates, per the ARCH and SKU
719 for PcdCName
, TokenSpaceGuid
in PcdSet
:
720 ValueList
= ['', '', '']
721 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
724 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
725 ValueList
[0:len(TokenList
)] = TokenList
727 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
728 # For the Integer & Boolean type, the optional data can only be InitialValue.
729 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
730 # until the DEC parser has been called.
732 VpdOffset
, MaxDatumSize
, InitialValue
= ValueList
734 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
735 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
738 self
._PCD
_TYPE
_STRING
_[Type
],
743 {self
.SkuName
: SkuInfo
},
749 ## Add external modules
751 # The external modules are mostly those listed in FDF file, which don't
754 # @param FilePath The path of module description file
756 def AddModule(self
, FilePath
):
757 FilePath
= NormPath(FilePath
)
758 if FilePath
not in self
.Modules
:
759 Module
= ModuleBuildClassObject()
760 Module
.MetaFile
= FilePath
761 self
.Modules
.append(Module
)
765 # The external PCDs are mostly those listed in FDF file to specify address
766 # or offset information.
768 # @param Name Name of the PCD
769 # @param Guid Token space guid of the PCD
770 # @param Value Value of the PCD
772 def AddPcd(self
, Name
, Guid
, Value
):
773 if (Name
, Guid
) not in self
.Pcds
:
774 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
775 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
777 Arch
= property(_GetArch
, _SetArch
)
778 Platform
= property(_GetPlatformName
)
779 PlatformName
= property(_GetPlatformName
)
780 Guid
= property(_GetFileGuid
)
781 Version
= property(_GetVersion
)
782 DscSpecification
= property(_GetDscSpec
)
783 OutputDirectory
= property(_GetOutpuDir
)
784 SupArchList
= property(_GetSupArch
)
785 BuildTargets
= property(_GetBuildTarget
)
786 SkuName
= property(_GetSkuName
, _SetSkuName
)
787 FlashDefinition
= property(_GetFdfFile
)
788 BuildNumber
= property(_GetBuildNumber
)
789 MakefileName
= property(_GetMakefileName
)
790 BsBaseAddress
= property(_GetBsBaseAddress
)
791 RtBaseAddress
= property(_GetRtBaseAddress
)
792 LoadFixAddress
= property(_GetLoadFixAddress
)
793 VpdToolGuid
= property(_GetVpdToolGuid
)
794 SkuIds
= property(_GetSkuIds
)
795 Modules
= property(_GetModules
)
796 LibraryInstances
= property(_GetLibraryInstances
)
797 LibraryClasses
= property(_GetLibraryClasses
)
798 Pcds
= property(_GetPcds
)
799 BuildOptions
= property(_GetBuildOptions
)
801 ## Platform build information from DEC file
803 # This class is used to retrieve information stored in database and convert them
804 # into PackageBuildClassObject form for easier use for AutoGen.
806 class DecBuildData(PackageBuildClassObject
):
807 # dict used to convert PCD type in database to string used by build tool
808 _PCD_TYPE_STRING_
= {
809 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
810 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
811 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
812 MODEL_PCD_DYNAMIC
: "Dynamic",
813 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
814 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
815 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
816 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
817 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
818 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
819 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
822 # dict used to convert part of [Defines] to members of DecBuildData directly
827 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
828 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
829 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
830 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
834 ## Constructor of DecBuildData
836 # Initialize object of DecBuildData
838 # @param FilePath The path of package description file
839 # @param RawData The raw data of DEC file
840 # @param BuildDataBase Database used to retrieve module information
841 # @param Arch The target architecture
842 # @param Platform (not used for DecBuildData)
843 # @param Macros Macros used for replacement in DSC file
845 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Platform
='DUMMY', Macros
={}):
847 self
._PackageDir
= File
.Dir
848 self
._RawData
= RawData
849 self
._Bdb
= BuildDataBase
851 self
._Macros
= Macros
855 def __setitem__(self
, key
, value
):
856 self
.__dict
__[self
._PROPERTY
_[key
]] = value
859 def __getitem__(self
, key
):
860 return self
.__dict
__[self
._PROPERTY
_[key
]]
863 def __contains__(self
, key
):
864 return key
in self
._PROPERTY
_
866 ## Set all internal used members of DecBuildData to None
869 self
._PackageName
= None
872 self
._PkgUniFile
= None
873 self
._Protocols
= None
876 self
._Includes
= None
877 self
._LibraryClasses
= None
886 # Changing the default ARCH to another may affect all other information
887 # because all information in a platform may be ARCH-related. That's
888 # why we need to clear all internal used members, in order to cause all
889 # information to be re-retrieved.
891 # @param Value The value of ARCH
893 def _SetArch(self
, Value
):
894 if self
._Arch
== Value
:
899 ## Retrieve all information in [Defines] section
901 # (Retriving all [Defines] information in one-shot is just to save time.)
903 def _GetHeaderInfo(self
):
904 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
]
905 for Record
in RecordList
:
908 self
[Name
] = Record
[1]
909 self
._Header
= 'DUMMY'
911 ## Retrieve package name
912 def _GetPackageName(self
):
913 if self
._PackageName
== None:
914 if self
._Header
== None:
915 self
._GetHeaderInfo
()
916 if self
._PackageName
== None:
917 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
918 return self
._PackageName
920 ## Retrieve file guid
921 def _GetFileGuid(self
):
922 if self
._Guid
== None:
923 if self
._Header
== None:
924 self
._GetHeaderInfo
()
925 if self
._Guid
== None:
926 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
929 ## Retrieve package version
930 def _GetVersion(self
):
931 if self
._Version
== None:
932 if self
._Header
== None:
933 self
._GetHeaderInfo
()
934 if self
._Version
== None:
938 ## Retrieve protocol definitions (name/value pairs)
939 def _GetProtocol(self
):
940 if self
._Protocols
== None:
942 # tdict is a special kind of dict, used for selecting correct
943 # protocol defition for given ARCH
945 ProtocolDict
= tdict(True)
947 # find out all protocol definitions for specific and 'common' arch
948 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
949 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
950 if Name
not in NameList
:
951 NameList
.append(Name
)
952 ProtocolDict
[Arch
, Name
] = Guid
953 # use sdict to keep the order
954 self
._Protocols
= sdict()
955 for Name
in NameList
:
957 # limit the ARCH to self._Arch, if no self._Arch found, tdict
958 # will automatically turn to 'common' ARCH for trying
960 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
961 return self
._Protocols
963 ## Retrieve PPI definitions (name/value pairs)
965 if self
._Ppis
== None:
967 # tdict is a special kind of dict, used for selecting correct
968 # PPI defition for given ARCH
970 PpiDict
= tdict(True)
972 # find out all PPI definitions for specific arch and 'common' arch
973 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
974 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
975 if Name
not in NameList
:
976 NameList
.append(Name
)
977 PpiDict
[Arch
, Name
] = Guid
978 # use sdict to keep the order
980 for Name
in NameList
:
982 # limit the ARCH to self._Arch, if no self._Arch found, tdict
983 # will automatically turn to 'common' ARCH for trying
985 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
988 ## Retrieve GUID definitions (name/value pairs)
990 if self
._Guids
== None:
992 # tdict is a special kind of dict, used for selecting correct
993 # GUID defition for given ARCH
995 GuidDict
= tdict(True)
997 # find out all protocol definitions for specific and 'common' arch
998 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
999 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1000 if Name
not in NameList
:
1001 NameList
.append(Name
)
1002 GuidDict
[Arch
, Name
] = Guid
1003 # use sdict to keep the order
1004 self
._Guids
= sdict()
1005 for Name
in NameList
:
1007 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1008 # will automatically turn to 'common' ARCH for trying
1010 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1013 ## Retrieve public include paths declared in this package
1014 def _GetInclude(self
):
1015 if self
._Includes
== None:
1017 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1018 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1019 Macros
.update(self
._Macros
)
1020 for Record
in RecordList
:
1021 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1024 ErrorCode
, ErrorInfo
= File
.Validate()
1026 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1028 # avoid duplicate include path
1029 if File
not in self
._Includes
:
1030 self
._Includes
.append(File
)
1031 return self
._Includes
1033 ## Retrieve library class declarations (not used in build at present)
1034 def _GetLibraryClass(self
):
1035 if self
._LibraryClasses
== None:
1037 # tdict is a special kind of dict, used for selecting correct
1038 # library class declaration for given ARCH
1040 LibraryClassDict
= tdict(True)
1041 LibraryClassSet
= set()
1042 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1043 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1044 Macros
.update(self
._Macros
)
1045 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1046 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1047 # check the file validation
1048 ErrorCode
, ErrorInfo
= File
.Validate()
1050 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1051 LibraryClassSet
.add(LibraryClass
)
1052 LibraryClassDict
[Arch
, LibraryClass
] = File
1053 self
._LibraryClasses
= sdict()
1054 for LibraryClass
in LibraryClassSet
:
1055 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1056 return self
._LibraryClasses
1058 ## Retrieve PCD declarations
1060 if self
._Pcds
== None:
1062 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1063 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1064 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1065 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1066 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1069 ## Retrieve PCD declarations for given type
1070 def _GetPcd(self
, Type
):
1073 # tdict is a special kind of dict, used for selecting correct
1074 # PCD declaration for given ARCH
1076 PcdDict
= tdict(True, 3)
1077 # for summarizing PCD
1079 # find out all PCDs of the 'type'
1080 RecordList
= self
._RawData
[Type
, self
._Arch
]
1081 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1082 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1083 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1085 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1086 ValueList
= ['', '', '']
1088 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1089 # will automatically turn to 'common' ARCH and try again
1091 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1094 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
1095 ValueList
[0:len(TokenList
)] = TokenList
1096 DefaultValue
, DatumType
, TokenNumber
= ValueList
1097 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1100 self
._PCD
_TYPE
_STRING
_[Type
],
1112 Arch
= property(_GetArch
, _SetArch
)
1113 PackageName
= property(_GetPackageName
)
1114 Guid
= property(_GetFileGuid
)
1115 Version
= property(_GetVersion
)
1117 Protocols
= property(_GetProtocol
)
1118 Ppis
= property(_GetPpi
)
1119 Guids
= property(_GetGuid
)
1120 Includes
= property(_GetInclude
)
1121 LibraryClasses
= property(_GetLibraryClass
)
1122 Pcds
= property(_GetPcds
)
1124 ## Module build information from INF file
1126 # This class is used to retrieve information stored in database and convert them
1127 # into ModuleBuildClassObject form for easier use for AutoGen.
1129 class InfBuildData(ModuleBuildClassObject
):
1130 # dict used to convert PCD type in database to string used by build tool
1131 _PCD_TYPE_STRING_
= {
1132 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1133 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1134 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1135 MODEL_PCD_DYNAMIC
: "Dynamic",
1136 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1137 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1138 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1139 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1140 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1141 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1142 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1145 # dict used to convert part of [Defines] to members of InfBuildData directly
1150 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1151 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1152 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1156 TAB_INF_DEFINES_INF_VERSION
: "_AutoGenVersion",
1157 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1158 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1159 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1160 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1161 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1162 TAB_INF_DEFINES_VERSION
: "_Version",
1163 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1164 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1166 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1169 # dict used to convert Component type to Module type
1172 "SECURITY_CORE" : "SEC",
1173 "PEI_CORE" : "PEI_CORE",
1174 "COMBINED_PEIM_DRIVER" : "PEIM",
1175 "PIC_PEIM" : "PEIM",
1176 "RELOCATABLE_PEIM" : "PEIM",
1177 "PE32_PEIM" : "PEIM",
1178 "BS_DRIVER" : "DXE_DRIVER",
1179 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1180 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1181 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1182 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1183 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1184 # "BS_DRIVER" : "UEFI_DRIVER",
1185 "APPLICATION" : "UEFI_APPLICATION",
1189 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1190 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1191 # dict used to convert old tool name used in [nmake] section to new ones
1199 ## Constructor of DscBuildData
1201 # Initialize object of DscBuildData
1203 # @param FilePath The path of platform description file
1204 # @param RawData The raw data of DSC file
1205 # @param BuildDataBase Database used to retrieve module/package information
1206 # @param Arch The target architecture
1207 # @param Platform The name of platform employing this module
1208 # @param Macros Macros used for replacement in DSC file
1210 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Platform
='COMMON', Macros
={}):
1211 self
.MetaFile
= FilePath
1212 self
._ModuleDir
= FilePath
.Dir
1213 self
._RawData
= RawData
1214 self
._Bdb
= BuildDatabase
1216 self
._Platform
= 'COMMON'
1217 self
._Macros
= Macros
1218 self
._SourceOverridePath
= None
1219 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1220 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1224 def __setitem__(self
, key
, value
):
1225 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1228 def __getitem__(self
, key
):
1229 return self
.__dict
__[self
._PROPERTY
_[key
]]
1231 ## "in" test support
1232 def __contains__(self
, key
):
1233 return key
in self
._PROPERTY
_
1235 ## Set all internal used members of InfBuildData to None
1237 self
._Header
_ = None
1238 self
._AutoGenVersion
= None
1239 self
._BaseName
= None
1240 self
._ModuleType
= None
1241 self
._ComponentType
= None
1242 self
._BuildType
= None
1244 self
._Version
= None
1245 self
._PcdIsDriver
= None
1246 self
._BinaryModule
= None
1248 self
._MakefileName
= None
1249 self
._CustomMakefile
= None
1250 self
._Specification
= None
1251 self
._LibraryClass
= None
1252 self
._ModuleEntryPointList
= None
1253 self
._ModuleUnloadImageList
= None
1254 self
._ConstructorList
= None
1255 self
._DestructorList
= None
1257 self
._Binaries
= None
1258 self
._Sources
= None
1259 self
._LibraryClasses
= None
1260 self
._Libraries
= None
1261 self
._Protocols
= None
1264 self
._Includes
= None
1265 self
._Packages
= None
1267 self
._BuildOptions
= None
1269 self
._DepexExpression
= None
1270 #self._SourceOverridePath = None
1278 # Changing the default ARCH to another may affect all other information
1279 # because all information in a platform may be ARCH-related. That's
1280 # why we need to clear all internal used members, in order to cause all
1281 # information to be re-retrieved.
1283 # @param Value The value of ARCH
1285 def _SetArch(self
, Value
):
1286 if self
._Arch
== Value
:
1291 ## Return the name of platform employing this module
1292 def _GetPlatform(self
):
1293 return self
._Platform
1295 ## Change the name of platform employing this module
1297 # Changing the default name of platform to another may affect some information
1298 # because they may be PLATFORM-related. That's why we need to clear all internal
1299 # used members, in order to cause all information to be re-retrieved.
1301 def _SetPlatform(self
, Value
):
1302 if self
._Platform
== Value
:
1304 self
._Platform
= Value
1307 ## Retrieve all information in [Defines] section
1309 # (Retriving all [Defines] information in one-shot is just to save time.)
1311 def _GetHeaderInfo(self
):
1312 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1313 for Record
in RecordList
:
1314 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1316 # items defined _PROPERTY_ don't need additional processing
1318 self
[Name
] = Record
[1]
1319 # some special items in [Defines] section need special treatment
1320 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1321 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1322 Name
= 'UEFI_SPECIFICATION_VERSION'
1323 if self
._Specification
== None:
1324 self
._Specification
= sdict()
1325 self
._Specification
[Name
] = GetHexVerValue(Record
[1])
1326 if self
._Specification
[Name
] == None:
1327 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1328 "'%s' format is not supported for %s" % (Record
[1], Name
),
1329 File
=self
.MetaFile
, Line
=Record
[-1])
1330 elif Name
== 'LIBRARY_CLASS':
1331 if self
._LibraryClass
== None:
1332 self
._LibraryClass
= []
1333 ValueList
= GetSplitValueList(Record
[1])
1334 LibraryClass
= ValueList
[0]
1335 if len(ValueList
) > 1:
1336 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1338 SupModuleList
= SUP_MODULE_LIST
1339 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1340 elif Name
== 'ENTRY_POINT':
1341 if self
._ModuleEntryPointList
== None:
1342 self
._ModuleEntryPointList
= []
1343 self
._ModuleEntryPointList
.append(Record
[1])
1344 elif Name
== 'UNLOAD_IMAGE':
1345 if self
._ModuleUnloadImageList
== None:
1346 self
._ModuleUnloadImageList
= []
1349 self
._ModuleUnloadImageList
.append(Record
[1])
1350 elif Name
== 'CONSTRUCTOR':
1351 if self
._ConstructorList
== None:
1352 self
._ConstructorList
= []
1355 self
._ConstructorList
.append(Record
[1])
1356 elif Name
== 'DESTRUCTOR':
1357 if self
._DestructorList
== None:
1358 self
._DestructorList
= []
1361 self
._DestructorList
.append(Record
[1])
1362 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1363 TokenList
= GetSplitValueList(Record
[1])
1364 if self
._CustomMakefile
== None:
1365 self
._CustomMakefile
= {}
1366 if len(TokenList
) < 2:
1367 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1368 self
._CustomMakefile
['GCC'] = TokenList
[0]
1370 if TokenList
[0] not in ['MSFT', 'GCC']:
1371 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1372 "No supported family [%s]" % TokenList
[0],
1373 File
=self
.MetaFile
, Line
=Record
[-1])
1374 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1376 if self
._Defs
== None:
1377 self
._Defs
= sdict()
1378 self
._Defs
[Name
] = Record
[1]
1381 # Retrieve information in sections specific to R8.x modules
1383 if self
._AutoGenVersion
>= 0x00010005: # _AutoGenVersion may be None, which is less than anything
1384 if not self
._ModuleType
:
1385 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1386 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1387 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (self
._Specification
['PI_SPECIFICATION_VERSION'] < 0x0001000A):
1388 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1389 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
)
1390 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1391 and 'PCI_CLASS_CODE' in self
._Defs
:
1392 self
._BuildType
= 'UEFI_OPTIONROM'
1393 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1394 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1395 self
._BuildType
= 'UEFI_HII'
1397 self
._BuildType
= self
._ModuleType
.upper()
1399 self
._BuildType
= self
._ComponentType
.upper()
1400 if not self
._ComponentType
:
1401 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1402 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1403 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1404 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1405 if self
._ComponentType
== 'LIBRARY':
1406 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1407 # make use some [nmake] section macros
1408 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1409 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1410 Value
= Value
.replace('$(PROCESSOR)', self
._Arch
)
1411 Name
= Name
.replace('$(PROCESSOR)', self
._Arch
)
1412 Name
, Value
= ReplaceMacros((Name
, Value
), GlobalData
.gEdkGlobal
, True)
1413 if Name
== "IMAGE_ENTRY_POINT":
1414 if self
._ModuleEntryPointList
== None:
1415 self
._ModuleEntryPointList
= []
1416 self
._ModuleEntryPointList
.append(Value
)
1417 elif Name
== "DPX_SOURCE":
1418 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1419 Macros
.update(self
._Macros
)
1420 File
= PathClass(NormPath(Value
, Macros
), self
._ModuleDir
, Arch
=self
._Arch
)
1421 # check the file validation
1422 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1424 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1425 File
=self
.MetaFile
, Line
=LineNo
)
1426 if self
.Sources
== None:
1428 self
._Sources
.append(File
)
1430 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1431 if len(ToolList
) == 0 or len(ToolList
) != 1:
1433 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1434 # File=self.MetaFile, Line=LineNo)
1436 if self
._BuildOptions
== None:
1437 self
._BuildOptions
= sdict()
1439 if ToolList
[0] in self
._TOOL
_CODE
_:
1440 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1443 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1444 ToolChainFamily
= 'MSFT' # R8.x only support MSFT tool chain
1445 #ignore not replaced macros in value
1446 ValueList
= GetSplitValueList(' ' + Value
, '/D')
1447 Dummy
= ValueList
[0]
1448 for Index
in range(1, len(ValueList
)):
1449 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1451 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1452 Value
= Dummy
.strip()
1453 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1454 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1456 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1457 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1458 # set _Header to non-None in order to avoid database re-querying
1459 self
._Header
_ = 'DUMMY'
1461 ## Retrieve file version
1462 def _GetInfVersion(self
):
1463 if self
._AutoGenVersion
== None:
1464 if self
._Header
_ == None:
1465 self
._GetHeaderInfo
()
1466 if self
._AutoGenVersion
== None:
1467 self
._AutoGenVersion
= 0x00010000
1468 return self
._AutoGenVersion
1470 ## Retrieve BASE_NAME
1471 def _GetBaseName(self
):
1472 if self
._BaseName
== None:
1473 if self
._Header
_ == None:
1474 self
._GetHeaderInfo
()
1475 if self
._BaseName
== None:
1476 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1477 return self
._BaseName
1479 ## Retrieve MODULE_TYPE
1480 def _GetModuleType(self
):
1481 if self
._ModuleType
== None:
1482 if self
._Header
_ == None:
1483 self
._GetHeaderInfo
()
1484 if self
._ModuleType
== None:
1485 self
._ModuleType
= 'BASE'
1486 if self
._ModuleType
not in SUP_MODULE_LIST
:
1487 self
._ModuleType
= "USER_DEFINED"
1488 return self
._ModuleType
1490 ## Retrieve COMPONENT_TYPE
1491 def _GetComponentType(self
):
1492 if self
._ComponentType
== None:
1493 if self
._Header
_ == None:
1494 self
._GetHeaderInfo
()
1495 if self
._ComponentType
== None:
1496 self
._ComponentType
= 'USER_DEFINED'
1497 return self
._ComponentType
1499 ## Retrieve "BUILD_TYPE"
1500 def _GetBuildType(self
):
1501 if self
._BuildType
== None:
1502 if self
._Header
_ == None:
1503 self
._GetHeaderInfo
()
1504 if not self
._BuildType
:
1505 self
._BuildType
= "BASE"
1506 return self
._BuildType
1508 ## Retrieve file guid
1509 def _GetFileGuid(self
):
1510 if self
._Guid
== None:
1511 if self
._Header
_ == None:
1512 self
._GetHeaderInfo
()
1513 if self
._Guid
== None:
1514 self
._Guid
= '00000000-0000-0000-000000000000'
1517 ## Retrieve module version
1518 def _GetVersion(self
):
1519 if self
._Version
== None:
1520 if self
._Header
_ == None:
1521 self
._GetHeaderInfo
()
1522 if self
._Version
== None:
1523 self
._Version
= '0.0'
1524 return self
._Version
1526 ## Retrieve PCD_IS_DRIVER
1527 def _GetPcdIsDriver(self
):
1528 if self
._PcdIsDriver
== None:
1529 if self
._Header
_ == None:
1530 self
._GetHeaderInfo
()
1531 if self
._PcdIsDriver
== None:
1532 self
._PcdIsDriver
= ''
1533 return self
._PcdIsDriver
1536 def _GetShadow(self
):
1537 if self
._Shadow
== None:
1538 if self
._Header
_ == None:
1539 self
._GetHeaderInfo
()
1540 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1543 self
._Shadow
= False
1546 ## Retrieve CUSTOM_MAKEFILE
1547 def _GetMakefile(self
):
1548 if self
._CustomMakefile
== None:
1549 if self
._Header
_ == None:
1550 self
._GetHeaderInfo
()
1551 if self
._CustomMakefile
== None:
1552 self
._CustomMakefile
= {}
1553 return self
._CustomMakefile
1555 ## Retrieve EFI_SPECIFICATION_VERSION
1557 if self
._Specification
== None:
1558 if self
._Header
_ == None:
1559 self
._GetHeaderInfo
()
1560 if self
._Specification
== None:
1561 self
._Specification
= {}
1562 return self
._Specification
1564 ## Retrieve LIBRARY_CLASS
1565 def _GetLibraryClass(self
):
1566 if self
._LibraryClass
== None:
1567 if self
._Header
_ == None:
1568 self
._GetHeaderInfo
()
1569 if self
._LibraryClass
== None:
1570 self
._LibraryClass
= []
1571 return self
._LibraryClass
1573 ## Retrieve ENTRY_POINT
1574 def _GetEntryPoint(self
):
1575 if self
._ModuleEntryPointList
== None:
1576 if self
._Header
_ == None:
1577 self
._GetHeaderInfo
()
1578 if self
._ModuleEntryPointList
== None:
1579 self
._ModuleEntryPointList
= []
1580 return self
._ModuleEntryPointList
1582 ## Retrieve UNLOAD_IMAGE
1583 def _GetUnloadImage(self
):
1584 if self
._ModuleUnloadImageList
== None:
1585 if self
._Header
_ == None:
1586 self
._GetHeaderInfo
()
1587 if self
._ModuleUnloadImageList
== None:
1588 self
._ModuleUnloadImageList
= []
1589 return self
._ModuleUnloadImageList
1591 ## Retrieve CONSTRUCTOR
1592 def _GetConstructor(self
):
1593 if self
._ConstructorList
== None:
1594 if self
._Header
_ == None:
1595 self
._GetHeaderInfo
()
1596 if self
._ConstructorList
== None:
1597 self
._ConstructorList
= []
1598 return self
._ConstructorList
1600 ## Retrieve DESTRUCTOR
1601 def _GetDestructor(self
):
1602 if self
._DestructorList
== None:
1603 if self
._Header
_ == None:
1604 self
._GetHeaderInfo
()
1605 if self
._DestructorList
== None:
1606 self
._DestructorList
= []
1607 return self
._DestructorList
1609 ## Retrieve definies other than above ones
1610 def _GetDefines(self
):
1611 if self
._Defs
== None:
1612 if self
._Header
_ == None:
1613 self
._GetHeaderInfo
()
1614 if self
._Defs
== None:
1615 self
._Defs
= sdict()
1618 ## Retrieve binary files
1619 def _GetBinaryFiles(self
):
1620 if self
._Binaries
== None:
1622 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
1623 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
, 'PROCESSOR':self
._Arch
}
1624 Macros
.update(self
._Macros
)
1625 for Record
in RecordList
:
1626 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1627 FileType
= Record
[0]
1632 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
1634 Target
= TokenList
[0]
1635 if len(TokenList
) > 1:
1636 FeatureFlag
= Record
[1:]
1638 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
1639 # check the file validation
1640 ErrorCode
, ErrorInfo
= File
.Validate()
1642 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1643 self
._Binaries
.append(File
)
1644 return self
._Binaries
1646 ## Retrieve source files
1647 def _GetSourceFiles(self
):
1648 if self
._Sources
== None:
1650 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
1651 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
, 'PROCESSOR':self
._Arch
}
1652 Macros
.update(self
._Macros
)
1653 for Record
in RecordList
:
1654 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1656 ToolChainFamily
= Record
[1]
1658 ToolCode
= Record
[3]
1659 FeatureFlag
= Record
[4]
1660 if self
._AutoGenVersion
< 0x00010005:
1661 # old module source files (R8)
1662 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
1663 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1664 # check the file validation
1665 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
1667 if File
.Ext
.lower() == '.h':
1668 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
1669 File
=self
.MetaFile
, Line
=LineNo
)
1672 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
1674 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
1675 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1676 # check the file validation
1677 ErrorCode
, ErrorInfo
= File
.Validate()
1679 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1681 self
._Sources
.append(File
)
1682 return self
._Sources
1684 ## Retrieve library classes employed by this module
1685 def _GetLibraryClassUses(self
):
1686 if self
._LibraryClasses
== None:
1687 self
._LibraryClasses
= sdict()
1688 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
1689 for Record
in RecordList
:
1690 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1692 Instance
= Record
[1]
1693 if Instance
!= None and Instance
!= '':
1694 Instance
= NormPath(Instance
, self
._Macros
)
1695 self
._LibraryClasses
[Lib
] = Instance
1696 return self
._LibraryClasses
1698 ## Retrieve library names (for R8.x style of modules)
1699 def _GetLibraryNames(self
):
1700 if self
._Libraries
== None:
1701 self
._Libraries
= []
1702 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
1703 for Record
in RecordList
:
1704 # in case of name with '.lib' extension, which is unusual in R8.x inf
1705 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1706 LibraryName
= os
.path
.splitext(Record
[0])[0]
1707 if LibraryName
not in self
._Libraries
:
1708 self
._Libraries
.append(LibraryName
)
1709 return self
._Libraries
1711 ## Retrieve protocols consumed/produced by this module
1712 def _GetProtocols(self
):
1713 if self
._Protocols
== None:
1714 self
._Protocols
= sdict()
1715 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
1716 for Record
in RecordList
:
1718 Value
= ProtocolValue(CName
, self
.Packages
)
1720 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1721 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1722 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
1723 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1724 self
._Protocols
[CName
] = Value
1725 return self
._Protocols
1727 ## Retrieve PPIs consumed/produced by this module
1729 if self
._Ppis
== None:
1730 self
._Ppis
= sdict()
1731 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
1732 for Record
in RecordList
:
1734 Value
= PpiValue(CName
, self
.Packages
)
1736 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1737 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1738 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
1739 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1740 self
._Ppis
[CName
] = Value
1743 ## Retrieve GUIDs consumed/produced by this module
1744 def _GetGuids(self
):
1745 if self
._Guids
== None:
1746 self
._Guids
= sdict()
1747 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
1748 for Record
in RecordList
:
1750 Value
= GuidValue(CName
, self
.Packages
)
1752 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1753 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1754 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
1755 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1756 self
._Guids
[CName
] = Value
1759 ## Retrieve include paths necessary for this module (for R8.x style of modules)
1760 def _GetIncludes(self
):
1761 if self
._Includes
== None:
1763 if self
._SourceOverridePath
:
1764 self
._Includes
.append(self
._SourceOverridePath
)
1765 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
1766 # [includes] section must be used only in old (R8.x) inf file
1767 if self
.AutoGenVersion
>= 0x00010005 and len(RecordList
) > 0:
1768 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, "No [include] section allowed",
1769 File
=self
.MetaFile
, Line
=RecordList
[0][-1]-1)
1770 for Record
in RecordList
:
1771 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1772 Record
[0] = Record
[0].replace('$(PROCESSOR)', self
._Arch
)
1773 Record
[0] = ReplaceMacro(Record
[0], {'EFI_SOURCE' : GlobalData
.gEfiSource
}, False)
1774 if Record
[0].find('EDK_SOURCE') > -1:
1775 File
= NormPath(ReplaceMacro(Record
[0], {'EDK_SOURCE' : GlobalData
.gEcpSource
}, False), self
._Macros
)
1777 File
= os
.path
.join(self
._ModuleDir
, File
)
1779 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1780 File
= RealPath(os
.path
.normpath(File
))
1782 self
._Includes
.append(File
)
1784 #TRICK: let compiler to choose correct header file
1785 File
= NormPath(ReplaceMacro(Record
[0], {'EDK_SOURCE' : GlobalData
.gEdkSource
}, False), self
._Macros
)
1787 File
= os
.path
.join(self
._ModuleDir
, File
)
1789 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1790 File
= RealPath(os
.path
.normpath(File
))
1792 self
._Includes
.append(File
)
1794 File
= NormPath(Record
[0], self
._Macros
)
1796 File
= os
.path
.join(self
._ModuleDir
, File
)
1798 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1799 File
= RealPath(os
.path
.normpath(File
))
1801 self
._Includes
.append(File
)
1802 return self
._Includes
1804 ## Retrieve packages this module depends on
1805 def _GetPackages(self
):
1806 if self
._Packages
== None:
1808 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
1809 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1810 Macros
.update(self
._Macros
)
1811 for Record
in RecordList
:
1812 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
1814 # check the file validation
1815 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
1817 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1818 # parse this package now. we need it to get protocol/ppi/guid value
1819 Package
= self
._Bdb
[File
, self
._Arch
]
1820 self
._Packages
.append(Package
)
1821 return self
._Packages
1823 ## Retrieve PCDs used in this module
1825 if self
._Pcds
== None:
1827 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1828 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1829 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1830 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1831 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1834 ## Retrieve build options specific to this module
1835 def _GetBuildOptions(self
):
1836 if self
._BuildOptions
== None:
1837 self
._BuildOptions
= sdict()
1838 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
1839 for Record
in RecordList
:
1840 ToolChainFamily
= Record
[0]
1841 ToolChain
= Record
[1]
1843 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1844 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
1846 # concatenate the option string if they're for the same tool
1847 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1848 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
1849 return self
._BuildOptions
1851 ## Retrieve depedency expression
1852 def _GetDepex(self
):
1853 if self
._Depex
== None:
1854 self
._Depex
= tdict(False, 2)
1855 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1857 # PEIM and DXE drivers must have a valid [Depex] section
1858 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
1859 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
1860 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
1861 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
1862 % self
.ModuleType
, File
=self
.MetaFile
)
1865 for Record
in RecordList
:
1866 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1868 ModuleType
= Record
[4]
1869 TokenList
= Record
[0].split()
1870 if (Arch
, ModuleType
) not in Depex
:
1871 Depex
[Arch
, ModuleType
] = []
1872 DepexList
= Depex
[Arch
, ModuleType
]
1873 for Token
in TokenList
:
1874 if Token
in DEPEX_SUPPORTED_OPCODE
:
1875 DepexList
.append(Token
)
1876 elif Token
.endswith(".inf"): # module file name
1877 ModuleFile
= os
.path
.normpath(Token
)
1878 Module
= self
.BuildDatabase
[ModuleFile
]
1880 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
1881 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
1882 DepexList
.append(Module
.Guid
)
1884 # get the GUID value now
1885 Value
= ProtocolValue(Token
, self
.Packages
)
1887 Value
= PpiValue(Token
, self
.Packages
)
1889 Value
= GuidValue(Token
, self
.Packages
)
1891 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1892 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1893 "Value of [%s] is not found in" % Token
,
1894 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1895 DepexList
.append(Value
)
1896 for Arch
, ModuleType
in Depex
:
1897 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
1900 ## Retrieve depedency expression
1901 def _GetDepexExpression(self
):
1902 if self
._DepexExpression
== None:
1903 self
._DepexExpression
= tdict(False, 2)
1904 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1905 DepexExpression
= {}
1906 for Record
in RecordList
:
1907 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1909 ModuleType
= Record
[4]
1910 TokenList
= Record
[0].split()
1911 if (Arch
, ModuleType
) not in DepexExpression
:
1912 DepexExpression
[Arch
, ModuleType
] = ''
1913 for Token
in TokenList
:
1914 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
1915 for Arch
, ModuleType
in DepexExpression
:
1916 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
1917 return self
._DepexExpression
1919 ## Retrieve PCD for given type
1920 def _GetPcd(self
, Type
):
1922 PcdDict
= tdict(True, 4)
1924 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
1925 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Dummy1
, LineNo
in RecordList
:
1926 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
1927 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1928 # get the guid value
1929 if TokenSpaceGuid
not in self
.Guids
:
1930 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
1932 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1933 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1934 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
1935 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
1936 self
.Guids
[TokenSpaceGuid
] = Value
1938 # resolve PCD type, value, datum info, etc. by getting its definition from package
1939 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1940 ValueList
= ['', '']
1941 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
1944 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
1945 ValueList
[0:len(TokenList
)] = TokenList
1946 DefaultValue
= ValueList
[0]
1947 Pcd
= PcdClassObject(
1957 self
.Guids
[TokenSpaceGuid
]
1960 # get necessary info from package declaring this PCD
1961 for Package
in self
.Packages
:
1963 # 'dynamic' in INF means its type is determined by platform;
1964 # if platform doesn't give its type, use 'lowest' one in the
1965 # following order, if any
1967 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
1969 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
1970 if Type
== MODEL_PCD_DYNAMIC
:
1972 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
1973 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
1979 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
1980 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
1982 Pcd
.TokenValue
= PcdInPackage
.TokenValue
1983 Pcd
.DatumType
= PcdInPackage
.DatumType
1984 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
1985 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
1986 if Pcd
.DefaultValue
in [None, '']:
1987 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
1993 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
1994 File
=self
.MetaFile
, Line
=LineNo
,
1995 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
1997 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2000 Arch
= property(_GetArch
, _SetArch
)
2001 Platform
= property(_GetPlatform
, _SetPlatform
)
2003 AutoGenVersion
= property(_GetInfVersion
)
2004 BaseName
= property(_GetBaseName
)
2005 ModuleType
= property(_GetModuleType
)
2006 ComponentType
= property(_GetComponentType
)
2007 BuildType
= property(_GetBuildType
)
2008 Guid
= property(_GetFileGuid
)
2009 Version
= property(_GetVersion
)
2010 PcdIsDriver
= property(_GetPcdIsDriver
)
2011 Shadow
= property(_GetShadow
)
2012 CustomMakefile
= property(_GetMakefile
)
2013 Specification
= property(_GetSpec
)
2014 LibraryClass
= property(_GetLibraryClass
)
2015 ModuleEntryPointList
= property(_GetEntryPoint
)
2016 ModuleUnloadImageList
= property(_GetUnloadImage
)
2017 ConstructorList
= property(_GetConstructor
)
2018 DestructorList
= property(_GetDestructor
)
2019 Defines
= property(_GetDefines
)
2021 Binaries
= property(_GetBinaryFiles
)
2022 Sources
= property(_GetSourceFiles
)
2023 LibraryClasses
= property(_GetLibraryClassUses
)
2024 Libraries
= property(_GetLibraryNames
)
2025 Protocols
= property(_GetProtocols
)
2026 Ppis
= property(_GetPpis
)
2027 Guids
= property(_GetGuids
)
2028 Includes
= property(_GetIncludes
)
2029 Packages
= property(_GetPackages
)
2030 Pcds
= property(_GetPcds
)
2031 BuildOptions
= property(_GetBuildOptions
)
2032 Depex
= property(_GetDepex
)
2033 DepexExpression
= property(_GetDepexExpression
)
2037 # This class defined the build database for all modules, packages and platform.
2038 # It will call corresponding parser for the given file if it cannot find it in
2041 # @param DbPath Path of database file
2042 # @param GlobalMacros Global macros used for replacement during file parsing
2043 # @prarm RenewDb=False Create new database file if it's already there
2045 class WorkspaceDatabase(object):
2048 MODEL_FILE_INF
: InfParser
,
2049 MODEL_FILE_DEC
: DecParser
,
2050 MODEL_FILE_DSC
: DscParser
,
2051 MODEL_FILE_FDF
: None, #FdfParser,
2052 MODEL_FILE_CIF
: None
2057 MODEL_FILE_INF
: ModuleTable
,
2058 MODEL_FILE_DEC
: PackageTable
,
2059 MODEL_FILE_DSC
: PlatformTable
,
2062 # default database file path
2063 _DB_PATH_
= "Conf/.cache/build.db"
2066 # internal class used for call corresponding file parser and caching the result
2067 # to avoid unnecessary re-parsing
2069 class BuildObjectFactory(object):
2071 ".inf" : MODEL_FILE_INF
,
2072 ".dec" : MODEL_FILE_DEC
,
2073 ".dsc" : MODEL_FILE_DSC
,
2074 ".fdf" : MODEL_FILE_FDF
,
2077 # convert to xxxBuildData object
2079 MODEL_FILE_INF
: InfBuildData
,
2080 MODEL_FILE_DEC
: DecBuildData
,
2081 MODEL_FILE_DSC
: DscBuildData
,
2082 MODEL_FILE_FDF
: None #FlashDefTable,
2085 _CACHE_
= {} # (FilePath, Arch) : <object>
2088 def __init__(self
, WorkspaceDb
):
2089 self
.WorkspaceDb
= WorkspaceDb
2091 # key = (FilePath, Arch='COMMON')
2092 def __contains__(self
, Key
):
2097 return (FilePath
, Arch
) in self
._CACHE
_
2099 # key = (FilePath, Arch='COMMON')
2100 def __getitem__(self
, Key
):
2109 # if it's generated before, just return the cached one
2110 Key
= (FilePath
, Arch
)
2111 if Key
in self
._CACHE
_:
2112 return self
._CACHE
_[Key
]
2115 Ext
= FilePath
.Ext
.lower()
2116 if Ext
not in self
._FILE
_TYPE
_:
2118 FileType
= self
._FILE
_TYPE
_[Ext
]
2119 if FileType
not in self
._GENERATOR
_:
2122 # get table for current file
2123 MetaFile
= self
.WorkspaceDb
[FilePath
, FileType
, self
.WorkspaceDb
._GlobalMacros
]
2124 BuildObject
= self
._GENERATOR
_[FileType
](
2130 self
.WorkspaceDb
._GlobalMacros
,
2132 self
._CACHE
_[Key
] = BuildObject
2135 # placeholder for file format conversion
2136 class TransformObjectFactory
:
2137 def __init__(self
, WorkspaceDb
):
2138 self
.WorkspaceDb
= WorkspaceDb
2140 # key = FilePath, Arch
2141 def __getitem__(self
, Key
):
2144 ## Constructor of WorkspaceDatabase
2146 # @param DbPath Path of database file
2147 # @param GlobalMacros Global macros used for replacement during file parsing
2148 # @prarm RenewDb=False Create new database file if it's already there
2150 def __init__(self
, DbPath
, GlobalMacros
={}, RenewDb
=False):
2151 self
._GlobalMacros
= GlobalMacros
2153 if DbPath
== None or DbPath
== '':
2154 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2156 # don't create necessary path for db in memory
2157 if DbPath
!= ':memory:':
2158 DbDir
= os
.path
.split(DbPath
)[0]
2159 if not os
.path
.exists(DbDir
):
2162 # remove db file in case inconsistency between db and file in file system
2163 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2166 # create db with optimized parameters
2167 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2168 self
.Conn
.execute("PRAGMA synchronous=OFF")
2169 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2170 self
.Conn
.execute("PRAGMA count_changes=OFF")
2171 self
.Conn
.execute("PRAGMA cache_size=8192")
2172 #self.Conn.execute("PRAGMA page_size=8192")
2174 # to avoid non-ascii character conversion issue
2175 self
.Conn
.text_factory
= str
2176 self
.Cur
= self
.Conn
.cursor()
2178 # create table for internal uses
2179 self
.TblDataModel
= TableDataModel(self
.Cur
)
2180 self
.TblFile
= TableFile(self
.Cur
)
2182 # conversion object for build or file format conversion purpose
2183 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2184 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2186 ## Check whether workspace database need to be renew.
2187 # The renew reason maybe:
2188 # 1) If user force to renew;
2189 # 2) If user do not force renew, and
2190 # a) If the time of last modified python source is newer than database file;
2191 # b) If the time of last modified frozen executable file is newer than database file;
2193 # @param force User force renew database
2194 # @param DbPath The absolute path of workspace database file
2196 # @return Bool value for whether need renew workspace databse
2198 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2199 DbDir
= os
.path
.split(DbPath
)[0]
2200 MacroFilePath
= os
.path
.normpath(os
.path
.join(DbDir
, "build.mac"))
2202 if os
.path
.exists(MacroFilePath
) and os
.path
.isfile(MacroFilePath
):
2205 f
= open(MacroFilePath
,'r')
2206 LastMacros
= pickle
.load(f
)
2213 if LastMacros
!= None and type(LastMacros
) is DictType
:
2214 if LastMacros
== self
._GlobalMacros
:
2216 for Macro
in LastMacros
.keys():
2217 if not (Macro
in self
._GlobalMacros
and LastMacros
[Macro
] == self
._GlobalMacros
[Macro
]):
2222 # save command line macros to file
2224 f
= open(MacroFilePath
,'w')
2225 pickle
.dump(self
._GlobalMacros
, f
, 2)
2234 # if database does not exist, we need do nothing
2235 if not os
.path
.exists(DbPath
): return False
2237 # if user force to renew database, then not check whether database is out of date
2238 if force
: return True
2241 # Check the time of last modified source file or build.exe
2242 # if is newer than time of database, then database need to be re-created.
2244 timeOfToolModified
= 0
2245 if hasattr(sys
, "frozen"):
2246 exePath
= os
.path
.abspath(sys
.executable
)
2247 timeOfToolModified
= os
.stat(exePath
).st_mtime
2249 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2250 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2251 if rootPath
== "" or rootPath
== None:
2252 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2253 determine whether database file is out of date!\n")
2255 # walk the root path of source or build's binary to get the time last modified.
2257 for root
, dirs
, files
in os
.walk (rootPath
):
2259 # bypass source control folder
2260 if dir.lower() in [".svn", "_svn", "cvs"]:
2264 ext
= os
.path
.splitext(file)[1]
2265 if ext
.lower() == ".py": # only check .py files
2266 fd
= os
.stat(os
.path
.join(root
, file))
2267 if timeOfToolModified
< fd
.st_mtime
:
2268 timeOfToolModified
= fd
.st_mtime
2269 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2270 EdkLogger
.verbose("\nWorkspace database is out of data!")
2275 ## Initialize build database
2276 def InitDatabase(self
):
2277 EdkLogger
.verbose("\nInitialize build database started ...")
2282 self
.TblDataModel
.Create(False)
2283 self
.TblFile
.Create(False)
2286 # Initialize table DataModel
2288 self
.TblDataModel
.InitTable()
2289 EdkLogger
.verbose("Initialize build database ... DONE!")
2293 # @param Table: The instance of the table to be queried
2295 def QueryTable(self
, Table
):
2298 ## Close entire database
2301 # Close the connection and cursor
2308 ## Get unique file ID for the gvien file
2309 def GetFileId(self
, FilePath
):
2310 return self
.TblFile
.GetFileId(FilePath
)
2312 ## Get file type value for the gvien file ID
2313 def GetFileType(self
, FileId
):
2314 return self
.TblFile
.GetFileType(FileId
)
2316 ## Get time stamp stored in file table
2317 def GetTimeStamp(self
, FileId
):
2318 return self
.TblFile
.GetFileTimeStamp(FileId
)
2320 ## Update time stamp in file table
2321 def SetTimeStamp(self
, FileId
, TimeStamp
):
2322 return self
.TblFile
.SetFileTimeStamp(FileId
, TimeStamp
)
2324 ## Check if a table integrity flag exists or not
2325 def CheckIntegrity(self
, TableName
):
2327 Result
= self
.Cur
.execute("select min(ID) from %s" % (TableName
)).fetchall()
2328 if Result
[0][0] != -1:
2331 # Check whether the meta data file has external dependency by comparing the time stamp
2333 Sql
= "select Value1, Value2 from %s where Model=%d" % (TableName
, MODEL_EXTERNAL_DEPENDENCY
)
2334 for Dependency
in self
.Cur
.execute(Sql
).fetchall():
2335 if str(os
.stat(Dependency
[0])[8]) != Dependency
[1]:
2341 ## Compose table name for given file type and file ID
2342 def GetTableName(self
, FileType
, FileId
):
2343 return "_%s_%s" % (FileType
, FileId
)
2345 ## Return a temp table containing all content of the given file
2347 # @param FileInfo The tuple containing path and type of a file
2349 def __getitem__(self
, FileInfo
):
2350 FilePath
, FileType
, Macros
= FileInfo
2351 if FileType
not in self
._FILE
_TABLE
_:
2354 # flag used to indicate if it's parsed or not
2355 FilePath
= str(FilePath
)
2357 FileId
= self
.GetFileId(FilePath
)
2359 TimeStamp
= os
.stat(FilePath
)[8]
2360 TableName
= self
.GetTableName(FileType
, FileId
)
2361 if TimeStamp
!= self
.GetTimeStamp(FileId
):
2362 # update the timestamp in database
2363 self
.SetTimeStamp(FileId
, TimeStamp
)
2365 # if the table exists and is integrity, don't parse it
2366 Parsed
= self
.CheckIntegrity(TableName
)
2368 FileId
= self
.TblFile
.InsertFile(FilePath
, FileType
)
2369 TableName
= self
.GetTableName(FileType
, FileId
)
2371 FileTable
= self
._FILE
_TABLE
_[FileType
](self
.Cur
, TableName
, FileId
)
2372 FileTable
.Create(not Parsed
)
2373 Parser
= self
._FILE
_PARSER
_[FileType
](FilePath
, FileType
, FileTable
, Macros
)
2374 # set the "Finished" flag in parser in order to avoid re-parsing (if parsed)
2375 Parser
.Finished
= Parsed
2378 ## Summarize all packages in the database
2379 def _GetPackageList(self
):
2381 for Module
in self
.ModuleList
:
2382 for Package
in Module
.Packages
:
2383 if Package
not in PackageList
:
2384 PackageList
.append(Package
)
2387 ## Summarize all platforms in the database
2388 def _GetPlatformList(self
):
2390 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2392 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2395 if Platform
!= None:
2396 PlatformList
.append(Platform
)
2399 ## Summarize all modules in the database
2400 def _GetModuleList(self
):
2402 for ModuleFile
in self
.TblFile
.GetFileList(MODEL_FILE_INF
):
2404 Module
= self
.BuildObject
[PathClass(ModuleFile
), 'COMMON']
2408 ModuleList
.append(Module
)
2411 PlatformList
= property(_GetPlatformList
)
2412 PackageList
= property(_GetPackageList
)
2413 ModuleList
= property(_GetModuleList
)
2417 # This acts like the main() function for the script, unless it is 'import'ed into another
2420 if __name__
== '__main__':