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