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.
23 import Common
.EdkLogger
as EdkLogger
24 import Common
.GlobalData
as GlobalData
26 from Common
.String
import *
27 from Common
.DataType
import *
28 from Common
.Misc
import *
31 from CommonDataClass
.CommonClass
import SkuInfoClass
33 from MetaDataTable
import *
34 from MetaFileTable
import *
35 from MetaFileParser
import *
36 from BuildClassObject
import *
37 from WorkspaceCommon
import GetDeclaredPcd
38 from Common
.Misc
import AnalyzeDscPcd
40 from Common
.Parsing
import IsValidWord
42 ## Platform build information from DSC file
44 # This class is used to retrieve information stored in database and convert them
45 # into PlatformBuildClassObject form for easier use for AutoGen.
47 class DscBuildData(PlatformBuildClassObject
):
48 # dict used to convert PCD type in database to string used by build tool
50 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
51 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
52 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
53 MODEL_PCD_DYNAMIC
: "Dynamic",
54 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
55 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
56 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
57 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
58 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
59 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
60 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
63 # dict used to convert part of [Defines] to members of DscBuildData directly
68 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
69 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
70 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
71 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
72 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
73 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
74 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
75 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
76 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
77 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
78 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
79 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
80 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
81 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
82 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
85 # used to compose dummy library class name for those forced library instances
86 _NullLibraryNumber
= 0
88 ## Constructor of DscBuildData
90 # Initialize object of DscBuildData
92 # @param FilePath The path of platform description file
93 # @param RawData The raw data of DSC file
94 # @param BuildDataBase Database used to retrieve module/package information
95 # @param Arch The target architecture
96 # @param Platform (not used for DscBuildData)
97 # @param Macros Macros used for replacement in DSC file
99 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
100 self
.MetaFile
= FilePath
101 self
._RawData
= RawData
102 self
._Bdb
= BuildDataBase
104 self
._Target
= Target
105 self
._Toolchain
= Toolchain
109 def __setitem__(self
, key
, value
):
110 self
.__dict
__[self
._PROPERTY
_[key
]] = value
113 def __getitem__(self
, key
):
114 return self
.__dict
__[self
._PROPERTY
_[key
]]
117 def __contains__(self
, key
):
118 return key
in self
._PROPERTY
_
120 ## Set all internal used members of DscBuildData to None
123 self
._PlatformName
= None
126 self
._DscSpecification
= None
127 self
._OutputDirectory
= None
128 self
._SupArchList
= None
129 self
._BuildTargets
= None
131 self
._SkuIdentifier
= None
132 self
._PcdInfoFlag
= None
133 self
._FlashDefinition
= None
134 self
._BuildNumber
= None
135 self
._MakefileName
= None
136 self
._BsBaseAddress
= None
137 self
._RtBaseAddress
= None
140 self
._LibraryInstances
= None
141 self
._LibraryClasses
= None
144 self
._BuildOptions
= None
145 self
._LoadFixAddress
= None
146 self
._RFCLanguages
= None
147 self
._ISOLanguages
= None
148 self
._VpdToolGuid
= None
151 ## Get current effective macros
152 def _GetMacros(self
):
153 if self
.__Macros
== None:
155 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
156 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
157 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
166 # Changing the default ARCH to another may affect all other information
167 # because all information in a platform may be ARCH-related. That's
168 # why we need to clear all internal used members, in order to cause all
169 # information to be re-retrieved.
171 # @param Value The value of ARCH
173 def _SetArch(self
, Value
):
174 if self
._Arch
== Value
:
179 ## Retrieve all information in [Defines] section
181 # (Retriving all [Defines] information in one-shot is just to save time.)
183 def _GetHeaderInfo(self
):
184 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
185 for Record
in RecordList
:
187 # items defined _PROPERTY_ don't need additional processing
189 # some special items in [Defines] section need special treatment
190 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
191 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
192 if ' ' in self
._OutputDirectory
:
193 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
194 File
=self
.MetaFile
, Line
=Record
[-1],
195 ExtraData
=self
._OutputDirectory
)
196 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
197 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
198 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
200 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
202 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
203 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
204 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
205 self
._BuildTargets
= GetSplitValueList(Record
[2])
206 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
207 if self
._SkuName
== None:
208 self
._SkuName
= Record
[2]
209 self
._SkuIdentifier
= Record
[2]
210 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
211 self
._PcdInfoFlag
= Record
[2]
212 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
214 self
._LoadFixAddress
= int (Record
[2], 0)
216 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
217 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
218 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
219 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"',
220 File
=self
.MetaFile
, Line
=Record
[-1])
221 LanguageCodes
= Record
[2][1:-1]
222 if not LanguageCodes
:
223 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
224 File
=self
.MetaFile
, Line
=Record
[-1])
225 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
226 # check whether there is empty entries in the list
227 if None in LanguageList
:
228 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
229 File
=self
.MetaFile
, Line
=Record
[-1])
230 self
._RFCLanguages
= LanguageList
231 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
232 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
233 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
234 File
=self
.MetaFile
, Line
=Record
[-1])
235 LanguageCodes
= Record
[2][1:-1]
236 if not LanguageCodes
:
237 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
238 File
=self
.MetaFile
, Line
=Record
[-1])
239 if len(LanguageCodes
)%3:
240 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
241 File
=self
.MetaFile
, Line
=Record
[-1])
243 for i
in range(0, len(LanguageCodes
), 3):
244 LanguageList
.append(LanguageCodes
[i
:i
+3])
245 self
._ISOLanguages
= LanguageList
246 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
248 # try to convert GUID to a real UUID value to see whether the GUID is format
249 # for VPD_TOOL_GUID is correct.
254 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
255 self
._VpdToolGuid
= Record
[2]
257 self
[Name
] = Record
[2]
258 # set _Header to non-None in order to avoid database re-querying
259 self
._Header
= 'DUMMY'
261 ## Retrieve platform name
262 def _GetPlatformName(self
):
263 if self
._PlatformName
== None:
264 if self
._Header
== None:
265 self
._GetHeaderInfo
()
266 if self
._PlatformName
== None:
267 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
268 return self
._PlatformName
270 ## Retrieve file guid
271 def _GetFileGuid(self
):
272 if self
._Guid
== None:
273 if self
._Header
== None:
274 self
._GetHeaderInfo
()
275 if self
._Guid
== None:
276 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
279 ## Retrieve platform version
280 def _GetVersion(self
):
281 if self
._Version
== None:
282 if self
._Header
== None:
283 self
._GetHeaderInfo
()
284 if self
._Version
== None:
285 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
288 ## Retrieve platform description file version
289 def _GetDscSpec(self
):
290 if self
._DscSpecification
== None:
291 if self
._Header
== None:
292 self
._GetHeaderInfo
()
293 if self
._DscSpecification
== None:
294 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
295 return self
._DscSpecification
297 ## Retrieve OUTPUT_DIRECTORY
298 def _GetOutpuDir(self
):
299 if self
._OutputDirectory
== None:
300 if self
._Header
== None:
301 self
._GetHeaderInfo
()
302 if self
._OutputDirectory
== None:
303 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
304 return self
._OutputDirectory
306 ## Retrieve SUPPORTED_ARCHITECTURES
307 def _GetSupArch(self
):
308 if self
._SupArchList
== None:
309 if self
._Header
== None:
310 self
._GetHeaderInfo
()
311 if self
._SupArchList
== None:
312 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
313 return self
._SupArchList
315 ## Retrieve BUILD_TARGETS
316 def _GetBuildTarget(self
):
317 if self
._BuildTargets
== None:
318 if self
._Header
== None:
319 self
._GetHeaderInfo
()
320 if self
._BuildTargets
== None:
321 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
322 return self
._BuildTargets
324 def _GetPcdInfoFlag(self
):
325 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
327 elif self
._PcdInfoFlag
.upper() == 'TRUE':
332 def _GetSkuIdentifier(self
):
335 if self
._SkuIdentifier
== None:
336 if self
._Header
== None:
337 self
._GetHeaderInfo
()
338 return self
._SkuIdentifier
339 ## Retrieve SKUID_IDENTIFIER
340 def _GetSkuName(self
):
341 if self
._SkuName
== None:
342 if self
._Header
== None:
343 self
._GetHeaderInfo
()
344 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
345 self
._SkuName
= 'DEFAULT'
348 ## Override SKUID_IDENTIFIER
349 def _SetSkuName(self
, Value
):
350 self
._SkuName
= Value
353 def _GetFdfFile(self
):
354 if self
._FlashDefinition
== None:
355 if self
._Header
== None:
356 self
._GetHeaderInfo
()
357 if self
._FlashDefinition
== None:
358 self
._FlashDefinition
= ''
359 return self
._FlashDefinition
361 ## Retrieve FLASH_DEFINITION
362 def _GetBuildNumber(self
):
363 if self
._BuildNumber
== None:
364 if self
._Header
== None:
365 self
._GetHeaderInfo
()
366 if self
._BuildNumber
== None:
367 self
._BuildNumber
= ''
368 return self
._BuildNumber
370 ## Retrieve MAKEFILE_NAME
371 def _GetMakefileName(self
):
372 if self
._MakefileName
== None:
373 if self
._Header
== None:
374 self
._GetHeaderInfo
()
375 if self
._MakefileName
== None:
376 self
._MakefileName
= ''
377 return self
._MakefileName
379 ## Retrieve BsBaseAddress
380 def _GetBsBaseAddress(self
):
381 if self
._BsBaseAddress
== None:
382 if self
._Header
== None:
383 self
._GetHeaderInfo
()
384 if self
._BsBaseAddress
== None:
385 self
._BsBaseAddress
= ''
386 return self
._BsBaseAddress
388 ## Retrieve RtBaseAddress
389 def _GetRtBaseAddress(self
):
390 if self
._RtBaseAddress
== None:
391 if self
._Header
== None:
392 self
._GetHeaderInfo
()
393 if self
._RtBaseAddress
== None:
394 self
._RtBaseAddress
= ''
395 return self
._RtBaseAddress
397 ## Retrieve the top address for the load fix address
398 def _GetLoadFixAddress(self
):
399 if self
._LoadFixAddress
== None:
400 if self
._Header
== None:
401 self
._GetHeaderInfo
()
403 if self
._LoadFixAddress
== None:
404 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
407 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
409 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
412 # If command line defined, should override the value in DSC file.
414 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
416 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
418 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']))
420 if self
._LoadFixAddress
< 0:
421 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
422 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
423 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
425 return self
._LoadFixAddress
427 ## Retrieve RFCLanguage filter
428 def _GetRFCLanguages(self
):
429 if self
._RFCLanguages
== None:
430 if self
._Header
== None:
431 self
._GetHeaderInfo
()
432 if self
._RFCLanguages
== None:
433 self
._RFCLanguages
= []
434 return self
._RFCLanguages
436 ## Retrieve ISOLanguage filter
437 def _GetISOLanguages(self
):
438 if self
._ISOLanguages
== None:
439 if self
._Header
== None:
440 self
._GetHeaderInfo
()
441 if self
._ISOLanguages
== None:
442 self
._ISOLanguages
= []
443 return self
._ISOLanguages
444 ## Retrieve the GUID string for VPD tool
445 def _GetVpdToolGuid(self
):
446 if self
._VpdToolGuid
== None:
447 if self
._Header
== None:
448 self
._GetHeaderInfo
()
449 if self
._VpdToolGuid
== None:
450 self
._VpdToolGuid
= ''
451 return self
._VpdToolGuid
453 ## Retrieve [SkuIds] section information
454 def _GetSkuIds(self
):
455 if self
._SkuIds
== None:
456 self
._SkuIds
= sdict()
457 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
458 for Record
in RecordList
:
459 if Record
[0] in [None, '']:
460 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
461 File
=self
.MetaFile
, Line
=Record
[-1])
462 if Record
[1] in [None, '']:
463 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
464 File
=self
.MetaFile
, Line
=Record
[-1])
465 self
._SkuIds
[Record
[1]] = Record
[0]
466 if 'DEFAULT' not in self
._SkuIds
:
467 self
._SkuIds
['DEFAULT'] = '0'
468 if 'COMMON' not in self
._SkuIds
:
469 self
._SkuIds
['COMMON'] = '0'
472 ## Retrieve [Components] section information
473 def _GetModules(self
):
474 if self
._Modules
!= None:
477 self
._Modules
= sdict()
478 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
479 Macros
= self
._Macros
480 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
481 for Record
in RecordList
:
482 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
486 # check the file validation
487 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
489 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
492 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
493 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
494 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
496 Module
= ModuleBuildClassObject()
497 Module
.MetaFile
= ModuleFile
499 # get module override path
500 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
502 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
504 # Check if the source override path exists
505 if not os
.path
.isdir(Module
.SourceOverridePath
):
506 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
508 #Add to GlobalData Variables
509 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
511 # get module private library instance
512 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
513 for Record
in RecordList
:
514 LibraryClass
= Record
[0]
515 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
518 # check the file validation
519 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
521 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
524 if LibraryClass
== '' or LibraryClass
== 'NULL':
525 self
._NullLibraryNumber
+= 1
526 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
527 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
528 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
529 if LibraryPath
not in self
.LibraryInstances
:
530 self
.LibraryInstances
.append(LibraryPath
)
532 # get module private PCD setting
533 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
534 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
535 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
536 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
537 TokenList
= GetSplitValueList(Setting
)
538 DefaultValue
= TokenList
[0]
539 if len(TokenList
) > 1:
540 MaxDatumSize
= TokenList
[1]
543 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
544 Pcd
= PcdClassObject(
556 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
558 # get module private build options
559 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
560 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
561 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
562 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
564 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
565 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
567 self
._Modules
[ModuleFile
] = Module
570 ## Retrieve all possible library instances used in this platform
571 def _GetLibraryInstances(self
):
572 if self
._LibraryInstances
== None:
573 self
._GetLibraryClasses
()
574 return self
._LibraryInstances
576 ## Retrieve [LibraryClasses] information
577 def _GetLibraryClasses(self
):
578 if self
._LibraryClasses
== None:
579 self
._LibraryInstances
= []
581 # tdict is a special dict kind of type, used for selecting correct
582 # library instance for given library class and module type
584 LibraryClassDict
= tdict(True, 3)
585 # track all library class names
586 LibraryClassSet
= set()
587 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
588 Macros
= self
._Macros
589 for Record
in RecordList
:
590 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
591 if LibraryClass
== '' or LibraryClass
== 'NULL':
592 self
._NullLibraryNumber
+= 1
593 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
594 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
595 LibraryClassSet
.add(LibraryClass
)
596 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
597 # check the file validation
598 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
600 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
603 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
604 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
605 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
606 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
607 if LibraryInstance
not in self
._LibraryInstances
:
608 self
._LibraryInstances
.append(LibraryInstance
)
610 # resolve the specific library instance for each class and each module type
611 self
._LibraryClasses
= tdict(True)
612 for LibraryClass
in LibraryClassSet
:
613 # try all possible module types
614 for ModuleType
in SUP_MODULE_LIST
:
615 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
616 if LibraryInstance
== None:
618 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
620 # for Edk style library instances, which are listed in different section
621 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
622 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
623 for Record
in RecordList
:
624 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
626 # check the file validation
627 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
629 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
631 if File
not in self
._LibraryInstances
:
632 self
._LibraryInstances
.append(File
)
634 # we need the module name as the library class name, so we have
635 # to parse it here. (self._Bdb[] will trigger a file parse if it
636 # hasn't been parsed)
638 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
639 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
640 return self
._LibraryClasses
642 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
643 if self
._DecPcds
== None:
644 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
645 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
646 EdkLogger
.error('build', PARSER_ERROR
,
647 "Pcd (%s.%s) defined in DSC is not declared in DEC files." % (TokenSpaceGuid
, PcdCName
),
648 File
=self
.MetaFile
, Line
=LineNo
)
649 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
650 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
651 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
652 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
653 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
655 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
656 except WrnExpression
, Value
:
657 ValueList
[Index
] = Value
.result
658 except EvaluationException
, Excpt
:
659 if hasattr(Excpt
, 'Pcd'):
660 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
661 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
662 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
663 " of the DSC file" % Excpt
.Pcd
,
664 File
=self
.MetaFile
, Line
=LineNo
)
666 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
667 File
=self
.MetaFile
, Line
=LineNo
)
669 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
670 File
=self
.MetaFile
, Line
=LineNo
)
671 if ValueList
[Index
] == 'True':
672 ValueList
[Index
] = '1'
673 elif ValueList
[Index
] == 'False':
674 ValueList
[Index
] = '0'
676 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
678 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
679 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
682 ## Retrieve all PCD settings in platform
684 if self
._Pcds
== None:
686 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
687 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
688 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
689 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
690 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
691 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
692 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
693 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
694 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
697 ## Retrieve [BuildOptions]
698 def _GetBuildOptions(self
):
699 if self
._BuildOptions
== None:
700 self
._BuildOptions
= sdict()
702 # Retrieve build option for EDKII style module
704 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
705 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
706 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
708 # Retrieve build option for EDK style module
710 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
711 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
712 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
713 return self
._BuildOptions
715 ## Retrieve non-dynamic PCD settings
717 # @param Type PCD type
719 # @retval a dict object contains settings of given PCD type
721 def _GetPcd(self
, Type
):
724 # tdict is a special dict kind of type, used for selecting correct
725 # PCD settings for certain ARCH
728 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
730 PcdDict
= tdict(True, 3)
732 # Find out all possible PCD candidates for self._Arch
733 RecordList
= self
._RawData
[Type
, self
._Arch
]
734 PcdValueDict
= sdict()
735 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
736 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
737 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
738 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
740 #handle pcd value override
741 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
742 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
745 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
746 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
747 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
749 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
751 PcdsKeys
= PcdValueDict
.keys()
752 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
754 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
758 if 'COMMON' in PcdSetting
:
759 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
760 if 'DEFAULT' in PcdSetting
:
761 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
762 if SkuObj
.SystemSkuId
in PcdSetting
:
763 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
765 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
768 self
._PCD
_TYPE
_STRING
_[Type
],
779 ## Retrieve dynamic PCD settings
781 # @param Type PCD type
783 # @retval a dict object contains settings of given PCD type
785 def _GetDynamicPcd(self
, Type
):
787 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
791 # tdict is a special dict kind of type, used for selecting correct
792 # PCD settings for certain ARCH and SKU
794 PcdDict
= tdict(True, 4)
796 # Find out all possible PCD candidates for self._Arch
797 RecordList
= self
._RawData
[Type
, self
._Arch
]
798 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
800 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
801 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
802 if SkuName
not in AvailableSkuIdSet
:
805 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
806 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
807 # Remove redundant PCD candidates, per the ARCH and SKU
808 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
810 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
814 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
815 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
816 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
817 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
818 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
819 if MaxDatumSize
.strip():
820 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
823 if pcdObject
.MaxDatumSize
:
824 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
827 if CurrentMaxSize
> PcdMaxSize
:
828 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
830 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
833 self
._PCD
_TYPE
_STRING
_[Type
],
843 for pcd
in Pcds
.values():
844 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
845 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
846 valuefromDec
= pcdDecObject
.DefaultValue
847 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
848 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
849 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
850 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
851 del(pcd
.SkuInfoList
['COMMON'])
852 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
853 del(pcd
.SkuInfoList
['COMMON'])
854 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
855 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
856 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
857 del(pcd
.SkuInfoList
['DEFAULT'])
861 ## Retrieve dynamic HII PCD settings
863 # @param Type PCD type
865 # @retval a dict object contains settings of given PCD type
867 def _GetDynamicHiiPcd(self
, Type
):
869 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
873 # tdict is a special dict kind of type, used for selecting correct
874 # PCD settings for certain ARCH and SKU
876 PcdDict
= tdict(True, 4)
878 RecordList
= self
._RawData
[Type
, self
._Arch
]
879 # Find out all possible PCD candidates for self._Arch
880 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
882 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
883 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
884 if SkuName
not in AvailableSkuIdSet
:
886 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
887 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
888 # Remove redundant PCD candidates, per the ARCH and SKU
889 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
891 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
894 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
898 if VariableOffset
.isdigit():
899 if int(VariableOffset
,10) > 0xFFFF:
901 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
902 if int(VariableOffset
,16) > 0xFFFF:
904 # For Offset written in "A.B"
905 elif VariableOffset
.find('.') > -1:
906 VariableOffsetList
= VariableOffset
.split(".")
907 if not (len(VariableOffsetList
) == 2
908 and IsValidWord(VariableOffsetList
[0])
909 and IsValidWord(VariableOffsetList
[1])):
910 FormatCorrect
= False
912 FormatCorrect
= False
913 if not FormatCorrect
:
914 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
917 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
919 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
920 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
921 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
922 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
924 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
927 self
._PCD
_TYPE
_STRING
_[Type
],
938 for pcd
in Pcds
.values():
939 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
940 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
941 # Only fix the value while no value provided in DSC file.
942 for sku
in pcd
.SkuInfoList
.values():
943 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
944 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
945 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
946 valuefromDec
= pcdDecObject
.DefaultValue
947 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
948 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
949 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
950 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
951 del(pcd
.SkuInfoList
['COMMON'])
952 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
953 del(pcd
.SkuInfoList
['COMMON'])
955 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
956 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
957 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
958 del(pcd
.SkuInfoList
['DEFAULT'])
961 if pcd
.MaxDatumSize
.strip():
962 MaxSize
= int(pcd
.MaxDatumSize
,0)
965 if pcdDecObject
.DatumType
== 'VOID*':
966 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
968 if skuobj
.HiiDefaultValue
.startswith("L"):
969 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
970 elif skuobj
.HiiDefaultValue
.startswith("{"):
971 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
973 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
976 pcd
.MaxDatumSize
= str(MaxSize
)
979 ## Retrieve dynamic VPD PCD settings
981 # @param Type PCD type
983 # @retval a dict object contains settings of given PCD type
985 def _GetDynamicVpdPcd(self
, Type
):
987 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
991 # tdict is a special dict kind of type, used for selecting correct
992 # PCD settings for certain ARCH and SKU
994 PcdDict
= tdict(True, 4)
996 # Find out all possible PCD candidates for self._Arch
997 RecordList
= self
._RawData
[Type
, self
._Arch
]
998 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1000 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1001 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1002 if SkuName
not in AvailableSkuIdSet
:
1005 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1006 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1007 # Remove redundant PCD candidates, per the ARCH and SKU
1008 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1009 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1013 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1014 # For the Integer & Boolean type, the optional data can only be InitialValue.
1015 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1016 # until the DEC parser has been called.
1018 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1019 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1020 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1021 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1022 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1023 if MaxDatumSize
.strip():
1024 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1027 if pcdObject
.MaxDatumSize
:
1028 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1031 if CurrentMaxSize
> PcdMaxSize
:
1032 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1034 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1037 self
._PCD
_TYPE
_STRING
_[Type
],
1042 {SkuName
: SkuInfo
},
1046 for pcd
in Pcds
.values():
1047 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1048 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1049 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1050 valuefromDec
= pcdDecObject
.DefaultValue
1051 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1052 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1053 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1054 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1055 del(pcd
.SkuInfoList
['COMMON'])
1056 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1057 del(pcd
.SkuInfoList
['COMMON'])
1058 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1059 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1060 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1061 del(pcd
.SkuInfoList
['DEFAULT'])
1065 ## Add external modules
1067 # The external modules are mostly those listed in FDF file, which don't
1070 # @param FilePath The path of module description file
1072 def AddModule(self
, FilePath
):
1073 FilePath
= NormPath(FilePath
)
1074 if FilePath
not in self
.Modules
:
1075 Module
= ModuleBuildClassObject()
1076 Module
.MetaFile
= FilePath
1077 self
.Modules
.append(Module
)
1079 ## Add external PCDs
1081 # The external PCDs are mostly those listed in FDF file to specify address
1082 # or offset information.
1084 # @param Name Name of the PCD
1085 # @param Guid Token space guid of the PCD
1086 # @param Value Value of the PCD
1088 def AddPcd(self
, Name
, Guid
, Value
):
1089 if (Name
, Guid
) not in self
.Pcds
:
1090 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1091 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1093 _Macros
= property(_GetMacros
)
1094 Arch
= property(_GetArch
, _SetArch
)
1095 Platform
= property(_GetPlatformName
)
1096 PlatformName
= property(_GetPlatformName
)
1097 Guid
= property(_GetFileGuid
)
1098 Version
= property(_GetVersion
)
1099 DscSpecification
= property(_GetDscSpec
)
1100 OutputDirectory
= property(_GetOutpuDir
)
1101 SupArchList
= property(_GetSupArch
)
1102 BuildTargets
= property(_GetBuildTarget
)
1103 SkuName
= property(_GetSkuName
, _SetSkuName
)
1104 SkuIdentifier
= property(_GetSkuIdentifier
)
1105 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1106 FlashDefinition
= property(_GetFdfFile
)
1107 BuildNumber
= property(_GetBuildNumber
)
1108 MakefileName
= property(_GetMakefileName
)
1109 BsBaseAddress
= property(_GetBsBaseAddress
)
1110 RtBaseAddress
= property(_GetRtBaseAddress
)
1111 LoadFixAddress
= property(_GetLoadFixAddress
)
1112 RFCLanguages
= property(_GetRFCLanguages
)
1113 ISOLanguages
= property(_GetISOLanguages
)
1114 VpdToolGuid
= property(_GetVpdToolGuid
)
1115 SkuIds
= property(_GetSkuIds
)
1116 Modules
= property(_GetModules
)
1117 LibraryInstances
= property(_GetLibraryInstances
)
1118 LibraryClasses
= property(_GetLibraryClasses
)
1119 Pcds
= property(_GetPcds
)
1120 BuildOptions
= property(_GetBuildOptions
)
1122 ## Platform build information from DEC file
1124 # This class is used to retrieve information stored in database and convert them
1125 # into PackageBuildClassObject form for easier use for AutoGen.
1127 class DecBuildData(PackageBuildClassObject
):
1128 # dict used to convert PCD type in database to string used by build tool
1129 _PCD_TYPE_STRING_
= {
1130 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1131 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1132 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1133 MODEL_PCD_DYNAMIC
: "Dynamic",
1134 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1135 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1136 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1137 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1138 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1139 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1140 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1143 # dict used to convert part of [Defines] to members of DecBuildData directly
1148 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1149 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1150 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1151 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1155 ## Constructor of DecBuildData
1157 # Initialize object of DecBuildData
1159 # @param FilePath The path of package description file
1160 # @param RawData The raw data of DEC file
1161 # @param BuildDataBase Database used to retrieve module information
1162 # @param Arch The target architecture
1163 # @param Platform (not used for DecBuildData)
1164 # @param Macros Macros used for replacement in DSC file
1166 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1167 self
.MetaFile
= File
1168 self
._PackageDir
= File
.Dir
1169 self
._RawData
= RawData
1170 self
._Bdb
= BuildDataBase
1172 self
._Target
= Target
1173 self
._Toolchain
= Toolchain
1177 def __setitem__(self
, key
, value
):
1178 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1181 def __getitem__(self
, key
):
1182 return self
.__dict
__[self
._PROPERTY
_[key
]]
1184 ## "in" test support
1185 def __contains__(self
, key
):
1186 return key
in self
._PROPERTY
_
1188 ## Set all internal used members of DecBuildData to None
1191 self
._PackageName
= None
1193 self
._Version
= None
1194 self
._PkgUniFile
= None
1195 self
._Protocols
= None
1198 self
._Includes
= None
1199 self
._LibraryClasses
= None
1201 self
.__Macros
= None
1203 ## Get current effective macros
1204 def _GetMacros(self
):
1205 if self
.__Macros
== None:
1207 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1208 return self
.__Macros
1216 # Changing the default ARCH to another may affect all other information
1217 # because all information in a platform may be ARCH-related. That's
1218 # why we need to clear all internal used members, in order to cause all
1219 # information to be re-retrieved.
1221 # @param Value The value of ARCH
1223 def _SetArch(self
, Value
):
1224 if self
._Arch
== Value
:
1229 ## Retrieve all information in [Defines] section
1231 # (Retriving all [Defines] information in one-shot is just to save time.)
1233 def _GetHeaderInfo(self
):
1234 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1235 for Record
in RecordList
:
1238 self
[Name
] = Record
[2]
1239 self
._Header
= 'DUMMY'
1241 ## Retrieve package name
1242 def _GetPackageName(self
):
1243 if self
._PackageName
== None:
1244 if self
._Header
== None:
1245 self
._GetHeaderInfo
()
1246 if self
._PackageName
== None:
1247 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1248 return self
._PackageName
1250 ## Retrieve file guid
1251 def _GetFileGuid(self
):
1252 if self
._Guid
== None:
1253 if self
._Header
== None:
1254 self
._GetHeaderInfo
()
1255 if self
._Guid
== None:
1256 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1259 ## Retrieve package version
1260 def _GetVersion(self
):
1261 if self
._Version
== None:
1262 if self
._Header
== None:
1263 self
._GetHeaderInfo
()
1264 if self
._Version
== None:
1266 return self
._Version
1268 ## Retrieve protocol definitions (name/value pairs)
1269 def _GetProtocol(self
):
1270 if self
._Protocols
== None:
1272 # tdict is a special kind of dict, used for selecting correct
1273 # protocol defition for given ARCH
1275 ProtocolDict
= tdict(True)
1277 # find out all protocol definitions for specific and 'common' arch
1278 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1279 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1280 if Name
not in NameList
:
1281 NameList
.append(Name
)
1282 ProtocolDict
[Arch
, Name
] = Guid
1283 # use sdict to keep the order
1284 self
._Protocols
= sdict()
1285 for Name
in NameList
:
1287 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1288 # will automatically turn to 'common' ARCH for trying
1290 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1291 return self
._Protocols
1293 ## Retrieve PPI definitions (name/value pairs)
1295 if self
._Ppis
== None:
1297 # tdict is a special kind of dict, used for selecting correct
1298 # PPI defition for given ARCH
1300 PpiDict
= tdict(True)
1302 # find out all PPI definitions for specific arch and 'common' arch
1303 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1304 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1305 if Name
not in NameList
:
1306 NameList
.append(Name
)
1307 PpiDict
[Arch
, Name
] = Guid
1308 # use sdict to keep the order
1309 self
._Ppis
= sdict()
1310 for Name
in NameList
:
1312 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1313 # will automatically turn to 'common' ARCH for trying
1315 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1318 ## Retrieve GUID definitions (name/value pairs)
1320 if self
._Guids
== None:
1322 # tdict is a special kind of dict, used for selecting correct
1323 # GUID defition for given ARCH
1325 GuidDict
= tdict(True)
1327 # find out all protocol definitions for specific and 'common' arch
1328 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1329 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1330 if Name
not in NameList
:
1331 NameList
.append(Name
)
1332 GuidDict
[Arch
, Name
] = Guid
1333 # use sdict to keep the order
1334 self
._Guids
= sdict()
1335 for Name
in NameList
:
1337 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1338 # will automatically turn to 'common' ARCH for trying
1340 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1343 ## Retrieve public include paths declared in this package
1344 def _GetInclude(self
):
1345 if self
._Includes
== None:
1347 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1348 Macros
= self
._Macros
1349 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1350 for Record
in RecordList
:
1351 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1354 ErrorCode
, ErrorInfo
= File
.Validate()
1356 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1358 # avoid duplicate include path
1359 if File
not in self
._Includes
:
1360 self
._Includes
.append(File
)
1361 return self
._Includes
1363 ## Retrieve library class declarations (not used in build at present)
1364 def _GetLibraryClass(self
):
1365 if self
._LibraryClasses
== None:
1367 # tdict is a special kind of dict, used for selecting correct
1368 # library class declaration for given ARCH
1370 LibraryClassDict
= tdict(True)
1371 LibraryClassSet
= set()
1372 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1373 Macros
= self
._Macros
1374 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1375 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1376 # check the file validation
1377 ErrorCode
, ErrorInfo
= File
.Validate()
1379 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1380 LibraryClassSet
.add(LibraryClass
)
1381 LibraryClassDict
[Arch
, LibraryClass
] = File
1382 self
._LibraryClasses
= sdict()
1383 for LibraryClass
in LibraryClassSet
:
1384 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1385 return self
._LibraryClasses
1387 ## Retrieve PCD declarations
1389 if self
._Pcds
== None:
1390 self
._Pcds
= sdict()
1391 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1392 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1393 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1394 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1395 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1398 ## Retrieve PCD declarations for given type
1399 def _GetPcd(self
, Type
):
1402 # tdict is a special kind of dict, used for selecting correct
1403 # PCD declaration for given ARCH
1405 PcdDict
= tdict(True, 3)
1406 # for summarizing PCD
1408 # find out all PCDs of the 'type'
1409 RecordList
= self
._RawData
[Type
, self
._Arch
]
1410 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1411 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1412 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1414 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1416 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1417 # will automatically turn to 'common' ARCH and try again
1419 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1423 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1425 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1428 self
._PCD
_TYPE
_STRING
_[Type
],
1440 _Macros
= property(_GetMacros
)
1441 Arch
= property(_GetArch
, _SetArch
)
1442 PackageName
= property(_GetPackageName
)
1443 Guid
= property(_GetFileGuid
)
1444 Version
= property(_GetVersion
)
1446 Protocols
= property(_GetProtocol
)
1447 Ppis
= property(_GetPpi
)
1448 Guids
= property(_GetGuid
)
1449 Includes
= property(_GetInclude
)
1450 LibraryClasses
= property(_GetLibraryClass
)
1451 Pcds
= property(_GetPcds
)
1453 ## Module build information from INF file
1455 # This class is used to retrieve information stored in database and convert them
1456 # into ModuleBuildClassObject form for easier use for AutoGen.
1458 class InfBuildData(ModuleBuildClassObject
):
1459 # dict used to convert PCD type in database to string used by build tool
1460 _PCD_TYPE_STRING_
= {
1461 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1462 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1463 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1464 MODEL_PCD_DYNAMIC
: "Dynamic",
1465 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1466 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1467 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1468 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1469 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1470 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1471 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1474 # dict used to convert part of [Defines] to members of InfBuildData directly
1479 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1480 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1481 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1485 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1486 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1487 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1488 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1489 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1490 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1491 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1492 TAB_INF_DEFINES_VERSION
: "_Version",
1493 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1494 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1496 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1499 # dict used to convert Component type to Module type
1502 "SECURITY_CORE" : "SEC",
1503 "PEI_CORE" : "PEI_CORE",
1504 "COMBINED_PEIM_DRIVER" : "PEIM",
1505 "PIC_PEIM" : "PEIM",
1506 "RELOCATABLE_PEIM" : "PEIM",
1507 "PE32_PEIM" : "PEIM",
1508 "BS_DRIVER" : "DXE_DRIVER",
1509 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1510 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1511 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1512 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1513 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1514 # "BS_DRIVER" : "UEFI_DRIVER",
1515 "APPLICATION" : "UEFI_APPLICATION",
1519 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1520 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1521 # dict used to convert old tool name used in [nmake] section to new ones
1529 ## Constructor of DscBuildData
1531 # Initialize object of DscBuildData
1533 # @param FilePath The path of platform description file
1534 # @param RawData The raw data of DSC file
1535 # @param BuildDataBase Database used to retrieve module/package information
1536 # @param Arch The target architecture
1537 # @param Platform The name of platform employing this module
1538 # @param Macros Macros used for replacement in DSC file
1540 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1541 self
.MetaFile
= FilePath
1542 self
._ModuleDir
= FilePath
.Dir
1543 self
._RawData
= RawData
1544 self
._Bdb
= BuildDatabase
1546 self
._Target
= Target
1547 self
._Toolchain
= Toolchain
1548 self
._Platform
= 'COMMON'
1549 self
._SourceOverridePath
= None
1550 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1551 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1555 def __setitem__(self
, key
, value
):
1556 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1559 def __getitem__(self
, key
):
1560 return self
.__dict
__[self
._PROPERTY
_[key
]]
1562 ## "in" test support
1563 def __contains__(self
, key
):
1564 return key
in self
._PROPERTY
_
1566 ## Set all internal used members of InfBuildData to None
1568 self
._HeaderComments
= None
1569 self
._TailComments
= None
1570 self
._Header
_ = None
1571 self
._AutoGenVersion
= None
1572 self
._BaseName
= None
1573 self
._DxsFile
= None
1574 self
._ModuleType
= None
1575 self
._ComponentType
= None
1576 self
._BuildType
= None
1578 self
._Version
= None
1579 self
._PcdIsDriver
= None
1580 self
._BinaryModule
= None
1582 self
._MakefileName
= None
1583 self
._CustomMakefile
= None
1584 self
._Specification
= None
1585 self
._LibraryClass
= None
1586 self
._ModuleEntryPointList
= None
1587 self
._ModuleUnloadImageList
= None
1588 self
._ConstructorList
= None
1589 self
._DestructorList
= None
1591 self
._Binaries
= None
1592 self
._Sources
= None
1593 self
._LibraryClasses
= None
1594 self
._Libraries
= None
1595 self
._Protocols
= None
1596 self
._ProtocolComments
= None
1598 self
._PpiComments
= None
1600 self
._GuidsUsedByPcd
= sdict()
1601 self
._GuidComments
= None
1602 self
._Includes
= None
1603 self
._Packages
= None
1605 self
._PcdComments
= None
1606 self
._BuildOptions
= None
1608 self
._DepexExpression
= None
1609 self
.__Macros
= None
1611 ## Get current effective macros
1612 def _GetMacros(self
):
1613 if self
.__Macros
== None:
1615 # EDK_GLOBAL defined macros can be applied to EDK module
1616 if self
.AutoGenVersion
< 0x00010005:
1617 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1618 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1619 return self
.__Macros
1627 # Changing the default ARCH to another may affect all other information
1628 # because all information in a platform may be ARCH-related. That's
1629 # why we need to clear all internal used members, in order to cause all
1630 # information to be re-retrieved.
1632 # @param Value The value of ARCH
1634 def _SetArch(self
, Value
):
1635 if self
._Arch
== Value
:
1640 ## Return the name of platform employing this module
1641 def _GetPlatform(self
):
1642 return self
._Platform
1644 ## Change the name of platform employing this module
1646 # Changing the default name of platform to another may affect some information
1647 # because they may be PLATFORM-related. That's why we need to clear all internal
1648 # used members, in order to cause all information to be re-retrieved.
1650 def _SetPlatform(self
, Value
):
1651 if self
._Platform
== Value
:
1653 self
._Platform
= Value
1655 def _GetHeaderComments(self
):
1656 if not self
._HeaderComments
:
1657 self
._HeaderComments
= []
1658 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1659 for Record
in RecordList
:
1660 self
._HeaderComments
.append(Record
[0])
1661 return self
._HeaderComments
1662 def _GetTailComments(self
):
1663 if not self
._TailComments
:
1664 self
._TailComments
= []
1665 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1666 for Record
in RecordList
:
1667 self
._TailComments
.append(Record
[0])
1668 return self
._TailComments
1669 ## Retrieve all information in [Defines] section
1671 # (Retriving all [Defines] information in one-shot is just to save time.)
1673 def _GetHeaderInfo(self
):
1674 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1675 for Record
in RecordList
:
1676 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1677 # items defined _PROPERTY_ don't need additional processing
1680 # some special items in [Defines] section need special treatment
1681 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1682 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1683 Name
= 'UEFI_SPECIFICATION_VERSION'
1684 if self
._Specification
== None:
1685 self
._Specification
= sdict()
1686 self
._Specification
[Name
] = GetHexVerValue(Value
)
1687 if self
._Specification
[Name
] == None:
1688 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1689 "'%s' format is not supported for %s" % (Value
, Name
),
1690 File
=self
.MetaFile
, Line
=Record
[-1])
1691 elif Name
== 'LIBRARY_CLASS':
1692 if self
._LibraryClass
== None:
1693 self
._LibraryClass
= []
1694 ValueList
= GetSplitValueList(Value
)
1695 LibraryClass
= ValueList
[0]
1696 if len(ValueList
) > 1:
1697 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1699 SupModuleList
= SUP_MODULE_LIST
1700 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1701 elif Name
== 'ENTRY_POINT':
1702 if self
._ModuleEntryPointList
== None:
1703 self
._ModuleEntryPointList
= []
1704 self
._ModuleEntryPointList
.append(Value
)
1705 elif Name
== 'UNLOAD_IMAGE':
1706 if self
._ModuleUnloadImageList
== None:
1707 self
._ModuleUnloadImageList
= []
1710 self
._ModuleUnloadImageList
.append(Value
)
1711 elif Name
== 'CONSTRUCTOR':
1712 if self
._ConstructorList
== None:
1713 self
._ConstructorList
= []
1716 self
._ConstructorList
.append(Value
)
1717 elif Name
== 'DESTRUCTOR':
1718 if self
._DestructorList
== None:
1719 self
._DestructorList
= []
1722 self
._DestructorList
.append(Value
)
1723 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1724 TokenList
= GetSplitValueList(Value
)
1725 if self
._CustomMakefile
== None:
1726 self
._CustomMakefile
= {}
1727 if len(TokenList
) < 2:
1728 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1729 self
._CustomMakefile
['GCC'] = TokenList
[0]
1731 if TokenList
[0] not in ['MSFT', 'GCC']:
1732 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1733 "No supported family [%s]" % TokenList
[0],
1734 File
=self
.MetaFile
, Line
=Record
[-1])
1735 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1737 if self
._Defs
== None:
1738 self
._Defs
= sdict()
1739 self
._Defs
[Name
] = Value
1742 # Retrieve information in sections specific to Edk.x modules
1744 if self
.AutoGenVersion
>= 0x00010005:
1745 if not self
._ModuleType
:
1746 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1747 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1748 if self
._ModuleType
not in SUP_MODULE_LIST
:
1749 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1750 for Record
in RecordList
:
1752 if Name
== "MODULE_TYPE":
1755 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1756 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1757 File
=self
.MetaFile
, Line
=LineNo
)
1758 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1759 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1760 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
)
1761 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1762 and 'PCI_CLASS_CODE' in self
._Defs
:
1763 self
._BuildType
= 'UEFI_OPTIONROM'
1764 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1765 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1766 self
._BuildType
= 'UEFI_HII'
1768 self
._BuildType
= self
._ModuleType
.upper()
1771 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1772 # check the file validation
1773 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1775 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1776 File
=self
.MetaFile
, Line
=LineNo
)
1777 if self
.Sources
== None:
1779 self
._Sources
.append(File
)
1781 if not self
._ComponentType
:
1782 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1783 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1784 self
._BuildType
= self
._ComponentType
.upper()
1785 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1786 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1787 if self
._ComponentType
== 'LIBRARY':
1788 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1789 # make use some [nmake] section macros
1790 Macros
= self
._Macros
1791 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1792 Macros
['PROCESSOR'] = self
._Arch
1793 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1794 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1795 Value
= ReplaceMacro(Value
, Macros
, True)
1796 if Name
== "IMAGE_ENTRY_POINT":
1797 if self
._ModuleEntryPointList
== None:
1798 self
._ModuleEntryPointList
= []
1799 self
._ModuleEntryPointList
.append(Value
)
1800 elif Name
== "DPX_SOURCE":
1801 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1802 # check the file validation
1803 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1805 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1806 File
=self
.MetaFile
, Line
=LineNo
)
1807 if self
.Sources
== None:
1809 self
._Sources
.append(File
)
1811 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1812 if len(ToolList
) == 0 or len(ToolList
) != 1:
1814 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1815 # File=self.MetaFile, Line=LineNo)
1817 if self
._BuildOptions
== None:
1818 self
._BuildOptions
= sdict()
1820 if ToolList
[0] in self
._TOOL
_CODE
_:
1821 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1824 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1825 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1826 #ignore not replaced macros in value
1827 ValueList
= GetSplitList(' ' + Value
, '/D')
1828 Dummy
= ValueList
[0]
1829 for Index
in range(1, len(ValueList
)):
1830 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1832 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1833 Value
= Dummy
.strip()
1834 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1835 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1837 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1838 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1839 # set _Header to non-None in order to avoid database re-querying
1840 self
._Header
_ = 'DUMMY'
1842 ## Retrieve file version
1843 def _GetInfVersion(self
):
1844 if self
._AutoGenVersion
== None:
1845 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1846 for Record
in RecordList
:
1847 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1848 self
._AutoGenVersion
= int(Record
[2], 0)
1850 if self
._AutoGenVersion
== None:
1851 self
._AutoGenVersion
= 0x00010000
1852 return self
._AutoGenVersion
1854 ## Retrieve BASE_NAME
1855 def _GetBaseName(self
):
1856 if self
._BaseName
== None:
1857 if self
._Header
_ == None:
1858 self
._GetHeaderInfo
()
1859 if self
._BaseName
== None:
1860 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1861 return self
._BaseName
1864 def _GetDxsFile(self
):
1865 if self
._DxsFile
== None:
1866 if self
._Header
_ == None:
1867 self
._GetHeaderInfo
()
1868 if self
._DxsFile
== None:
1870 return self
._DxsFile
1872 ## Retrieve MODULE_TYPE
1873 def _GetModuleType(self
):
1874 if self
._ModuleType
== None:
1875 if self
._Header
_ == None:
1876 self
._GetHeaderInfo
()
1877 if self
._ModuleType
== None:
1878 self
._ModuleType
= 'BASE'
1879 if self
._ModuleType
not in SUP_MODULE_LIST
:
1880 self
._ModuleType
= "USER_DEFINED"
1881 return self
._ModuleType
1883 ## Retrieve COMPONENT_TYPE
1884 def _GetComponentType(self
):
1885 if self
._ComponentType
== None:
1886 if self
._Header
_ == None:
1887 self
._GetHeaderInfo
()
1888 if self
._ComponentType
== None:
1889 self
._ComponentType
= 'USER_DEFINED'
1890 return self
._ComponentType
1892 ## Retrieve "BUILD_TYPE"
1893 def _GetBuildType(self
):
1894 if self
._BuildType
== None:
1895 if self
._Header
_ == None:
1896 self
._GetHeaderInfo
()
1897 if not self
._BuildType
:
1898 self
._BuildType
= "BASE"
1899 return self
._BuildType
1901 ## Retrieve file guid
1902 def _GetFileGuid(self
):
1903 if self
._Guid
== None:
1904 if self
._Header
_ == None:
1905 self
._GetHeaderInfo
()
1906 if self
._Guid
== None:
1907 self
._Guid
= '00000000-0000-0000-000000000000'
1910 ## Retrieve module version
1911 def _GetVersion(self
):
1912 if self
._Version
== None:
1913 if self
._Header
_ == None:
1914 self
._GetHeaderInfo
()
1915 if self
._Version
== None:
1916 self
._Version
= '0.0'
1917 return self
._Version
1919 ## Retrieve PCD_IS_DRIVER
1920 def _GetPcdIsDriver(self
):
1921 if self
._PcdIsDriver
== None:
1922 if self
._Header
_ == None:
1923 self
._GetHeaderInfo
()
1924 if self
._PcdIsDriver
== None:
1925 self
._PcdIsDriver
= ''
1926 return self
._PcdIsDriver
1929 def _GetShadow(self
):
1930 if self
._Shadow
== None:
1931 if self
._Header
_ == None:
1932 self
._GetHeaderInfo
()
1933 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1936 self
._Shadow
= False
1939 ## Retrieve CUSTOM_MAKEFILE
1940 def _GetMakefile(self
):
1941 if self
._CustomMakefile
== None:
1942 if self
._Header
_ == None:
1943 self
._GetHeaderInfo
()
1944 if self
._CustomMakefile
== None:
1945 self
._CustomMakefile
= {}
1946 return self
._CustomMakefile
1948 ## Retrieve EFI_SPECIFICATION_VERSION
1950 if self
._Specification
== None:
1951 if self
._Header
_ == None:
1952 self
._GetHeaderInfo
()
1953 if self
._Specification
== None:
1954 self
._Specification
= {}
1955 return self
._Specification
1957 ## Retrieve LIBRARY_CLASS
1958 def _GetLibraryClass(self
):
1959 if self
._LibraryClass
== None:
1960 if self
._Header
_ == None:
1961 self
._GetHeaderInfo
()
1962 if self
._LibraryClass
== None:
1963 self
._LibraryClass
= []
1964 return self
._LibraryClass
1966 ## Retrieve ENTRY_POINT
1967 def _GetEntryPoint(self
):
1968 if self
._ModuleEntryPointList
== None:
1969 if self
._Header
_ == None:
1970 self
._GetHeaderInfo
()
1971 if self
._ModuleEntryPointList
== None:
1972 self
._ModuleEntryPointList
= []
1973 return self
._ModuleEntryPointList
1975 ## Retrieve UNLOAD_IMAGE
1976 def _GetUnloadImage(self
):
1977 if self
._ModuleUnloadImageList
== None:
1978 if self
._Header
_ == None:
1979 self
._GetHeaderInfo
()
1980 if self
._ModuleUnloadImageList
== None:
1981 self
._ModuleUnloadImageList
= []
1982 return self
._ModuleUnloadImageList
1984 ## Retrieve CONSTRUCTOR
1985 def _GetConstructor(self
):
1986 if self
._ConstructorList
== None:
1987 if self
._Header
_ == None:
1988 self
._GetHeaderInfo
()
1989 if self
._ConstructorList
== None:
1990 self
._ConstructorList
= []
1991 return self
._ConstructorList
1993 ## Retrieve DESTRUCTOR
1994 def _GetDestructor(self
):
1995 if self
._DestructorList
== None:
1996 if self
._Header
_ == None:
1997 self
._GetHeaderInfo
()
1998 if self
._DestructorList
== None:
1999 self
._DestructorList
= []
2000 return self
._DestructorList
2002 ## Retrieve definies other than above ones
2003 def _GetDefines(self
):
2004 if self
._Defs
== None:
2005 if self
._Header
_ == None:
2006 self
._GetHeaderInfo
()
2007 if self
._Defs
== None:
2008 self
._Defs
= sdict()
2011 ## Retrieve binary files
2012 def _GetBinaryFiles(self
):
2013 if self
._Binaries
== None:
2015 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2016 Macros
= self
._Macros
2017 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2018 Macros
['PROCESSOR'] = self
._Arch
2019 for Record
in RecordList
:
2020 FileType
= Record
[0]
2025 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2027 Target
= TokenList
[0]
2028 if len(TokenList
) > 1:
2029 FeatureFlag
= Record
[1:]
2031 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2032 # check the file validation
2033 ErrorCode
, ErrorInfo
= File
.Validate()
2035 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2036 self
._Binaries
.append(File
)
2037 return self
._Binaries
2039 ## Retrieve source files
2040 def _GetSourceFiles(self
):
2041 if self
._Sources
== None:
2043 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2044 Macros
= self
._Macros
2045 for Record
in RecordList
:
2047 ToolChainFamily
= Record
[1]
2049 ToolCode
= Record
[3]
2050 FeatureFlag
= Record
[4]
2051 if self
.AutoGenVersion
< 0x00010005:
2052 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2053 Macros
['PROCESSOR'] = self
._Arch
2054 # old module source files (Edk)
2055 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
2056 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2057 # check the file validation
2058 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2060 if File
.Ext
.lower() == '.h':
2061 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2062 File
=self
.MetaFile
, Line
=LineNo
)
2065 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2067 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2068 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2069 # check the file validation
2070 ErrorCode
, ErrorInfo
= File
.Validate()
2072 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2074 self
._Sources
.append(File
)
2075 return self
._Sources
2077 ## Retrieve library classes employed by this module
2078 def _GetLibraryClassUses(self
):
2079 if self
._LibraryClasses
== None:
2080 self
._LibraryClasses
= sdict()
2081 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2082 for Record
in RecordList
:
2084 Instance
= Record
[1]
2086 Instance
= NormPath(Instance
, self
._Macros
)
2087 self
._LibraryClasses
[Lib
] = Instance
2088 return self
._LibraryClasses
2090 ## Retrieve library names (for Edk.x style of modules)
2091 def _GetLibraryNames(self
):
2092 if self
._Libraries
== None:
2093 self
._Libraries
= []
2094 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2095 for Record
in RecordList
:
2096 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2097 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2098 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2099 if LibraryName
not in self
._Libraries
:
2100 self
._Libraries
.append(LibraryName
)
2101 return self
._Libraries
2103 def _GetProtocolComments(self
):
2104 self
._GetProtocols
()
2105 return self
._ProtocolComments
2106 ## Retrieve protocols consumed/produced by this module
2107 def _GetProtocols(self
):
2108 if self
._Protocols
== None:
2109 self
._Protocols
= sdict()
2110 self
._ProtocolComments
= sdict()
2111 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2112 for Record
in RecordList
:
2114 Value
= ProtocolValue(CName
, self
.Packages
)
2116 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2117 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2118 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2119 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2120 self
._Protocols
[CName
] = Value
2121 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2123 for CmtRec
in CommentRecords
:
2124 Comments
.append(CmtRec
[0])
2125 self
._ProtocolComments
[CName
] = Comments
2126 return self
._Protocols
2128 def _GetPpiComments(self
):
2130 return self
._PpiComments
2131 ## Retrieve PPIs consumed/produced by this module
2133 if self
._Ppis
== None:
2134 self
._Ppis
= sdict()
2135 self
._PpiComments
= sdict()
2136 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2137 for Record
in RecordList
:
2139 Value
= PpiValue(CName
, self
.Packages
)
2141 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2142 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2143 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2144 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2145 self
._Ppis
[CName
] = Value
2146 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2148 for CmtRec
in CommentRecords
:
2149 Comments
.append(CmtRec
[0])
2150 self
._PpiComments
[CName
] = Comments
2153 def _GetGuidComments(self
):
2155 return self
._GuidComments
2156 ## Retrieve GUIDs consumed/produced by this module
2157 def _GetGuids(self
):
2158 if self
._Guids
== None:
2159 self
._Guids
= sdict()
2160 self
._GuidComments
= sdict()
2161 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2162 for Record
in RecordList
:
2164 Value
= GuidValue(CName
, self
.Packages
)
2166 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2167 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2168 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2169 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2170 self
._Guids
[CName
] = Value
2171 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2173 for CmtRec
in CommentRecords
:
2174 Comments
.append(CmtRec
[0])
2175 self
._GuidComments
[CName
] = Comments
2178 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2179 def _GetIncludes(self
):
2180 if self
._Includes
== None:
2182 if self
._SourceOverridePath
:
2183 self
._Includes
.append(self
._SourceOverridePath
)
2185 Macros
= self
._Macros
2186 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2187 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2189 Macros
['PROCESSOR'] = self
._Arch
2190 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2191 for Record
in RecordList
:
2192 if Record
[0].find('EDK_SOURCE') > -1:
2193 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2194 File
= NormPath(Record
[0], self
._Macros
)
2196 File
= os
.path
.join(self
._ModuleDir
, File
)
2198 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2199 File
= RealPath(os
.path
.normpath(File
))
2201 self
._Includes
.append(File
)
2203 #TRICK: let compiler to choose correct header file
2204 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2205 File
= NormPath(Record
[0], self
._Macros
)
2207 File
= os
.path
.join(self
._ModuleDir
, File
)
2209 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2210 File
= RealPath(os
.path
.normpath(File
))
2212 self
._Includes
.append(File
)
2214 File
= NormPath(Record
[0], Macros
)
2216 File
= os
.path
.join(self
._ModuleDir
, File
)
2218 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2219 File
= RealPath(os
.path
.normpath(File
))
2221 self
._Includes
.append(File
)
2222 return self
._Includes
2224 ## Retrieve packages this module depends on
2225 def _GetPackages(self
):
2226 if self
._Packages
== None:
2228 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2229 Macros
= self
._Macros
2230 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2231 for Record
in RecordList
:
2232 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2234 # check the file validation
2235 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2237 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2238 # parse this package now. we need it to get protocol/ppi/guid value
2239 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2240 self
._Packages
.append(Package
)
2241 return self
._Packages
2243 ## Retrieve PCD comments
2244 def _GetPcdComments(self
):
2246 return self
._PcdComments
2247 ## Retrieve PCDs used in this module
2249 if self
._Pcds
== None:
2250 self
._Pcds
= sdict()
2251 self
._PcdComments
= sdict()
2252 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2253 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2254 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2255 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2256 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2259 ## Retrieve build options specific to this module
2260 def _GetBuildOptions(self
):
2261 if self
._BuildOptions
== None:
2262 self
._BuildOptions
= sdict()
2263 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2264 for Record
in RecordList
:
2265 ToolChainFamily
= Record
[0]
2266 ToolChain
= Record
[1]
2268 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2269 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2271 # concatenate the option string if they're for the same tool
2272 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2273 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2274 return self
._BuildOptions
2276 ## Retrieve dependency expression
2277 def _GetDepex(self
):
2278 if self
._Depex
== None:
2279 self
._Depex
= tdict(False, 2)
2280 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2282 # If the module has only Binaries and no Sources, then ignore [Depex]
2283 if self
.Sources
== None or self
.Sources
== []:
2284 if self
.Binaries
!= None and self
.Binaries
!= []:
2287 # PEIM and DXE drivers must have a valid [Depex] section
2288 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2289 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2290 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2291 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2292 % self
.ModuleType
, File
=self
.MetaFile
)
2295 for Record
in RecordList
:
2296 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2298 ModuleType
= Record
[4]
2299 TokenList
= DepexStr
.split()
2300 if (Arch
, ModuleType
) not in Depex
:
2301 Depex
[Arch
, ModuleType
] = []
2302 DepexList
= Depex
[Arch
, ModuleType
]
2303 for Token
in TokenList
:
2304 if Token
in DEPEX_SUPPORTED_OPCODE
:
2305 DepexList
.append(Token
)
2306 elif Token
.endswith(".inf"): # module file name
2307 ModuleFile
= os
.path
.normpath(Token
)
2308 Module
= self
.BuildDatabase
[ModuleFile
]
2310 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2311 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2312 DepexList
.append(Module
.Guid
)
2314 # get the GUID value now
2315 Value
= ProtocolValue(Token
, self
.Packages
)
2317 Value
= PpiValue(Token
, self
.Packages
)
2319 Value
= GuidValue(Token
, self
.Packages
)
2321 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2322 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2323 "Value of [%s] is not found in" % Token
,
2324 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2325 DepexList
.append(Value
)
2326 for Arch
, ModuleType
in Depex
:
2327 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2330 ## Retrieve depedency expression
2331 def _GetDepexExpression(self
):
2332 if self
._DepexExpression
== None:
2333 self
._DepexExpression
= tdict(False, 2)
2334 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2335 DepexExpression
= sdict()
2336 for Record
in RecordList
:
2337 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2339 ModuleType
= Record
[4]
2340 TokenList
= DepexStr
.split()
2341 if (Arch
, ModuleType
) not in DepexExpression
:
2342 DepexExpression
[Arch
, ModuleType
] = ''
2343 for Token
in TokenList
:
2344 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2345 for Arch
, ModuleType
in DepexExpression
:
2346 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2347 return self
._DepexExpression
2349 def GetGuidsUsedByPcd(self
):
2350 return self
._GuidsUsedByPcd
2351 ## Retrieve PCD for given type
2352 def _GetPcd(self
, Type
):
2354 PcdDict
= tdict(True, 4)
2356 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2357 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2358 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2359 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2360 # get the guid value
2361 if TokenSpaceGuid
not in self
.Guids
:
2362 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2364 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2365 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2366 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2367 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2368 self
.Guids
[TokenSpaceGuid
] = Value
2369 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2370 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2372 for CmtRec
in CommentRecords
:
2373 Comments
.append(CmtRec
[0])
2374 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2376 # resolve PCD type, value, datum info, etc. by getting its definition from package
2377 for PcdCName
, TokenSpaceGuid
in PcdList
:
2378 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2381 ValueList
= AnalyzePcdData(Setting
)
2382 DefaultValue
= ValueList
[0]
2383 Pcd
= PcdClassObject(
2393 self
.Guids
[TokenSpaceGuid
]
2395 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2396 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2397 Pcd
.Offset
= ValueList
[1]
2399 # get necessary info from package declaring this PCD
2400 for Package
in self
.Packages
:
2402 # 'dynamic' in INF means its type is determined by platform;
2403 # if platform doesn't give its type, use 'lowest' one in the
2404 # following order, if any
2406 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2408 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2409 if Type
== MODEL_PCD_DYNAMIC
:
2411 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2412 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2418 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2419 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2421 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2424 # Check whether the token value exist or not.
2426 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2430 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2431 File
=self
.MetaFile
, Line
=LineNo
,
2435 # Check hexadecimal token value length and format.
2437 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2438 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2439 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2443 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2444 File
=self
.MetaFile
, Line
=LineNo
,
2449 # Check decimal token value length and format.
2453 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2454 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2458 "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
)),
2459 File
=self
.MetaFile
, Line
=LineNo
,
2466 "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
)),
2467 File
=self
.MetaFile
, Line
=LineNo
,
2471 Pcd
.DatumType
= PcdInPackage
.DatumType
2472 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2473 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2474 if Pcd
.DefaultValue
in [None, '']:
2475 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2481 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2482 File
=self
.MetaFile
, Line
=LineNo
,
2483 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2485 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2489 ## check whether current module is binary module
2490 def _IsBinaryModule(self
):
2491 if self
.Binaries
and not self
.Sources
:
2493 elif GlobalData
.gIgnoreSource
:
2498 _Macros
= property(_GetMacros
)
2499 Arch
= property(_GetArch
, _SetArch
)
2500 Platform
= property(_GetPlatform
, _SetPlatform
)
2502 HeaderComments
= property(_GetHeaderComments
)
2503 TailComments
= property(_GetTailComments
)
2504 AutoGenVersion
= property(_GetInfVersion
)
2505 BaseName
= property(_GetBaseName
)
2506 ModuleType
= property(_GetModuleType
)
2507 ComponentType
= property(_GetComponentType
)
2508 BuildType
= property(_GetBuildType
)
2509 Guid
= property(_GetFileGuid
)
2510 Version
= property(_GetVersion
)
2511 PcdIsDriver
= property(_GetPcdIsDriver
)
2512 Shadow
= property(_GetShadow
)
2513 CustomMakefile
= property(_GetMakefile
)
2514 Specification
= property(_GetSpec
)
2515 LibraryClass
= property(_GetLibraryClass
)
2516 ModuleEntryPointList
= property(_GetEntryPoint
)
2517 ModuleUnloadImageList
= property(_GetUnloadImage
)
2518 ConstructorList
= property(_GetConstructor
)
2519 DestructorList
= property(_GetDestructor
)
2520 Defines
= property(_GetDefines
)
2521 DxsFile
= property(_GetDxsFile
)
2523 Binaries
= property(_GetBinaryFiles
)
2524 Sources
= property(_GetSourceFiles
)
2525 LibraryClasses
= property(_GetLibraryClassUses
)
2526 Libraries
= property(_GetLibraryNames
)
2527 Protocols
= property(_GetProtocols
)
2528 ProtocolComments
= property(_GetProtocolComments
)
2529 Ppis
= property(_GetPpis
)
2530 PpiComments
= property(_GetPpiComments
)
2531 Guids
= property(_GetGuids
)
2532 GuidComments
= property(_GetGuidComments
)
2533 Includes
= property(_GetIncludes
)
2534 Packages
= property(_GetPackages
)
2535 Pcds
= property(_GetPcds
)
2536 PcdComments
= property(_GetPcdComments
)
2537 BuildOptions
= property(_GetBuildOptions
)
2538 Depex
= property(_GetDepex
)
2539 DepexExpression
= property(_GetDepexExpression
)
2540 IsBinaryModule
= property(_IsBinaryModule
)
2544 # This class defined the build database for all modules, packages and platform.
2545 # It will call corresponding parser for the given file if it cannot find it in
2548 # @param DbPath Path of database file
2549 # @param GlobalMacros Global macros used for replacement during file parsing
2550 # @prarm RenewDb=False Create new database file if it's already there
2552 class WorkspaceDatabase(object):
2554 # default database file path
2555 _DB_PATH_
= "Conf/.cache/build.db"
2558 # internal class used for call corresponding file parser and caching the result
2559 # to avoid unnecessary re-parsing
2561 class BuildObjectFactory(object):
2564 ".inf" : MODEL_FILE_INF
,
2565 ".dec" : MODEL_FILE_DEC
,
2566 ".dsc" : MODEL_FILE_DSC
,
2571 MODEL_FILE_INF
: InfParser
,
2572 MODEL_FILE_DEC
: DecParser
,
2573 MODEL_FILE_DSC
: DscParser
,
2576 # convert to xxxBuildData object
2578 MODEL_FILE_INF
: InfBuildData
,
2579 MODEL_FILE_DEC
: DecBuildData
,
2580 MODEL_FILE_DSC
: DscBuildData
,
2583 _CACHE_
= {} # (FilePath, Arch) : <object>
2586 def __init__(self
, WorkspaceDb
):
2587 self
.WorkspaceDb
= WorkspaceDb
2589 # key = (FilePath, Arch=None)
2590 def __contains__(self
, Key
):
2596 return (FilePath
, Arch
) in self
._CACHE
_
2598 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2599 def __getitem__(self
, Key
):
2601 KeyLength
= len(Key
)
2615 # if it's generated before, just return the cached one
2616 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2617 if Key
in self
._CACHE
_:
2618 return self
._CACHE
_[Key
]
2622 if Ext
not in self
._FILE
_TYPE
_:
2624 FileType
= self
._FILE
_TYPE
_[Ext
]
2625 if FileType
not in self
._GENERATOR
_:
2628 # get the parser ready for this file
2629 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2632 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2634 # alwasy do post-process, in case of macros change
2635 MetaFile
.DoPostProcess()
2636 # object the build is based on
2637 BuildObject
= self
._GENERATOR
_[FileType
](
2645 self
._CACHE
_[Key
] = BuildObject
2648 # placeholder for file format conversion
2649 class TransformObjectFactory
:
2650 def __init__(self
, WorkspaceDb
):
2651 self
.WorkspaceDb
= WorkspaceDb
2653 # key = FilePath, Arch
2654 def __getitem__(self
, Key
):
2657 ## Constructor of WorkspaceDatabase
2659 # @param DbPath Path of database file
2660 # @param GlobalMacros Global macros used for replacement during file parsing
2661 # @prarm RenewDb=False Create new database file if it's already there
2663 def __init__(self
, DbPath
, RenewDb
=False):
2664 self
._DbClosedFlag
= False
2666 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2668 # don't create necessary path for db in memory
2669 if DbPath
!= ':memory:':
2670 DbDir
= os
.path
.split(DbPath
)[0]
2671 if not os
.path
.exists(DbDir
):
2674 # remove db file in case inconsistency between db and file in file system
2675 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2678 # create db with optimized parameters
2679 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2680 self
.Conn
.execute("PRAGMA synchronous=OFF")
2681 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2682 self
.Conn
.execute("PRAGMA count_changes=OFF")
2683 self
.Conn
.execute("PRAGMA cache_size=8192")
2684 #self.Conn.execute("PRAGMA page_size=8192")
2686 # to avoid non-ascii character conversion issue
2687 self
.Conn
.text_factory
= str
2688 self
.Cur
= self
.Conn
.cursor()
2690 # create table for internal uses
2691 self
.TblDataModel
= TableDataModel(self
.Cur
)
2692 self
.TblFile
= TableFile(self
.Cur
)
2693 self
.Platform
= None
2695 # conversion object for build or file format conversion purpose
2696 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2697 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2699 ## Check whether workspace database need to be renew.
2700 # The renew reason maybe:
2701 # 1) If user force to renew;
2702 # 2) If user do not force renew, and
2703 # a) If the time of last modified python source is newer than database file;
2704 # b) If the time of last modified frozen executable file is newer than database file;
2706 # @param force User force renew database
2707 # @param DbPath The absolute path of workspace database file
2709 # @return Bool value for whether need renew workspace databse
2711 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2712 # if database does not exist, we need do nothing
2713 if not os
.path
.exists(DbPath
): return False
2715 # if user force to renew database, then not check whether database is out of date
2716 if force
: return True
2719 # Check the time of last modified source file or build.exe
2720 # if is newer than time of database, then database need to be re-created.
2722 timeOfToolModified
= 0
2723 if hasattr(sys
, "frozen"):
2724 exePath
= os
.path
.abspath(sys
.executable
)
2725 timeOfToolModified
= os
.stat(exePath
).st_mtime
2727 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2728 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2729 if rootPath
== "" or rootPath
== None:
2730 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2731 determine whether database file is out of date!\n")
2733 # walk the root path of source or build's binary to get the time last modified.
2735 for root
, dirs
, files
in os
.walk (rootPath
):
2737 # bypass source control folder
2738 if dir.lower() in [".svn", "_svn", "cvs"]:
2742 ext
= os
.path
.splitext(file)[1]
2743 if ext
.lower() == ".py": # only check .py files
2744 fd
= os
.stat(os
.path
.join(root
, file))
2745 if timeOfToolModified
< fd
.st_mtime
:
2746 timeOfToolModified
= fd
.st_mtime
2747 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2748 EdkLogger
.verbose("\nWorkspace database is out of data!")
2753 ## Initialize build database
2754 def InitDatabase(self
):
2755 EdkLogger
.verbose("\nInitialize build database started ...")
2760 self
.TblDataModel
.Create(False)
2761 self
.TblFile
.Create(False)
2764 # Initialize table DataModel
2766 self
.TblDataModel
.InitTable()
2767 EdkLogger
.verbose("Initialize build database ... DONE!")
2771 # @param Table: The instance of the table to be queried
2773 def QueryTable(self
, Table
):
2779 ## Close entire database
2782 # Close the connection and cursor
2785 if not self
._DbClosedFlag
:
2789 self
._DbClosedFlag
= True
2791 ## Summarize all packages in the database
2792 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2793 self
.Platform
= Platform
2795 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2797 # Get Package related to Modules
2799 for Module
in Pa
.Modules
:
2800 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2801 for Package
in ModuleObj
.Packages
:
2802 if Package
not in PackageList
:
2803 PackageList
.append(Package
)
2805 # Get Packages related to Libraries
2807 for Lib
in Pa
.LibraryInstances
:
2808 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2809 for Package
in LibObj
.Packages
:
2810 if Package
not in PackageList
:
2811 PackageList
.append(Package
)
2815 ## Summarize all platforms in the database
2816 def _GetPlatformList(self
):
2818 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2820 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2823 if Platform
!= None:
2824 PlatformList
.append(Platform
)
2827 PlatformList
= property(_GetPlatformList
)
2831 # This acts like the main() function for the script, unless it is 'import'ed into another
2834 if __name__
== '__main__':