2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2014, 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.
18 import Common
.LongFilePathOs
as os
22 import Common
.EdkLogger
as EdkLogger
23 import Common
.GlobalData
as GlobalData
25 from Common
.String
import *
26 from Common
.DataType
import *
27 from Common
.Misc
import *
30 from CommonDataClass
.CommonClass
import SkuInfoClass
32 from MetaDataTable
import *
33 from MetaFileTable
import *
34 from MetaFileParser
import *
35 from BuildClassObject
import *
36 from WorkspaceCommon
import GetDeclaredPcd
37 from Common
.Misc
import AnalyzeDscPcd
39 from Common
.Parsing
import IsValidWord
41 ## Platform build information from DSC file
43 # This class is used to retrieve information stored in database and convert them
44 # into PlatformBuildClassObject form for easier use for AutoGen.
46 class DscBuildData(PlatformBuildClassObject
):
47 # dict used to convert PCD type in database to string used by build tool
49 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
50 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
51 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
52 MODEL_PCD_DYNAMIC
: "Dynamic",
53 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
54 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
55 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
56 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
57 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
58 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
59 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
62 # dict used to convert part of [Defines] to members of DscBuildData directly
67 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
68 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
69 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
70 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
71 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
72 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
73 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
74 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
75 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
76 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
77 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
78 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
79 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
80 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
81 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
84 # used to compose dummy library class name for those forced library instances
85 _NullLibraryNumber
= 0
87 ## Constructor of DscBuildData
89 # Initialize object of DscBuildData
91 # @param FilePath The path of platform description file
92 # @param RawData The raw data of DSC file
93 # @param BuildDataBase Database used to retrieve module/package information
94 # @param Arch The target architecture
95 # @param Platform (not used for DscBuildData)
96 # @param Macros Macros used for replacement in DSC file
98 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
99 self
.MetaFile
= FilePath
100 self
._RawData
= RawData
101 self
._Bdb
= BuildDataBase
103 self
._Target
= Target
104 self
._Toolchain
= Toolchain
108 def __setitem__(self
, key
, value
):
109 self
.__dict
__[self
._PROPERTY
_[key
]] = value
112 def __getitem__(self
, key
):
113 return self
.__dict
__[self
._PROPERTY
_[key
]]
116 def __contains__(self
, key
):
117 return key
in self
._PROPERTY
_
119 ## Set all internal used members of DscBuildData to None
122 self
._PlatformName
= None
125 self
._DscSpecification
= None
126 self
._OutputDirectory
= None
127 self
._SupArchList
= None
128 self
._BuildTargets
= None
130 self
._SkuIdentifier
= None
131 self
._PcdInfoFlag
= None
132 self
._FlashDefinition
= None
133 self
._BuildNumber
= None
134 self
._MakefileName
= None
135 self
._BsBaseAddress
= None
136 self
._RtBaseAddress
= None
139 self
._LibraryInstances
= None
140 self
._LibraryClasses
= None
143 self
._BuildOptions
= None
144 self
._LoadFixAddress
= None
145 self
._RFCLanguages
= None
146 self
._ISOLanguages
= None
147 self
._VpdToolGuid
= None
150 ## Get current effective macros
151 def _GetMacros(self
):
152 if self
.__Macros
== None:
154 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
155 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
156 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
165 # Changing the default ARCH to another may affect all other information
166 # because all information in a platform may be ARCH-related. That's
167 # why we need to clear all internal used members, in order to cause all
168 # information to be re-retrieved.
170 # @param Value The value of ARCH
172 def _SetArch(self
, Value
):
173 if self
._Arch
== Value
:
178 ## Retrieve all information in [Defines] section
180 # (Retriving all [Defines] information in one-shot is just to save time.)
182 def _GetHeaderInfo(self
):
183 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
184 for Record
in RecordList
:
186 # items defined _PROPERTY_ don't need additional processing
188 # some special items in [Defines] section need special treatment
189 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
190 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
191 if ' ' in self
._OutputDirectory
:
192 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
193 File
=self
.MetaFile
, Line
=Record
[-1],
194 ExtraData
=self
._OutputDirectory
)
195 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
196 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
197 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
199 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
201 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
202 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
203 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
204 self
._BuildTargets
= GetSplitValueList(Record
[2])
205 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
206 if self
._SkuName
== None:
207 self
._SkuName
= Record
[2]
208 self
._SkuIdentifier
= Record
[2]
209 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
210 self
._PcdInfoFlag
= Record
[2]
211 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
213 self
._LoadFixAddress
= int (Record
[2], 0)
215 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
216 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
217 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
218 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
219 File
=self
.MetaFile
, Line
=Record
[-1])
220 LanguageCodes
= Record
[2][1:-1]
221 if not LanguageCodes
:
222 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
223 File
=self
.MetaFile
, Line
=Record
[-1])
224 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
225 # check whether there is empty entries in the list
226 if None in LanguageList
:
227 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
228 File
=self
.MetaFile
, Line
=Record
[-1])
229 self
._RFCLanguages
= LanguageList
230 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
231 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
232 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
233 File
=self
.MetaFile
, Line
=Record
[-1])
234 LanguageCodes
= Record
[2][1:-1]
235 if not LanguageCodes
:
236 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
237 File
=self
.MetaFile
, Line
=Record
[-1])
238 if len(LanguageCodes
)%3:
239 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
240 File
=self
.MetaFile
, Line
=Record
[-1])
242 for i
in range(0, len(LanguageCodes
), 3):
243 LanguageList
.append(LanguageCodes
[i
:i
+3])
244 self
._ISOLanguages
= LanguageList
245 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
247 # try to convert GUID to a real UUID value to see whether the GUID is format
248 # for VPD_TOOL_GUID is correct.
253 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
254 self
._VpdToolGuid
= Record
[2]
256 self
[Name
] = Record
[2]
257 # set _Header to non-None in order to avoid database re-querying
258 self
._Header
= 'DUMMY'
260 ## Retrieve platform name
261 def _GetPlatformName(self
):
262 if self
._PlatformName
== None:
263 if self
._Header
== None:
264 self
._GetHeaderInfo
()
265 if self
._PlatformName
== None:
266 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
267 return self
._PlatformName
269 ## Retrieve file guid
270 def _GetFileGuid(self
):
271 if self
._Guid
== None:
272 if self
._Header
== None:
273 self
._GetHeaderInfo
()
274 if self
._Guid
== None:
275 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
278 ## Retrieve platform version
279 def _GetVersion(self
):
280 if self
._Version
== None:
281 if self
._Header
== None:
282 self
._GetHeaderInfo
()
283 if self
._Version
== None:
284 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
287 ## Retrieve platform description file version
288 def _GetDscSpec(self
):
289 if self
._DscSpecification
== None:
290 if self
._Header
== None:
291 self
._GetHeaderInfo
()
292 if self
._DscSpecification
== None:
293 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
294 return self
._DscSpecification
296 ## Retrieve OUTPUT_DIRECTORY
297 def _GetOutpuDir(self
):
298 if self
._OutputDirectory
== None:
299 if self
._Header
== None:
300 self
._GetHeaderInfo
()
301 if self
._OutputDirectory
== None:
302 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
303 return self
._OutputDirectory
305 ## Retrieve SUPPORTED_ARCHITECTURES
306 def _GetSupArch(self
):
307 if self
._SupArchList
== None:
308 if self
._Header
== None:
309 self
._GetHeaderInfo
()
310 if self
._SupArchList
== None:
311 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
312 return self
._SupArchList
314 ## Retrieve BUILD_TARGETS
315 def _GetBuildTarget(self
):
316 if self
._BuildTargets
== None:
317 if self
._Header
== None:
318 self
._GetHeaderInfo
()
319 if self
._BuildTargets
== None:
320 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
321 return self
._BuildTargets
323 def _GetPcdInfoFlag(self
):
324 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
326 elif self
._PcdInfoFlag
.upper() == 'TRUE':
331 def _GetSkuIdentifier(self
):
334 if self
._SkuIdentifier
== None:
335 if self
._Header
== None:
336 self
._GetHeaderInfo
()
337 return self
._SkuIdentifier
338 ## Retrieve SKUID_IDENTIFIER
339 def _GetSkuName(self
):
340 if self
._SkuName
== None:
341 if self
._Header
== None:
342 self
._GetHeaderInfo
()
343 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
344 self
._SkuName
= 'DEFAULT'
347 ## Override SKUID_IDENTIFIER
348 def _SetSkuName(self
, Value
):
349 self
._SkuName
= Value
352 def _GetFdfFile(self
):
353 if self
._FlashDefinition
== None:
354 if self
._Header
== None:
355 self
._GetHeaderInfo
()
356 if self
._FlashDefinition
== None:
357 self
._FlashDefinition
= ''
358 return self
._FlashDefinition
360 ## Retrieve FLASH_DEFINITION
361 def _GetBuildNumber(self
):
362 if self
._BuildNumber
== None:
363 if self
._Header
== None:
364 self
._GetHeaderInfo
()
365 if self
._BuildNumber
== None:
366 self
._BuildNumber
= ''
367 return self
._BuildNumber
369 ## Retrieve MAKEFILE_NAME
370 def _GetMakefileName(self
):
371 if self
._MakefileName
== None:
372 if self
._Header
== None:
373 self
._GetHeaderInfo
()
374 if self
._MakefileName
== None:
375 self
._MakefileName
= ''
376 return self
._MakefileName
378 ## Retrieve BsBaseAddress
379 def _GetBsBaseAddress(self
):
380 if self
._BsBaseAddress
== None:
381 if self
._Header
== None:
382 self
._GetHeaderInfo
()
383 if self
._BsBaseAddress
== None:
384 self
._BsBaseAddress
= ''
385 return self
._BsBaseAddress
387 ## Retrieve RtBaseAddress
388 def _GetRtBaseAddress(self
):
389 if self
._RtBaseAddress
== None:
390 if self
._Header
== None:
391 self
._GetHeaderInfo
()
392 if self
._RtBaseAddress
== None:
393 self
._RtBaseAddress
= ''
394 return self
._RtBaseAddress
396 ## Retrieve the top address for the load fix address
397 def _GetLoadFixAddress(self
):
398 if self
._LoadFixAddress
== None:
399 if self
._Header
== None:
400 self
._GetHeaderInfo
()
402 if self
._LoadFixAddress
== None:
403 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
406 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
408 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
411 # If command line defined, should override the value in DSC file.
413 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
415 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
417 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS']))
419 if self
._LoadFixAddress
< 0:
420 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
421 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
422 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
424 return self
._LoadFixAddress
426 ## Retrieve RFCLanguage filter
427 def _GetRFCLanguages(self
):
428 if self
._RFCLanguages
== None:
429 if self
._Header
== None:
430 self
._GetHeaderInfo
()
431 if self
._RFCLanguages
== None:
432 self
._RFCLanguages
= []
433 return self
._RFCLanguages
435 ## Retrieve ISOLanguage filter
436 def _GetISOLanguages(self
):
437 if self
._ISOLanguages
== None:
438 if self
._Header
== None:
439 self
._GetHeaderInfo
()
440 if self
._ISOLanguages
== None:
441 self
._ISOLanguages
= []
442 return self
._ISOLanguages
443 ## Retrieve the GUID string for VPD tool
444 def _GetVpdToolGuid(self
):
445 if self
._VpdToolGuid
== None:
446 if self
._Header
== None:
447 self
._GetHeaderInfo
()
448 if self
._VpdToolGuid
== None:
449 self
._VpdToolGuid
= ''
450 return self
._VpdToolGuid
452 ## Retrieve [SkuIds] section information
453 def _GetSkuIds(self
):
454 if self
._SkuIds
== None:
455 self
._SkuIds
= sdict()
456 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
457 for Record
in RecordList
:
458 if Record
[0] in [None, '']:
459 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
460 File
=self
.MetaFile
, Line
=Record
[-1])
461 if Record
[1] in [None, '']:
462 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
463 File
=self
.MetaFile
, Line
=Record
[-1])
464 self
._SkuIds
[Record
[1]] = Record
[0]
465 if 'DEFAULT' not in self
._SkuIds
:
466 self
._SkuIds
['DEFAULT'] = '0'
467 if 'COMMON' not in self
._SkuIds
:
468 self
._SkuIds
['COMMON'] = '0'
471 ## Retrieve [Components] section information
472 def _GetModules(self
):
473 if self
._Modules
!= None:
476 self
._Modules
= sdict()
477 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
478 Macros
= self
._Macros
479 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
480 for Record
in RecordList
:
481 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
485 # check the file validation
486 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
488 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
491 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
492 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
493 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
495 Module
= ModuleBuildClassObject()
496 Module
.MetaFile
= ModuleFile
498 # get module override path
499 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
501 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
503 # Check if the source override path exists
504 if not os
.path
.isdir(Module
.SourceOverridePath
):
505 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
507 #Add to GlobalData Variables
508 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
510 # get module private library instance
511 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
512 for Record
in RecordList
:
513 LibraryClass
= Record
[0]
514 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
517 # check the file validation
518 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
520 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
523 if LibraryClass
== '' or LibraryClass
== 'NULL':
524 self
._NullLibraryNumber
+= 1
525 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
526 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
527 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
528 if LibraryPath
not in self
.LibraryInstances
:
529 self
.LibraryInstances
.append(LibraryPath
)
531 # get module private PCD setting
532 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
533 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
534 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
535 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
536 TokenList
= GetSplitValueList(Setting
)
537 DefaultValue
= TokenList
[0]
538 if len(TokenList
) > 1:
539 MaxDatumSize
= TokenList
[1]
542 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
543 Pcd
= PcdClassObject(
555 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
557 # get module private build options
558 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
559 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
560 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
561 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
563 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
564 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
566 self
._Modules
[ModuleFile
] = Module
569 ## Retrieve all possible library instances used in this platform
570 def _GetLibraryInstances(self
):
571 if self
._LibraryInstances
== None:
572 self
._GetLibraryClasses
()
573 return self
._LibraryInstances
575 ## Retrieve [LibraryClasses] information
576 def _GetLibraryClasses(self
):
577 if self
._LibraryClasses
== None:
578 self
._LibraryInstances
= []
580 # tdict is a special dict kind of type, used for selecting correct
581 # library instance for given library class and module type
583 LibraryClassDict
= tdict(True, 3)
584 # track all library class names
585 LibraryClassSet
= set()
586 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
587 Macros
= self
._Macros
588 for Record
in RecordList
:
589 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
590 if LibraryClass
== '' or LibraryClass
== 'NULL':
591 self
._NullLibraryNumber
+= 1
592 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
593 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
594 LibraryClassSet
.add(LibraryClass
)
595 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
596 # check the file validation
597 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
599 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
602 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
603 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
604 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
605 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
606 if LibraryInstance
not in self
._LibraryInstances
:
607 self
._LibraryInstances
.append(LibraryInstance
)
609 # resolve the specific library instance for each class and each module type
610 self
._LibraryClasses
= tdict(True)
611 for LibraryClass
in LibraryClassSet
:
612 # try all possible module types
613 for ModuleType
in SUP_MODULE_LIST
:
614 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
615 if LibraryInstance
== None:
617 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
619 # for Edk style library instances, which are listed in different section
620 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
621 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
622 for Record
in RecordList
:
623 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
625 # check the file validation
626 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
628 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
630 if File
not in self
._LibraryInstances
:
631 self
._LibraryInstances
.append(File
)
633 # we need the module name as the library class name, so we have
634 # to parse it here. (self._Bdb[] will trigger a file parse if it
635 # hasn't been parsed)
637 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
638 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
639 return self
._LibraryClasses
641 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
642 if self
._DecPcds
== None:
643 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
644 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
645 EdkLogger
.error('build', PARSER_ERROR
,
646 "Pcd (%s.%s) defined in DSC is not declared in DEC files." % (TokenSpaceGuid
, PcdCName
),
647 File
=self
.MetaFile
, Line
=LineNo
)
648 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
649 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
650 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
651 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
652 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
654 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
655 except WrnExpression
, Value
:
656 ValueList
[Index
] = Value
.result
657 except EvaluationException
, Excpt
:
658 if hasattr(Excpt
, 'Pcd'):
659 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
660 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
661 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
662 " of the DSC file" % Excpt
.Pcd
,
663 File
=self
.MetaFile
, Line
=LineNo
)
665 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
666 File
=self
.MetaFile
, Line
=LineNo
)
668 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
669 File
=self
.MetaFile
, Line
=LineNo
)
670 if ValueList
[Index
] == 'True':
671 ValueList
[Index
] = '1'
672 elif ValueList
[Index
] == 'False':
673 ValueList
[Index
] = '0'
675 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
677 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
678 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
681 ## Retrieve all PCD settings in platform
683 if self
._Pcds
== None:
685 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
686 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
687 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
688 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
689 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
690 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
691 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
692 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
693 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
696 ## Retrieve [BuildOptions]
697 def _GetBuildOptions(self
):
698 if self
._BuildOptions
== None:
699 self
._BuildOptions
= sdict()
701 # Retrieve build option for EDKII style module
703 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
704 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
705 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
707 # Retrieve build option for EDK style module
709 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
710 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
711 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
712 return self
._BuildOptions
714 ## Retrieve non-dynamic PCD settings
716 # @param Type PCD type
718 # @retval a dict object contains settings of given PCD type
720 def _GetPcd(self
, Type
):
723 # tdict is a special dict kind of type, used for selecting correct
724 # PCD settings for certain ARCH
727 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
729 PcdDict
= tdict(True, 3)
731 # Find out all possible PCD candidates for self._Arch
732 RecordList
= self
._RawData
[Type
, self
._Arch
]
733 PcdValueDict
= sdict()
734 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
735 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
736 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
737 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
739 #handle pcd value override
740 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
741 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
744 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
745 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
746 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
748 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
750 PcdsKeys
= PcdValueDict
.keys()
751 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
753 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
757 if 'COMMON' in PcdSetting
:
758 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
759 if 'DEFAULT' in PcdSetting
:
760 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
761 if SkuObj
.SystemSkuId
in PcdSetting
:
762 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
764 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
767 self
._PCD
_TYPE
_STRING
_[Type
],
778 ## Retrieve dynamic PCD settings
780 # @param Type PCD type
782 # @retval a dict object contains settings of given PCD type
784 def _GetDynamicPcd(self
, Type
):
786 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
790 # tdict is a special dict kind of type, used for selecting correct
791 # PCD settings for certain ARCH and SKU
793 PcdDict
= tdict(True, 4)
795 # Find out all possible PCD candidates for self._Arch
796 RecordList
= self
._RawData
[Type
, self
._Arch
]
797 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
799 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
800 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
801 if SkuName
not in AvailableSkuIdSet
:
804 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
805 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
806 # Remove redundant PCD candidates, per the ARCH and SKU
807 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
809 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
813 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
814 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
815 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
816 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
817 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
818 if MaxDatumSize
.strip():
819 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
822 if pcdObject
.MaxDatumSize
:
823 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
826 if CurrentMaxSize
> PcdMaxSize
:
827 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
829 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
832 self
._PCD
_TYPE
_STRING
_[Type
],
842 for pcd
in Pcds
.values():
843 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
844 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
845 valuefromDec
= pcdDecObject
.DefaultValue
846 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
847 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
848 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
849 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
850 del(pcd
.SkuInfoList
['COMMON'])
851 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
852 del(pcd
.SkuInfoList
['COMMON'])
853 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
854 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
855 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
856 del(pcd
.SkuInfoList
['DEFAULT'])
860 ## Retrieve dynamic HII PCD settings
862 # @param Type PCD type
864 # @retval a dict object contains settings of given PCD type
866 def _GetDynamicHiiPcd(self
, Type
):
868 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
872 # tdict is a special dict kind of type, used for selecting correct
873 # PCD settings for certain ARCH and SKU
875 PcdDict
= tdict(True, 4)
877 RecordList
= self
._RawData
[Type
, self
._Arch
]
878 # Find out all possible PCD candidates for self._Arch
879 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
881 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
882 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
883 if SkuName
not in AvailableSkuIdSet
:
885 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
886 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
887 # Remove redundant PCD candidates, per the ARCH and SKU
888 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
890 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
893 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
897 if VariableOffset
.isdigit():
898 if int(VariableOffset
,10) > 0xFFFF:
900 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
901 if int(VariableOffset
,16) > 0xFFFF:
903 # For Offset written in "A.B"
904 elif VariableOffset
.find('.') > -1:
905 VariableOffsetList
= VariableOffset
.split(".")
906 if not (len(VariableOffsetList
) == 2
907 and IsValidWord(VariableOffsetList
[0])
908 and IsValidWord(VariableOffsetList
[1])):
909 FormatCorrect
= False
911 FormatCorrect
= False
912 if not FormatCorrect
:
913 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
916 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
918 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
919 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
920 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
921 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
923 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
926 self
._PCD
_TYPE
_STRING
_[Type
],
937 for pcd
in Pcds
.values():
938 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
939 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
940 # Only fix the value while no value provided in DSC file.
941 for sku
in pcd
.SkuInfoList
.values():
942 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
943 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
944 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
945 valuefromDec
= pcdDecObject
.DefaultValue
946 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
947 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
948 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
949 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
950 del(pcd
.SkuInfoList
['COMMON'])
951 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
952 del(pcd
.SkuInfoList
['COMMON'])
954 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
955 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
956 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
957 del(pcd
.SkuInfoList
['DEFAULT'])
960 if pcd
.MaxDatumSize
.strip():
961 MaxSize
= int(pcd
.MaxDatumSize
,0)
964 if pcdDecObject
.DatumType
== 'VOID*':
965 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
967 if skuobj
.HiiDefaultValue
.startswith("L"):
968 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
969 elif skuobj
.HiiDefaultValue
.startswith("{"):
970 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
972 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
975 pcd
.MaxDatumSize
= str(MaxSize
)
978 ## Retrieve dynamic VPD PCD settings
980 # @param Type PCD type
982 # @retval a dict object contains settings of given PCD type
984 def _GetDynamicVpdPcd(self
, Type
):
986 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
990 # tdict is a special dict kind of type, used for selecting correct
991 # PCD settings for certain ARCH and SKU
993 PcdDict
= tdict(True, 4)
995 # Find out all possible PCD candidates for self._Arch
996 RecordList
= self
._RawData
[Type
, self
._Arch
]
997 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
999 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1000 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1001 if SkuName
not in AvailableSkuIdSet
:
1004 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1005 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1006 # Remove redundant PCD candidates, per the ARCH and SKU
1007 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1008 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1012 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1013 # For the Integer & Boolean type, the optional data can only be InitialValue.
1014 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1015 # until the DEC parser has been called.
1017 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1018 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1019 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1020 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1021 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1022 if MaxDatumSize
.strip():
1023 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1026 if pcdObject
.MaxDatumSize
:
1027 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1030 if CurrentMaxSize
> PcdMaxSize
:
1031 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1033 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1036 self
._PCD
_TYPE
_STRING
_[Type
],
1041 {SkuName
: SkuInfo
},
1045 for pcd
in Pcds
.values():
1046 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1047 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1048 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1049 valuefromDec
= pcdDecObject
.DefaultValue
1050 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1051 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1052 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1053 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1054 del(pcd
.SkuInfoList
['COMMON'])
1055 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1056 del(pcd
.SkuInfoList
['COMMON'])
1057 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1058 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1059 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1060 del(pcd
.SkuInfoList
['DEFAULT'])
1064 ## Add external modules
1066 # The external modules are mostly those listed in FDF file, which don't
1069 # @param FilePath The path of module description file
1071 def AddModule(self
, FilePath
):
1072 FilePath
= NormPath(FilePath
)
1073 if FilePath
not in self
.Modules
:
1074 Module
= ModuleBuildClassObject()
1075 Module
.MetaFile
= FilePath
1076 self
.Modules
.append(Module
)
1078 ## Add external PCDs
1080 # The external PCDs are mostly those listed in FDF file to specify address
1081 # or offset information.
1083 # @param Name Name of the PCD
1084 # @param Guid Token space guid of the PCD
1085 # @param Value Value of the PCD
1087 def AddPcd(self
, Name
, Guid
, Value
):
1088 if (Name
, Guid
) not in self
.Pcds
:
1089 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1090 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1092 _Macros
= property(_GetMacros
)
1093 Arch
= property(_GetArch
, _SetArch
)
1094 Platform
= property(_GetPlatformName
)
1095 PlatformName
= property(_GetPlatformName
)
1096 Guid
= property(_GetFileGuid
)
1097 Version
= property(_GetVersion
)
1098 DscSpecification
= property(_GetDscSpec
)
1099 OutputDirectory
= property(_GetOutpuDir
)
1100 SupArchList
= property(_GetSupArch
)
1101 BuildTargets
= property(_GetBuildTarget
)
1102 SkuName
= property(_GetSkuName
, _SetSkuName
)
1103 SkuIdentifier
= property(_GetSkuIdentifier
)
1104 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1105 FlashDefinition
= property(_GetFdfFile
)
1106 BuildNumber
= property(_GetBuildNumber
)
1107 MakefileName
= property(_GetMakefileName
)
1108 BsBaseAddress
= property(_GetBsBaseAddress
)
1109 RtBaseAddress
= property(_GetRtBaseAddress
)
1110 LoadFixAddress
= property(_GetLoadFixAddress
)
1111 RFCLanguages
= property(_GetRFCLanguages
)
1112 ISOLanguages
= property(_GetISOLanguages
)
1113 VpdToolGuid
= property(_GetVpdToolGuid
)
1114 SkuIds
= property(_GetSkuIds
)
1115 Modules
= property(_GetModules
)
1116 LibraryInstances
= property(_GetLibraryInstances
)
1117 LibraryClasses
= property(_GetLibraryClasses
)
1118 Pcds
= property(_GetPcds
)
1119 BuildOptions
= property(_GetBuildOptions
)
1121 ## Platform build information from DEC file
1123 # This class is used to retrieve information stored in database and convert them
1124 # into PackageBuildClassObject form for easier use for AutoGen.
1126 class DecBuildData(PackageBuildClassObject
):
1127 # dict used to convert PCD type in database to string used by build tool
1128 _PCD_TYPE_STRING_
= {
1129 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1130 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1131 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1132 MODEL_PCD_DYNAMIC
: "Dynamic",
1133 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1134 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1135 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1136 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1137 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1138 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1139 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1142 # dict used to convert part of [Defines] to members of DecBuildData directly
1147 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1148 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1149 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1150 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1154 ## Constructor of DecBuildData
1156 # Initialize object of DecBuildData
1158 # @param FilePath The path of package description file
1159 # @param RawData The raw data of DEC file
1160 # @param BuildDataBase Database used to retrieve module information
1161 # @param Arch The target architecture
1162 # @param Platform (not used for DecBuildData)
1163 # @param Macros Macros used for replacement in DSC file
1165 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1166 self
.MetaFile
= File
1167 self
._PackageDir
= File
.Dir
1168 self
._RawData
= RawData
1169 self
._Bdb
= BuildDataBase
1171 self
._Target
= Target
1172 self
._Toolchain
= Toolchain
1176 def __setitem__(self
, key
, value
):
1177 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1180 def __getitem__(self
, key
):
1181 return self
.__dict
__[self
._PROPERTY
_[key
]]
1183 ## "in" test support
1184 def __contains__(self
, key
):
1185 return key
in self
._PROPERTY
_
1187 ## Set all internal used members of DecBuildData to None
1190 self
._PackageName
= None
1192 self
._Version
= None
1193 self
._PkgUniFile
= None
1194 self
._Protocols
= None
1197 self
._Includes
= None
1198 self
._LibraryClasses
= None
1200 self
.__Macros
= None
1202 ## Get current effective macros
1203 def _GetMacros(self
):
1204 if self
.__Macros
== None:
1206 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1207 return self
.__Macros
1215 # Changing the default ARCH to another may affect all other information
1216 # because all information in a platform may be ARCH-related. That's
1217 # why we need to clear all internal used members, in order to cause all
1218 # information to be re-retrieved.
1220 # @param Value The value of ARCH
1222 def _SetArch(self
, Value
):
1223 if self
._Arch
== Value
:
1228 ## Retrieve all information in [Defines] section
1230 # (Retriving all [Defines] information in one-shot is just to save time.)
1232 def _GetHeaderInfo(self
):
1233 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1234 for Record
in RecordList
:
1237 self
[Name
] = Record
[2]
1238 self
._Header
= 'DUMMY'
1240 ## Retrieve package name
1241 def _GetPackageName(self
):
1242 if self
._PackageName
== None:
1243 if self
._Header
== None:
1244 self
._GetHeaderInfo
()
1245 if self
._PackageName
== None:
1246 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1247 return self
._PackageName
1249 ## Retrieve file guid
1250 def _GetFileGuid(self
):
1251 if self
._Guid
== None:
1252 if self
._Header
== None:
1253 self
._GetHeaderInfo
()
1254 if self
._Guid
== None:
1255 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1258 ## Retrieve package version
1259 def _GetVersion(self
):
1260 if self
._Version
== None:
1261 if self
._Header
== None:
1262 self
._GetHeaderInfo
()
1263 if self
._Version
== None:
1265 return self
._Version
1267 ## Retrieve protocol definitions (name/value pairs)
1268 def _GetProtocol(self
):
1269 if self
._Protocols
== None:
1271 # tdict is a special kind of dict, used for selecting correct
1272 # protocol defition for given ARCH
1274 ProtocolDict
= tdict(True)
1276 # find out all protocol definitions for specific and 'common' arch
1277 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1278 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1279 if Name
not in NameList
:
1280 NameList
.append(Name
)
1281 ProtocolDict
[Arch
, Name
] = Guid
1282 # use sdict to keep the order
1283 self
._Protocols
= sdict()
1284 for Name
in NameList
:
1286 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1287 # will automatically turn to 'common' ARCH for trying
1289 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1290 return self
._Protocols
1292 ## Retrieve PPI definitions (name/value pairs)
1294 if self
._Ppis
== None:
1296 # tdict is a special kind of dict, used for selecting correct
1297 # PPI defition for given ARCH
1299 PpiDict
= tdict(True)
1301 # find out all PPI definitions for specific arch and 'common' arch
1302 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1303 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1304 if Name
not in NameList
:
1305 NameList
.append(Name
)
1306 PpiDict
[Arch
, Name
] = Guid
1307 # use sdict to keep the order
1308 self
._Ppis
= sdict()
1309 for Name
in NameList
:
1311 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1312 # will automatically turn to 'common' ARCH for trying
1314 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1317 ## Retrieve GUID definitions (name/value pairs)
1319 if self
._Guids
== None:
1321 # tdict is a special kind of dict, used for selecting correct
1322 # GUID defition for given ARCH
1324 GuidDict
= tdict(True)
1326 # find out all protocol definitions for specific and 'common' arch
1327 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1328 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1329 if Name
not in NameList
:
1330 NameList
.append(Name
)
1331 GuidDict
[Arch
, Name
] = Guid
1332 # use sdict to keep the order
1333 self
._Guids
= sdict()
1334 for Name
in NameList
:
1336 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1337 # will automatically turn to 'common' ARCH for trying
1339 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1342 ## Retrieve public include paths declared in this package
1343 def _GetInclude(self
):
1344 if self
._Includes
== None:
1346 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1347 Macros
= self
._Macros
1348 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1349 for Record
in RecordList
:
1350 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1353 ErrorCode
, ErrorInfo
= File
.Validate()
1355 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1357 # avoid duplicate include path
1358 if File
not in self
._Includes
:
1359 self
._Includes
.append(File
)
1360 return self
._Includes
1362 ## Retrieve library class declarations (not used in build at present)
1363 def _GetLibraryClass(self
):
1364 if self
._LibraryClasses
== None:
1366 # tdict is a special kind of dict, used for selecting correct
1367 # library class declaration for given ARCH
1369 LibraryClassDict
= tdict(True)
1370 LibraryClassSet
= set()
1371 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1372 Macros
= self
._Macros
1373 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1374 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1375 # check the file validation
1376 ErrorCode
, ErrorInfo
= File
.Validate()
1378 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1379 LibraryClassSet
.add(LibraryClass
)
1380 LibraryClassDict
[Arch
, LibraryClass
] = File
1381 self
._LibraryClasses
= sdict()
1382 for LibraryClass
in LibraryClassSet
:
1383 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1384 return self
._LibraryClasses
1386 ## Retrieve PCD declarations
1388 if self
._Pcds
== None:
1389 self
._Pcds
= sdict()
1390 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1391 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1392 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1393 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1394 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1397 ## Retrieve PCD declarations for given type
1398 def _GetPcd(self
, Type
):
1401 # tdict is a special kind of dict, used for selecting correct
1402 # PCD declaration for given ARCH
1404 PcdDict
= tdict(True, 3)
1405 # for summarizing PCD
1407 # find out all PCDs of the 'type'
1408 RecordList
= self
._RawData
[Type
, self
._Arch
]
1409 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1410 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1411 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1413 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1415 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1416 # will automatically turn to 'common' ARCH and try again
1418 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1422 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1424 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1427 self
._PCD
_TYPE
_STRING
_[Type
],
1439 _Macros
= property(_GetMacros
)
1440 Arch
= property(_GetArch
, _SetArch
)
1441 PackageName
= property(_GetPackageName
)
1442 Guid
= property(_GetFileGuid
)
1443 Version
= property(_GetVersion
)
1445 Protocols
= property(_GetProtocol
)
1446 Ppis
= property(_GetPpi
)
1447 Guids
= property(_GetGuid
)
1448 Includes
= property(_GetInclude
)
1449 LibraryClasses
= property(_GetLibraryClass
)
1450 Pcds
= property(_GetPcds
)
1452 ## Module build information from INF file
1454 # This class is used to retrieve information stored in database and convert them
1455 # into ModuleBuildClassObject form for easier use for AutoGen.
1457 class InfBuildData(ModuleBuildClassObject
):
1458 # dict used to convert PCD type in database to string used by build tool
1459 _PCD_TYPE_STRING_
= {
1460 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1461 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1462 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1463 MODEL_PCD_DYNAMIC
: "Dynamic",
1464 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1465 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1466 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1467 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1468 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1469 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1470 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1473 # dict used to convert part of [Defines] to members of InfBuildData directly
1478 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1479 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1480 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1484 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1485 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1486 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1487 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1488 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1489 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1490 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1491 TAB_INF_DEFINES_VERSION
: "_Version",
1492 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1493 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1495 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1498 # dict used to convert Component type to Module type
1501 "SECURITY_CORE" : "SEC",
1502 "PEI_CORE" : "PEI_CORE",
1503 "COMBINED_PEIM_DRIVER" : "PEIM",
1504 "PIC_PEIM" : "PEIM",
1505 "RELOCATABLE_PEIM" : "PEIM",
1506 "PE32_PEIM" : "PEIM",
1507 "BS_DRIVER" : "DXE_DRIVER",
1508 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1509 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1510 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1511 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1512 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1513 # "BS_DRIVER" : "UEFI_DRIVER",
1514 "APPLICATION" : "UEFI_APPLICATION",
1518 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1519 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1520 # dict used to convert old tool name used in [nmake] section to new ones
1528 ## Constructor of DscBuildData
1530 # Initialize object of DscBuildData
1532 # @param FilePath The path of platform description file
1533 # @param RawData The raw data of DSC file
1534 # @param BuildDataBase Database used to retrieve module/package information
1535 # @param Arch The target architecture
1536 # @param Platform The name of platform employing this module
1537 # @param Macros Macros used for replacement in DSC file
1539 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1540 self
.MetaFile
= FilePath
1541 self
._ModuleDir
= FilePath
.Dir
1542 self
._RawData
= RawData
1543 self
._Bdb
= BuildDatabase
1545 self
._Target
= Target
1546 self
._Toolchain
= Toolchain
1547 self
._Platform
= 'COMMON'
1548 self
._SourceOverridePath
= None
1549 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1550 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1554 def __setitem__(self
, key
, value
):
1555 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1558 def __getitem__(self
, key
):
1559 return self
.__dict
__[self
._PROPERTY
_[key
]]
1561 ## "in" test support
1562 def __contains__(self
, key
):
1563 return key
in self
._PROPERTY
_
1565 ## Set all internal used members of InfBuildData to None
1567 self
._HeaderComments
= None
1568 self
._TailComments
= None
1569 self
._Header
_ = None
1570 self
._AutoGenVersion
= None
1571 self
._BaseName
= None
1572 self
._DxsFile
= None
1573 self
._ModuleType
= None
1574 self
._ComponentType
= None
1575 self
._BuildType
= None
1577 self
._Version
= None
1578 self
._PcdIsDriver
= None
1579 self
._BinaryModule
= None
1581 self
._MakefileName
= None
1582 self
._CustomMakefile
= None
1583 self
._Specification
= None
1584 self
._LibraryClass
= None
1585 self
._ModuleEntryPointList
= None
1586 self
._ModuleUnloadImageList
= None
1587 self
._ConstructorList
= None
1588 self
._DestructorList
= None
1590 self
._Binaries
= None
1591 self
._Sources
= None
1592 self
._LibraryClasses
= None
1593 self
._Libraries
= None
1594 self
._Protocols
= None
1595 self
._ProtocolComments
= None
1597 self
._PpiComments
= None
1599 self
._GuidsUsedByPcd
= sdict()
1600 self
._GuidComments
= None
1601 self
._Includes
= None
1602 self
._Packages
= None
1604 self
._PcdComments
= None
1605 self
._BuildOptions
= None
1607 self
._DepexExpression
= None
1608 self
.__Macros
= None
1610 ## Get current effective macros
1611 def _GetMacros(self
):
1612 if self
.__Macros
== None:
1614 # EDK_GLOBAL defined macros can be applied to EDK module
1615 if self
.AutoGenVersion
< 0x00010005:
1616 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1617 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1618 return self
.__Macros
1626 # Changing the default ARCH to another may affect all other information
1627 # because all information in a platform may be ARCH-related. That's
1628 # why we need to clear all internal used members, in order to cause all
1629 # information to be re-retrieved.
1631 # @param Value The value of ARCH
1633 def _SetArch(self
, Value
):
1634 if self
._Arch
== Value
:
1639 ## Return the name of platform employing this module
1640 def _GetPlatform(self
):
1641 return self
._Platform
1643 ## Change the name of platform employing this module
1645 # Changing the default name of platform to another may affect some information
1646 # because they may be PLATFORM-related. That's why we need to clear all internal
1647 # used members, in order to cause all information to be re-retrieved.
1649 def _SetPlatform(self
, Value
):
1650 if self
._Platform
== Value
:
1652 self
._Platform
= Value
1654 def _GetHeaderComments(self
):
1655 if not self
._HeaderComments
:
1656 self
._HeaderComments
= []
1657 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1658 for Record
in RecordList
:
1659 self
._HeaderComments
.append(Record
[0])
1660 return self
._HeaderComments
1661 def _GetTailComments(self
):
1662 if not self
._TailComments
:
1663 self
._TailComments
= []
1664 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1665 for Record
in RecordList
:
1666 self
._TailComments
.append(Record
[0])
1667 return self
._TailComments
1668 ## Retrieve all information in [Defines] section
1670 # (Retriving all [Defines] information in one-shot is just to save time.)
1672 def _GetHeaderInfo(self
):
1673 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1674 for Record
in RecordList
:
1675 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1676 # items defined _PROPERTY_ don't need additional processing
1679 # some special items in [Defines] section need special treatment
1680 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1681 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1682 Name
= 'UEFI_SPECIFICATION_VERSION'
1683 if self
._Specification
== None:
1684 self
._Specification
= sdict()
1685 self
._Specification
[Name
] = GetHexVerValue(Value
)
1686 if self
._Specification
[Name
] == None:
1687 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1688 "'%s' format is not supported for %s" % (Value
, Name
),
1689 File
=self
.MetaFile
, Line
=Record
[-1])
1690 elif Name
== 'LIBRARY_CLASS':
1691 if self
._LibraryClass
== None:
1692 self
._LibraryClass
= []
1693 ValueList
= GetSplitValueList(Value
)
1694 LibraryClass
= ValueList
[0]
1695 if len(ValueList
) > 1:
1696 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1698 SupModuleList
= SUP_MODULE_LIST
1699 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1700 elif Name
== 'ENTRY_POINT':
1701 if self
._ModuleEntryPointList
== None:
1702 self
._ModuleEntryPointList
= []
1703 self
._ModuleEntryPointList
.append(Value
)
1704 elif Name
== 'UNLOAD_IMAGE':
1705 if self
._ModuleUnloadImageList
== None:
1706 self
._ModuleUnloadImageList
= []
1709 self
._ModuleUnloadImageList
.append(Value
)
1710 elif Name
== 'CONSTRUCTOR':
1711 if self
._ConstructorList
== None:
1712 self
._ConstructorList
= []
1715 self
._ConstructorList
.append(Value
)
1716 elif Name
== 'DESTRUCTOR':
1717 if self
._DestructorList
== None:
1718 self
._DestructorList
= []
1721 self
._DestructorList
.append(Value
)
1722 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1723 TokenList
= GetSplitValueList(Value
)
1724 if self
._CustomMakefile
== None:
1725 self
._CustomMakefile
= {}
1726 if len(TokenList
) < 2:
1727 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1728 self
._CustomMakefile
['GCC'] = TokenList
[0]
1730 if TokenList
[0] not in ['MSFT', 'GCC']:
1731 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1732 "No supported family [%s]" % TokenList
[0],
1733 File
=self
.MetaFile
, Line
=Record
[-1])
1734 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1736 if self
._Defs
== None:
1737 self
._Defs
= sdict()
1738 self
._Defs
[Name
] = Value
1741 # Retrieve information in sections specific to Edk.x modules
1743 if self
.AutoGenVersion
>= 0x00010005:
1744 if not self
._ModuleType
:
1745 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1746 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1747 if self
._ModuleType
not in SUP_MODULE_LIST
:
1748 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1749 for Record
in RecordList
:
1751 if Name
== "MODULE_TYPE":
1754 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1755 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1756 File
=self
.MetaFile
, Line
=LineNo
)
1757 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1758 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1759 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
)
1760 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1761 and 'PCI_CLASS_CODE' in self
._Defs
:
1762 self
._BuildType
= 'UEFI_OPTIONROM'
1763 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1764 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1765 self
._BuildType
= 'UEFI_HII'
1767 self
._BuildType
= self
._ModuleType
.upper()
1770 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1771 # check the file validation
1772 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1774 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1775 File
=self
.MetaFile
, Line
=LineNo
)
1776 if self
.Sources
== None:
1778 self
._Sources
.append(File
)
1780 if not self
._ComponentType
:
1781 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1782 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1783 self
._BuildType
= self
._ComponentType
.upper()
1784 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1785 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1786 if self
._ComponentType
== 'LIBRARY':
1787 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1788 # make use some [nmake] section macros
1789 Macros
= self
._Macros
1790 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1791 Macros
['PROCESSOR'] = self
._Arch
1792 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1793 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1794 Value
= ReplaceMacro(Value
, Macros
, True)
1795 if Name
== "IMAGE_ENTRY_POINT":
1796 if self
._ModuleEntryPointList
== None:
1797 self
._ModuleEntryPointList
= []
1798 self
._ModuleEntryPointList
.append(Value
)
1799 elif Name
== "DPX_SOURCE":
1800 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1801 # check the file validation
1802 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1804 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1805 File
=self
.MetaFile
, Line
=LineNo
)
1806 if self
.Sources
== None:
1808 self
._Sources
.append(File
)
1810 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1811 if len(ToolList
) == 0 or len(ToolList
) != 1:
1813 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1814 # File=self.MetaFile, Line=LineNo)
1816 if self
._BuildOptions
== None:
1817 self
._BuildOptions
= sdict()
1819 if ToolList
[0] in self
._TOOL
_CODE
_:
1820 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1823 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1824 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1825 #ignore not replaced macros in value
1826 ValueList
= GetSplitList(' ' + Value
, '/D')
1827 Dummy
= ValueList
[0]
1828 for Index
in range(1, len(ValueList
)):
1829 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1831 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1832 Value
= Dummy
.strip()
1833 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1834 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1836 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1837 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1838 # set _Header to non-None in order to avoid database re-querying
1839 self
._Header
_ = 'DUMMY'
1841 ## Retrieve file version
1842 def _GetInfVersion(self
):
1843 if self
._AutoGenVersion
== None:
1844 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1845 for Record
in RecordList
:
1846 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1847 self
._AutoGenVersion
= int(Record
[2], 0)
1849 if self
._AutoGenVersion
== None:
1850 self
._AutoGenVersion
= 0x00010000
1851 return self
._AutoGenVersion
1853 ## Retrieve BASE_NAME
1854 def _GetBaseName(self
):
1855 if self
._BaseName
== None:
1856 if self
._Header
_ == None:
1857 self
._GetHeaderInfo
()
1858 if self
._BaseName
== None:
1859 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1860 return self
._BaseName
1863 def _GetDxsFile(self
):
1864 if self
._DxsFile
== None:
1865 if self
._Header
_ == None:
1866 self
._GetHeaderInfo
()
1867 if self
._DxsFile
== None:
1869 return self
._DxsFile
1871 ## Retrieve MODULE_TYPE
1872 def _GetModuleType(self
):
1873 if self
._ModuleType
== None:
1874 if self
._Header
_ == None:
1875 self
._GetHeaderInfo
()
1876 if self
._ModuleType
== None:
1877 self
._ModuleType
= 'BASE'
1878 if self
._ModuleType
not in SUP_MODULE_LIST
:
1879 self
._ModuleType
= "USER_DEFINED"
1880 return self
._ModuleType
1882 ## Retrieve COMPONENT_TYPE
1883 def _GetComponentType(self
):
1884 if self
._ComponentType
== None:
1885 if self
._Header
_ == None:
1886 self
._GetHeaderInfo
()
1887 if self
._ComponentType
== None:
1888 self
._ComponentType
= 'USER_DEFINED'
1889 return self
._ComponentType
1891 ## Retrieve "BUILD_TYPE"
1892 def _GetBuildType(self
):
1893 if self
._BuildType
== None:
1894 if self
._Header
_ == None:
1895 self
._GetHeaderInfo
()
1896 if not self
._BuildType
:
1897 self
._BuildType
= "BASE"
1898 return self
._BuildType
1900 ## Retrieve file guid
1901 def _GetFileGuid(self
):
1902 if self
._Guid
== None:
1903 if self
._Header
_ == None:
1904 self
._GetHeaderInfo
()
1905 if self
._Guid
== None:
1906 self
._Guid
= '00000000-0000-0000-000000000000'
1909 ## Retrieve module version
1910 def _GetVersion(self
):
1911 if self
._Version
== None:
1912 if self
._Header
_ == None:
1913 self
._GetHeaderInfo
()
1914 if self
._Version
== None:
1915 self
._Version
= '0.0'
1916 return self
._Version
1918 ## Retrieve PCD_IS_DRIVER
1919 def _GetPcdIsDriver(self
):
1920 if self
._PcdIsDriver
== None:
1921 if self
._Header
_ == None:
1922 self
._GetHeaderInfo
()
1923 if self
._PcdIsDriver
== None:
1924 self
._PcdIsDriver
= ''
1925 return self
._PcdIsDriver
1928 def _GetShadow(self
):
1929 if self
._Shadow
== None:
1930 if self
._Header
_ == None:
1931 self
._GetHeaderInfo
()
1932 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1935 self
._Shadow
= False
1938 ## Retrieve CUSTOM_MAKEFILE
1939 def _GetMakefile(self
):
1940 if self
._CustomMakefile
== None:
1941 if self
._Header
_ == None:
1942 self
._GetHeaderInfo
()
1943 if self
._CustomMakefile
== None:
1944 self
._CustomMakefile
= {}
1945 return self
._CustomMakefile
1947 ## Retrieve EFI_SPECIFICATION_VERSION
1949 if self
._Specification
== None:
1950 if self
._Header
_ == None:
1951 self
._GetHeaderInfo
()
1952 if self
._Specification
== None:
1953 self
._Specification
= {}
1954 return self
._Specification
1956 ## Retrieve LIBRARY_CLASS
1957 def _GetLibraryClass(self
):
1958 if self
._LibraryClass
== None:
1959 if self
._Header
_ == None:
1960 self
._GetHeaderInfo
()
1961 if self
._LibraryClass
== None:
1962 self
._LibraryClass
= []
1963 return self
._LibraryClass
1965 ## Retrieve ENTRY_POINT
1966 def _GetEntryPoint(self
):
1967 if self
._ModuleEntryPointList
== None:
1968 if self
._Header
_ == None:
1969 self
._GetHeaderInfo
()
1970 if self
._ModuleEntryPointList
== None:
1971 self
._ModuleEntryPointList
= []
1972 return self
._ModuleEntryPointList
1974 ## Retrieve UNLOAD_IMAGE
1975 def _GetUnloadImage(self
):
1976 if self
._ModuleUnloadImageList
== None:
1977 if self
._Header
_ == None:
1978 self
._GetHeaderInfo
()
1979 if self
._ModuleUnloadImageList
== None:
1980 self
._ModuleUnloadImageList
= []
1981 return self
._ModuleUnloadImageList
1983 ## Retrieve CONSTRUCTOR
1984 def _GetConstructor(self
):
1985 if self
._ConstructorList
== None:
1986 if self
._Header
_ == None:
1987 self
._GetHeaderInfo
()
1988 if self
._ConstructorList
== None:
1989 self
._ConstructorList
= []
1990 return self
._ConstructorList
1992 ## Retrieve DESTRUCTOR
1993 def _GetDestructor(self
):
1994 if self
._DestructorList
== None:
1995 if self
._Header
_ == None:
1996 self
._GetHeaderInfo
()
1997 if self
._DestructorList
== None:
1998 self
._DestructorList
= []
1999 return self
._DestructorList
2001 ## Retrieve definies other than above ones
2002 def _GetDefines(self
):
2003 if self
._Defs
== None:
2004 if self
._Header
_ == None:
2005 self
._GetHeaderInfo
()
2006 if self
._Defs
== None:
2007 self
._Defs
= sdict()
2010 ## Retrieve binary files
2011 def _GetBinaryFiles(self
):
2012 if self
._Binaries
== None:
2014 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2015 Macros
= self
._Macros
2016 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2017 Macros
['PROCESSOR'] = self
._Arch
2018 for Record
in RecordList
:
2019 FileType
= Record
[0]
2024 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2026 Target
= TokenList
[0]
2027 if len(TokenList
) > 1:
2028 FeatureFlag
= Record
[1:]
2030 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2031 # check the file validation
2032 ErrorCode
, ErrorInfo
= File
.Validate()
2034 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2035 self
._Binaries
.append(File
)
2036 return self
._Binaries
2038 ## Retrieve source files
2039 def _GetSourceFiles(self
):
2040 if self
._Sources
== None:
2042 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2043 Macros
= self
._Macros
2044 for Record
in RecordList
:
2046 ToolChainFamily
= Record
[1]
2048 ToolCode
= Record
[3]
2049 FeatureFlag
= Record
[4]
2050 if self
.AutoGenVersion
< 0x00010005:
2051 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2052 Macros
['PROCESSOR'] = self
._Arch
2053 # old module source files (Edk)
2054 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
2055 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2056 # check the file validation
2057 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2059 if File
.Ext
.lower() == '.h':
2060 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2061 File
=self
.MetaFile
, Line
=LineNo
)
2064 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2066 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2067 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2068 # check the file validation
2069 ErrorCode
, ErrorInfo
= File
.Validate()
2071 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2073 self
._Sources
.append(File
)
2074 return self
._Sources
2076 ## Retrieve library classes employed by this module
2077 def _GetLibraryClassUses(self
):
2078 if self
._LibraryClasses
== None:
2079 self
._LibraryClasses
= sdict()
2080 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2081 for Record
in RecordList
:
2083 Instance
= Record
[1]
2085 Instance
= NormPath(Instance
, self
._Macros
)
2086 self
._LibraryClasses
[Lib
] = Instance
2087 return self
._LibraryClasses
2089 ## Retrieve library names (for Edk.x style of modules)
2090 def _GetLibraryNames(self
):
2091 if self
._Libraries
== None:
2092 self
._Libraries
= []
2093 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2094 for Record
in RecordList
:
2095 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2096 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2097 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2098 if LibraryName
not in self
._Libraries
:
2099 self
._Libraries
.append(LibraryName
)
2100 return self
._Libraries
2102 def _GetProtocolComments(self
):
2103 self
._GetProtocols
()
2104 return self
._ProtocolComments
2105 ## Retrieve protocols consumed/produced by this module
2106 def _GetProtocols(self
):
2107 if self
._Protocols
== None:
2108 self
._Protocols
= sdict()
2109 self
._ProtocolComments
= sdict()
2110 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2111 for Record
in RecordList
:
2113 Value
= ProtocolValue(CName
, self
.Packages
)
2115 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2116 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2117 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2118 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2119 self
._Protocols
[CName
] = Value
2120 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2122 for CmtRec
in CommentRecords
:
2123 Comments
.append(CmtRec
[0])
2124 self
._ProtocolComments
[CName
] = Comments
2125 return self
._Protocols
2127 def _GetPpiComments(self
):
2129 return self
._PpiComments
2130 ## Retrieve PPIs consumed/produced by this module
2132 if self
._Ppis
== None:
2133 self
._Ppis
= sdict()
2134 self
._PpiComments
= sdict()
2135 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2136 for Record
in RecordList
:
2138 Value
= PpiValue(CName
, self
.Packages
)
2140 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2141 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2142 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2143 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2144 self
._Ppis
[CName
] = Value
2145 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2147 for CmtRec
in CommentRecords
:
2148 Comments
.append(CmtRec
[0])
2149 self
._PpiComments
[CName
] = Comments
2152 def _GetGuidComments(self
):
2154 return self
._GuidComments
2155 ## Retrieve GUIDs consumed/produced by this module
2156 def _GetGuids(self
):
2157 if self
._Guids
== None:
2158 self
._Guids
= sdict()
2159 self
._GuidComments
= sdict()
2160 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2161 for Record
in RecordList
:
2163 Value
= GuidValue(CName
, self
.Packages
)
2165 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2166 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2167 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2168 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2169 self
._Guids
[CName
] = Value
2170 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2172 for CmtRec
in CommentRecords
:
2173 Comments
.append(CmtRec
[0])
2174 self
._GuidComments
[CName
] = Comments
2177 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2178 def _GetIncludes(self
):
2179 if self
._Includes
== None:
2181 if self
._SourceOverridePath
:
2182 self
._Includes
.append(self
._SourceOverridePath
)
2184 Macros
= self
._Macros
2185 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2186 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2188 Macros
['PROCESSOR'] = self
._Arch
2189 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2190 for Record
in RecordList
:
2191 if Record
[0].find('EDK_SOURCE') > -1:
2192 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2193 File
= NormPath(Record
[0], self
._Macros
)
2195 File
= os
.path
.join(self
._ModuleDir
, File
)
2197 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2198 File
= RealPath(os
.path
.normpath(File
))
2200 self
._Includes
.append(File
)
2202 #TRICK: let compiler to choose correct header file
2203 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2204 File
= NormPath(Record
[0], self
._Macros
)
2206 File
= os
.path
.join(self
._ModuleDir
, File
)
2208 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2209 File
= RealPath(os
.path
.normpath(File
))
2211 self
._Includes
.append(File
)
2213 File
= NormPath(Record
[0], Macros
)
2215 File
= os
.path
.join(self
._ModuleDir
, File
)
2217 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2218 File
= RealPath(os
.path
.normpath(File
))
2220 self
._Includes
.append(File
)
2221 return self
._Includes
2223 ## Retrieve packages this module depends on
2224 def _GetPackages(self
):
2225 if self
._Packages
== None:
2227 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2228 Macros
= self
._Macros
2229 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2230 for Record
in RecordList
:
2231 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2233 # check the file validation
2234 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2236 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2237 # parse this package now. we need it to get protocol/ppi/guid value
2238 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2239 self
._Packages
.append(Package
)
2240 return self
._Packages
2242 ## Retrieve PCD comments
2243 def _GetPcdComments(self
):
2245 return self
._PcdComments
2246 ## Retrieve PCDs used in this module
2248 if self
._Pcds
== None:
2249 self
._Pcds
= sdict()
2250 self
._PcdComments
= sdict()
2251 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2252 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2253 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2254 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2255 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2258 ## Retrieve build options specific to this module
2259 def _GetBuildOptions(self
):
2260 if self
._BuildOptions
== None:
2261 self
._BuildOptions
= sdict()
2262 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2263 for Record
in RecordList
:
2264 ToolChainFamily
= Record
[0]
2265 ToolChain
= Record
[1]
2267 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2268 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2270 # concatenate the option string if they're for the same tool
2271 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2272 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2273 return self
._BuildOptions
2275 ## Retrieve dependency expression
2276 def _GetDepex(self
):
2277 if self
._Depex
== None:
2278 self
._Depex
= tdict(False, 2)
2279 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2281 # If the module has only Binaries and no Sources, then ignore [Depex]
2282 if self
.Sources
== None or self
.Sources
== []:
2283 if self
.Binaries
!= None and self
.Binaries
!= []:
2286 # PEIM and DXE drivers must have a valid [Depex] section
2287 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2288 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2289 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2290 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2291 % self
.ModuleType
, File
=self
.MetaFile
)
2294 for Record
in RecordList
:
2295 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2297 ModuleType
= Record
[4]
2298 TokenList
= DepexStr
.split()
2299 if (Arch
, ModuleType
) not in Depex
:
2300 Depex
[Arch
, ModuleType
] = []
2301 DepexList
= Depex
[Arch
, ModuleType
]
2302 for Token
in TokenList
:
2303 if Token
in DEPEX_SUPPORTED_OPCODE
:
2304 DepexList
.append(Token
)
2305 elif Token
.endswith(".inf"): # module file name
2306 ModuleFile
= os
.path
.normpath(Token
)
2307 Module
= self
.BuildDatabase
[ModuleFile
]
2309 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2310 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2311 DepexList
.append(Module
.Guid
)
2313 # get the GUID value now
2314 Value
= ProtocolValue(Token
, self
.Packages
)
2316 Value
= PpiValue(Token
, self
.Packages
)
2318 Value
= GuidValue(Token
, self
.Packages
)
2320 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2321 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2322 "Value of [%s] is not found in" % Token
,
2323 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2324 DepexList
.append(Value
)
2325 for Arch
, ModuleType
in Depex
:
2326 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2329 ## Retrieve depedency expression
2330 def _GetDepexExpression(self
):
2331 if self
._DepexExpression
== None:
2332 self
._DepexExpression
= tdict(False, 2)
2333 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2334 DepexExpression
= sdict()
2335 for Record
in RecordList
:
2336 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2338 ModuleType
= Record
[4]
2339 TokenList
= DepexStr
.split()
2340 if (Arch
, ModuleType
) not in DepexExpression
:
2341 DepexExpression
[Arch
, ModuleType
] = ''
2342 for Token
in TokenList
:
2343 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2344 for Arch
, ModuleType
in DepexExpression
:
2345 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2346 return self
._DepexExpression
2348 def GetGuidsUsedByPcd(self
):
2349 return self
._GuidsUsedByPcd
2350 ## Retrieve PCD for given type
2351 def _GetPcd(self
, Type
):
2353 PcdDict
= tdict(True, 4)
2355 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2356 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2357 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2358 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2359 # get the guid value
2360 if TokenSpaceGuid
not in self
.Guids
:
2361 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2363 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2364 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2365 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2366 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2367 self
.Guids
[TokenSpaceGuid
] = Value
2368 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2369 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2371 for CmtRec
in CommentRecords
:
2372 Comments
.append(CmtRec
[0])
2373 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2375 # resolve PCD type, value, datum info, etc. by getting its definition from package
2376 for PcdCName
, TokenSpaceGuid
in PcdList
:
2377 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2380 ValueList
= AnalyzePcdData(Setting
)
2381 DefaultValue
= ValueList
[0]
2382 Pcd
= PcdClassObject(
2392 self
.Guids
[TokenSpaceGuid
]
2394 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2395 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2396 Pcd
.Offset
= ValueList
[1]
2398 # get necessary info from package declaring this PCD
2399 for Package
in self
.Packages
:
2401 # 'dynamic' in INF means its type is determined by platform;
2402 # if platform doesn't give its type, use 'lowest' one in the
2403 # following order, if any
2405 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2407 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2408 if Type
== MODEL_PCD_DYNAMIC
:
2410 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2411 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2417 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2418 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2420 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2423 # Check whether the token value exist or not.
2425 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2429 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2430 File
=self
.MetaFile
, Line
=LineNo
,
2434 # Check hexadecimal token value length and format.
2436 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2437 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2438 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2442 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2443 File
=self
.MetaFile
, Line
=LineNo
,
2448 # Check decimal token value length and format.
2452 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2453 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2457 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!"% (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2458 File
=self
.MetaFile
, Line
=LineNo
,
2465 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!"% (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2466 File
=self
.MetaFile
, Line
=LineNo
,
2470 Pcd
.DatumType
= PcdInPackage
.DatumType
2471 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2472 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2473 if Pcd
.DefaultValue
in [None, '']:
2474 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2480 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2481 File
=self
.MetaFile
, Line
=LineNo
,
2482 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2484 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2488 ## check whether current module is binary module
2489 def _IsBinaryModule(self
):
2490 if self
.Binaries
and not self
.Sources
:
2492 elif GlobalData
.gIgnoreSource
:
2497 _Macros
= property(_GetMacros
)
2498 Arch
= property(_GetArch
, _SetArch
)
2499 Platform
= property(_GetPlatform
, _SetPlatform
)
2501 HeaderComments
= property(_GetHeaderComments
)
2502 TailComments
= property(_GetTailComments
)
2503 AutoGenVersion
= property(_GetInfVersion
)
2504 BaseName
= property(_GetBaseName
)
2505 ModuleType
= property(_GetModuleType
)
2506 ComponentType
= property(_GetComponentType
)
2507 BuildType
= property(_GetBuildType
)
2508 Guid
= property(_GetFileGuid
)
2509 Version
= property(_GetVersion
)
2510 PcdIsDriver
= property(_GetPcdIsDriver
)
2511 Shadow
= property(_GetShadow
)
2512 CustomMakefile
= property(_GetMakefile
)
2513 Specification
= property(_GetSpec
)
2514 LibraryClass
= property(_GetLibraryClass
)
2515 ModuleEntryPointList
= property(_GetEntryPoint
)
2516 ModuleUnloadImageList
= property(_GetUnloadImage
)
2517 ConstructorList
= property(_GetConstructor
)
2518 DestructorList
= property(_GetDestructor
)
2519 Defines
= property(_GetDefines
)
2520 DxsFile
= property(_GetDxsFile
)
2522 Binaries
= property(_GetBinaryFiles
)
2523 Sources
= property(_GetSourceFiles
)
2524 LibraryClasses
= property(_GetLibraryClassUses
)
2525 Libraries
= property(_GetLibraryNames
)
2526 Protocols
= property(_GetProtocols
)
2527 ProtocolComments
= property(_GetProtocolComments
)
2528 Ppis
= property(_GetPpis
)
2529 PpiComments
= property(_GetPpiComments
)
2530 Guids
= property(_GetGuids
)
2531 GuidComments
= property(_GetGuidComments
)
2532 Includes
= property(_GetIncludes
)
2533 Packages
= property(_GetPackages
)
2534 Pcds
= property(_GetPcds
)
2535 PcdComments
= property(_GetPcdComments
)
2536 BuildOptions
= property(_GetBuildOptions
)
2537 Depex
= property(_GetDepex
)
2538 DepexExpression
= property(_GetDepexExpression
)
2539 IsBinaryModule
= property(_IsBinaryModule
)
2543 # This class defined the build database for all modules, packages and platform.
2544 # It will call corresponding parser for the given file if it cannot find it in
2547 # @param DbPath Path of database file
2548 # @param GlobalMacros Global macros used for replacement during file parsing
2549 # @prarm RenewDb=False Create new database file if it's already there
2551 class WorkspaceDatabase(object):
2553 # default database file path
2554 _DB_PATH_
= "Conf/.cache/build.db"
2557 # internal class used for call corresponding file parser and caching the result
2558 # to avoid unnecessary re-parsing
2560 class BuildObjectFactory(object):
2563 ".inf" : MODEL_FILE_INF
,
2564 ".dec" : MODEL_FILE_DEC
,
2565 ".dsc" : MODEL_FILE_DSC
,
2570 MODEL_FILE_INF
: InfParser
,
2571 MODEL_FILE_DEC
: DecParser
,
2572 MODEL_FILE_DSC
: DscParser
,
2575 # convert to xxxBuildData object
2577 MODEL_FILE_INF
: InfBuildData
,
2578 MODEL_FILE_DEC
: DecBuildData
,
2579 MODEL_FILE_DSC
: DscBuildData
,
2582 _CACHE_
= {} # (FilePath, Arch) : <object>
2585 def __init__(self
, WorkspaceDb
):
2586 self
.WorkspaceDb
= WorkspaceDb
2588 # key = (FilePath, Arch=None)
2589 def __contains__(self
, Key
):
2595 return (FilePath
, Arch
) in self
._CACHE
_
2597 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2598 def __getitem__(self
, Key
):
2600 KeyLength
= len(Key
)
2614 # if it's generated before, just return the cached one
2615 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2616 if Key
in self
._CACHE
_:
2617 return self
._CACHE
_[Key
]
2621 if Ext
not in self
._FILE
_TYPE
_:
2623 FileType
= self
._FILE
_TYPE
_[Ext
]
2624 if FileType
not in self
._GENERATOR
_:
2627 # get the parser ready for this file
2628 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2631 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2633 # alwasy do post-process, in case of macros change
2634 MetaFile
.DoPostProcess()
2635 # object the build is based on
2636 BuildObject
= self
._GENERATOR
_[FileType
](
2644 self
._CACHE
_[Key
] = BuildObject
2647 # placeholder for file format conversion
2648 class TransformObjectFactory
:
2649 def __init__(self
, WorkspaceDb
):
2650 self
.WorkspaceDb
= WorkspaceDb
2652 # key = FilePath, Arch
2653 def __getitem__(self
, Key
):
2656 ## Constructor of WorkspaceDatabase
2658 # @param DbPath Path of database file
2659 # @param GlobalMacros Global macros used for replacement during file parsing
2660 # @prarm RenewDb=False Create new database file if it's already there
2662 def __init__(self
, DbPath
, RenewDb
=False):
2663 self
._DbClosedFlag
= False
2665 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2667 # don't create necessary path for db in memory
2668 if DbPath
!= ':memory:':
2669 DbDir
= os
.path
.split(DbPath
)[0]
2670 if not os
.path
.exists(DbDir
):
2673 # remove db file in case inconsistency between db and file in file system
2674 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2677 # create db with optimized parameters
2678 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2679 self
.Conn
.execute("PRAGMA synchronous=OFF")
2680 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2681 self
.Conn
.execute("PRAGMA count_changes=OFF")
2682 self
.Conn
.execute("PRAGMA cache_size=8192")
2683 #self.Conn.execute("PRAGMA page_size=8192")
2685 # to avoid non-ascii character conversion issue
2686 self
.Conn
.text_factory
= str
2687 self
.Cur
= self
.Conn
.cursor()
2689 # create table for internal uses
2690 self
.TblDataModel
= TableDataModel(self
.Cur
)
2691 self
.TblFile
= TableFile(self
.Cur
)
2692 self
.Platform
= None
2694 # conversion object for build or file format conversion purpose
2695 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2696 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2698 ## Check whether workspace database need to be renew.
2699 # The renew reason maybe:
2700 # 1) If user force to renew;
2701 # 2) If user do not force renew, and
2702 # a) If the time of last modified python source is newer than database file;
2703 # b) If the time of last modified frozen executable file is newer than database file;
2705 # @param force User force renew database
2706 # @param DbPath The absolute path of workspace database file
2708 # @return Bool value for whether need renew workspace databse
2710 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2711 # if database does not exist, we need do nothing
2712 if not os
.path
.exists(DbPath
): return False
2714 # if user force to renew database, then not check whether database is out of date
2715 if force
: return True
2718 # Check the time of last modified source file or build.exe
2719 # if is newer than time of database, then database need to be re-created.
2721 timeOfToolModified
= 0
2722 if hasattr(sys
, "frozen"):
2723 exePath
= os
.path
.abspath(sys
.executable
)
2724 timeOfToolModified
= os
.stat(exePath
).st_mtime
2726 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2727 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2728 if rootPath
== "" or rootPath
== None:
2729 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2730 determine whether database file is out of date!\n")
2732 # walk the root path of source or build's binary to get the time last modified.
2734 for root
, dirs
, files
in os
.walk (rootPath
):
2736 # bypass source control folder
2737 if dir.lower() in [".svn", "_svn", "cvs"]:
2741 ext
= os
.path
.splitext(file)[1]
2742 if ext
.lower() == ".py": # only check .py files
2743 fd
= os
.stat(os
.path
.join(root
, file))
2744 if timeOfToolModified
< fd
.st_mtime
:
2745 timeOfToolModified
= fd
.st_mtime
2746 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2747 EdkLogger
.verbose("\nWorkspace database is out of data!")
2752 ## Initialize build database
2753 def InitDatabase(self
):
2754 EdkLogger
.verbose("\nInitialize build database started ...")
2759 self
.TblDataModel
.Create(False)
2760 self
.TblFile
.Create(False)
2763 # Initialize table DataModel
2765 self
.TblDataModel
.InitTable()
2766 EdkLogger
.verbose("Initialize build database ... DONE!")
2770 # @param Table: The instance of the table to be queried
2772 def QueryTable(self
, Table
):
2778 ## Close entire database
2781 # Close the connection and cursor
2784 if not self
._DbClosedFlag
:
2788 self
._DbClosedFlag
= True
2790 ## Summarize all packages in the database
2791 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2792 self
.Platform
= Platform
2794 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2796 # Get Package related to Modules
2798 for Module
in Pa
.Modules
:
2799 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2800 for Package
in ModuleObj
.Packages
:
2801 if Package
not in PackageList
:
2802 PackageList
.append(Package
)
2804 # Get Packages related to Libraries
2806 for Lib
in Pa
.LibraryInstances
:
2807 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2808 for Package
in LibObj
.Packages
:
2809 if Package
not in PackageList
:
2810 PackageList
.append(Package
)
2814 ## Summarize all platforms in the database
2815 def _GetPlatformList(self
):
2817 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2819 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2822 if Platform
!= None:
2823 PlatformList
.append(Platform
)
2826 PlatformList
= property(_GetPlatformList
)
2830 # This acts like the main() function for the script, unless it is 'import'ed into another
2833 if __name__
== '__main__':