2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 import Common
.EdkLogger
as EdkLogger
24 import Common
.GlobalData
as GlobalData
26 from Common
.String
import *
27 from Common
.DataType
import *
28 from Common
.Misc
import *
31 from CommonDataClass
.CommonClass
import SkuInfoClass
33 from MetaDataTable
import *
34 from MetaFileTable
import *
35 from MetaFileParser
import *
36 from BuildClassObject
import *
37 from WorkspaceCommon
import GetDeclaredPcd
38 from Common
.Misc
import AnalyzeDscPcd
40 ## Platform build information from DSC file
42 # This class is used to retrieve information stored in database and convert them
43 # into PlatformBuildClassObject form for easier use for AutoGen.
45 class DscBuildData(PlatformBuildClassObject
):
46 # dict used to convert PCD type in database to string used by build tool
48 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
49 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
50 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
51 MODEL_PCD_DYNAMIC
: "Dynamic",
52 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
53 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
54 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
55 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
56 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
57 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
58 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
61 # dict used to convert part of [Defines] to members of DscBuildData directly
66 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
67 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
68 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
69 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
70 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
71 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
72 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
73 #TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
74 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
75 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
76 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
77 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
78 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
79 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
80 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
83 # used to compose dummy library class name for those forced library instances
84 _NullLibraryNumber
= 0
86 ## Constructor of DscBuildData
88 # Initialize object of DscBuildData
90 # @param FilePath The path of platform description file
91 # @param RawData The raw data of DSC file
92 # @param BuildDataBase Database used to retrieve module/package information
93 # @param Arch The target architecture
94 # @param Platform (not used for DscBuildData)
95 # @param Macros Macros used for replacement in DSC file
97 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
98 self
.MetaFile
= FilePath
99 self
._RawData
= RawData
100 self
._Bdb
= BuildDataBase
102 self
._Target
= Target
103 self
._Toolchain
= Toolchain
107 def __setitem__(self
, key
, value
):
108 self
.__dict
__[self
._PROPERTY
_[key
]] = value
111 def __getitem__(self
, key
):
112 return self
.__dict
__[self
._PROPERTY
_[key
]]
115 def __contains__(self
, key
):
116 return key
in self
._PROPERTY
_
118 ## Set all internal used members of DscBuildData to None
121 self
._PlatformName
= None
124 self
._DscSpecification
= None
125 self
._OutputDirectory
= None
126 self
._SupArchList
= None
127 self
._BuildTargets
= None
129 self
._FlashDefinition
= None
130 self
._BuildNumber
= None
131 self
._MakefileName
= None
132 self
._BsBaseAddress
= None
133 self
._RtBaseAddress
= None
136 self
._LibraryInstances
= None
137 self
._LibraryClasses
= None
140 self
._BuildOptions
= None
141 self
._LoadFixAddress
= None
142 self
._RFCLanguages
= None
143 self
._ISOLanguages
= None
144 self
._VpdToolGuid
= None
147 ## Get current effective macros
148 def _GetMacros(self
):
149 if self
.__Macros
== None:
151 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
152 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
153 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
162 # Changing the default ARCH to another may affect all other information
163 # because all information in a platform may be ARCH-related. That's
164 # why we need to clear all internal used members, in order to cause all
165 # information to be re-retrieved.
167 # @param Value The value of ARCH
169 def _SetArch(self
, Value
):
170 if self
._Arch
== Value
:
175 ## Retrieve all information in [Defines] section
177 # (Retriving all [Defines] information in one-shot is just to save time.)
179 def _GetHeaderInfo(self
):
180 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
181 for Record
in RecordList
:
183 # items defined _PROPERTY_ don't need additional processing
185 self
[Name
] = Record
[2]
186 # some special items in [Defines] section need special treatment
187 elif Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
188 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
189 if ' ' in self
._OutputDirectory
:
190 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
191 File
=self
.MetaFile
, Line
=Record
[-1],
192 ExtraData
=self
._OutputDirectory
)
193 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
194 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
195 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
197 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
199 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
200 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
201 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
202 self
._BuildTargets
= GetSplitValueList(Record
[2])
203 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
204 if self
._SkuName
== None:
205 self
._SkuName
= Record
[2]
206 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
208 self
._LoadFixAddress
= int (Record
[2], 0)
210 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
211 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
212 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
213 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"',
214 File
=self
.MetaFile
, Line
=Record
[-1])
215 LanguageCodes
= Record
[2][1:-1]
216 if not LanguageCodes
:
217 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
218 File
=self
.MetaFile
, Line
=Record
[-1])
219 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
220 # check whether there is empty entries in the list
221 if None in LanguageList
:
222 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
223 File
=self
.MetaFile
, Line
=Record
[-1])
224 self
._RFCLanguages
= LanguageList
225 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
226 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
227 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
228 File
=self
.MetaFile
, Line
=Record
[-1])
229 LanguageCodes
= Record
[2][1:-1]
230 if not LanguageCodes
:
231 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
232 File
=self
.MetaFile
, Line
=Record
[-1])
233 if len(LanguageCodes
)%3:
234 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
235 File
=self
.MetaFile
, Line
=Record
[-1])
237 for i
in range(0, len(LanguageCodes
), 3):
238 LanguageList
.append(LanguageCodes
[i
:i
+3])
239 self
._ISOLanguages
= LanguageList
240 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
242 # try to convert GUID to a real UUID value to see whether the GUID is format
243 # for VPD_TOOL_GUID is correct.
248 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
249 self
._VpdToolGuid
= Record
[2]
250 # set _Header to non-None in order to avoid database re-querying
251 self
._Header
= 'DUMMY'
253 ## Retrieve platform name
254 def _GetPlatformName(self
):
255 if self
._PlatformName
== None:
256 if self
._Header
== None:
257 self
._GetHeaderInfo
()
258 if self
._PlatformName
== None:
259 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
260 return self
._PlatformName
262 ## Retrieve file guid
263 def _GetFileGuid(self
):
264 if self
._Guid
== None:
265 if self
._Header
== None:
266 self
._GetHeaderInfo
()
267 if self
._Guid
== None:
268 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
271 ## Retrieve platform version
272 def _GetVersion(self
):
273 if self
._Version
== None:
274 if self
._Header
== None:
275 self
._GetHeaderInfo
()
276 if self
._Version
== None:
277 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
280 ## Retrieve platform description file version
281 def _GetDscSpec(self
):
282 if self
._DscSpecification
== None:
283 if self
._Header
== None:
284 self
._GetHeaderInfo
()
285 if self
._DscSpecification
== None:
286 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
287 return self
._DscSpecification
289 ## Retrieve OUTPUT_DIRECTORY
290 def _GetOutpuDir(self
):
291 if self
._OutputDirectory
== None:
292 if self
._Header
== None:
293 self
._GetHeaderInfo
()
294 if self
._OutputDirectory
== None:
295 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
296 return self
._OutputDirectory
298 ## Retrieve SUPPORTED_ARCHITECTURES
299 def _GetSupArch(self
):
300 if self
._SupArchList
== None:
301 if self
._Header
== None:
302 self
._GetHeaderInfo
()
303 if self
._SupArchList
== None:
304 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
305 return self
._SupArchList
307 ## Retrieve BUILD_TARGETS
308 def _GetBuildTarget(self
):
309 if self
._BuildTargets
== None:
310 if self
._Header
== None:
311 self
._GetHeaderInfo
()
312 if self
._BuildTargets
== None:
313 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
314 return self
._BuildTargets
316 ## Retrieve SKUID_IDENTIFIER
317 def _GetSkuName(self
):
318 if self
._SkuName
== None:
319 if self
._Header
== None:
320 self
._GetHeaderInfo
()
321 if self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
:
322 self
._SkuName
= 'DEFAULT'
325 ## Override SKUID_IDENTIFIER
326 def _SetSkuName(self
, Value
):
327 if Value
in self
.SkuIds
:
328 self
._SkuName
= Value
329 # Needs to re-retrieve the PCD information
332 def _GetFdfFile(self
):
333 if self
._FlashDefinition
== None:
334 if self
._Header
== None:
335 self
._GetHeaderInfo
()
336 if self
._FlashDefinition
== None:
337 self
._FlashDefinition
= ''
338 return self
._FlashDefinition
340 ## Retrieve FLASH_DEFINITION
341 def _GetBuildNumber(self
):
342 if self
._BuildNumber
== None:
343 if self
._Header
== None:
344 self
._GetHeaderInfo
()
345 if self
._BuildNumber
== None:
346 self
._BuildNumber
= ''
347 return self
._BuildNumber
349 ## Retrieve MAKEFILE_NAME
350 def _GetMakefileName(self
):
351 if self
._MakefileName
== None:
352 if self
._Header
== None:
353 self
._GetHeaderInfo
()
354 if self
._MakefileName
== None:
355 self
._MakefileName
= ''
356 return self
._MakefileName
358 ## Retrieve BsBaseAddress
359 def _GetBsBaseAddress(self
):
360 if self
._BsBaseAddress
== None:
361 if self
._Header
== None:
362 self
._GetHeaderInfo
()
363 if self
._BsBaseAddress
== None:
364 self
._BsBaseAddress
= ''
365 return self
._BsBaseAddress
367 ## Retrieve RtBaseAddress
368 def _GetRtBaseAddress(self
):
369 if self
._RtBaseAddress
== None:
370 if self
._Header
== None:
371 self
._GetHeaderInfo
()
372 if self
._RtBaseAddress
== None:
373 self
._RtBaseAddress
= ''
374 return self
._RtBaseAddress
376 ## Retrieve the top address for the load fix address
377 def _GetLoadFixAddress(self
):
378 if self
._LoadFixAddress
== None:
379 if self
._Header
== None:
380 self
._GetHeaderInfo
()
382 if self
._LoadFixAddress
== None:
383 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
386 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
388 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
391 # If command line defined, should override the value in DSC file.
393 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
395 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
397 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']))
399 if self
._LoadFixAddress
< 0:
400 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
401 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
402 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
404 return self
._LoadFixAddress
406 ## Retrieve RFCLanguage filter
407 def _GetRFCLanguages(self
):
408 if self
._RFCLanguages
== None:
409 if self
._Header
== None:
410 self
._GetHeaderInfo
()
411 if self
._RFCLanguages
== None:
412 self
._RFCLanguages
= []
413 return self
._RFCLanguages
415 ## Retrieve ISOLanguage filter
416 def _GetISOLanguages(self
):
417 if self
._ISOLanguages
== None:
418 if self
._Header
== None:
419 self
._GetHeaderInfo
()
420 if self
._ISOLanguages
== None:
421 self
._ISOLanguages
= []
422 return self
._ISOLanguages
423 ## Retrieve the GUID string for VPD tool
424 def _GetVpdToolGuid(self
):
425 if self
._VpdToolGuid
== None:
426 if self
._Header
== None:
427 self
._GetHeaderInfo
()
428 if self
._VpdToolGuid
== None:
429 self
._VpdToolGuid
= ''
430 return self
._VpdToolGuid
432 ## Retrieve [SkuIds] section information
433 def _GetSkuIds(self
):
434 if self
._SkuIds
== None:
435 self
._SkuIds
= sdict()
436 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
437 for Record
in RecordList
:
438 if Record
[0] in [None, '']:
439 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
440 File
=self
.MetaFile
, Line
=Record
[-1])
441 if Record
[1] in [None, '']:
442 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
443 File
=self
.MetaFile
, Line
=Record
[-1])
444 self
._SkuIds
[Record
[1]] = Record
[0]
445 if 'DEFAULT' not in self
._SkuIds
:
446 self
._SkuIds
['DEFAULT'] = '0'
449 ## Retrieve [Components] section information
450 def _GetModules(self
):
451 if self
._Modules
!= None:
454 self
._Modules
= sdict()
455 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
456 Macros
= self
._Macros
457 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
458 for Record
in RecordList
:
459 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
463 # check the file validation
464 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
466 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
469 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
470 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
471 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
473 Module
= ModuleBuildClassObject()
474 Module
.MetaFile
= ModuleFile
476 # get module override path
477 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
479 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
481 # Check if the source override path exists
482 if not os
.path
.isdir(Module
.SourceOverridePath
):
483 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
485 #Add to GlobalData Variables
486 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
488 # get module private library instance
489 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
490 for Record
in RecordList
:
491 LibraryClass
= Record
[0]
492 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
495 # check the file validation
496 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
498 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
501 if LibraryClass
== '' or LibraryClass
== 'NULL':
502 self
._NullLibraryNumber
+= 1
503 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
504 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
505 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
506 if LibraryPath
not in self
.LibraryInstances
:
507 self
.LibraryInstances
.append(LibraryPath
)
509 # get module private PCD setting
510 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
511 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
512 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
513 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
514 TokenList
= GetSplitValueList(Setting
)
515 DefaultValue
= TokenList
[0]
516 if len(TokenList
) > 1:
517 MaxDatumSize
= TokenList
[1]
520 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
521 Pcd
= PcdClassObject(
533 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
535 # get module private build options
536 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
537 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
538 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
539 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
541 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
542 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
544 self
._Modules
[ModuleFile
] = Module
547 ## Retrieve all possible library instances used in this platform
548 def _GetLibraryInstances(self
):
549 if self
._LibraryInstances
== None:
550 self
._GetLibraryClasses
()
551 return self
._LibraryInstances
553 ## Retrieve [LibraryClasses] information
554 def _GetLibraryClasses(self
):
555 if self
._LibraryClasses
== None:
556 self
._LibraryInstances
= []
558 # tdict is a special dict kind of type, used for selecting correct
559 # library instance for given library class and module type
561 LibraryClassDict
= tdict(True, 3)
562 # track all library class names
563 LibraryClassSet
= set()
564 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
565 Macros
= self
._Macros
566 for Record
in RecordList
:
567 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
568 if LibraryClass
== '' or LibraryClass
== 'NULL':
569 self
._NullLibraryNumber
+= 1
570 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
571 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
572 LibraryClassSet
.add(LibraryClass
)
573 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
574 # check the file validation
575 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
577 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
580 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
581 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
582 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
583 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
584 if LibraryInstance
not in self
._LibraryInstances
:
585 self
._LibraryInstances
.append(LibraryInstance
)
587 # resolve the specific library instance for each class and each module type
588 self
._LibraryClasses
= tdict(True)
589 for LibraryClass
in LibraryClassSet
:
590 # try all possible module types
591 for ModuleType
in SUP_MODULE_LIST
:
592 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
593 if LibraryInstance
== None:
595 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
597 # for Edk style library instances, which are listed in different section
598 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
599 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
600 for Record
in RecordList
:
601 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
603 # check the file validation
604 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
606 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
608 if File
not in self
._LibraryInstances
:
609 self
._LibraryInstances
.append(File
)
611 # we need the module name as the library class name, so we have
612 # to parse it here. (self._Bdb[] will trigger a file parse if it
613 # hasn't been parsed)
615 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
616 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
617 return self
._LibraryClasses
619 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
620 if self
._DecPcds
== None:
621 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
622 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
623 EdkLogger
.error('build', PARSER_ERROR
,
624 "Pcd (%s.%s) defined in DSC is not declared in DEC files." % (TokenSpaceGuid
, PcdCName
),
625 File
=self
.MetaFile
, Line
=LineNo
)
626 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
627 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
628 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
629 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
630 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
632 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
633 except WrnExpression
, Value
:
634 ValueList
[Index
] = Value
.result
635 except EvaluationException
, Excpt
:
636 if hasattr(Excpt
, 'Pcd'):
637 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
638 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
639 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
640 " of the DSC file" % Excpt
.Pcd
,
641 File
=self
.MetaFile
, Line
=LineNo
)
643 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
644 File
=self
.MetaFile
, Line
=LineNo
)
646 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
647 File
=self
.MetaFile
, Line
=LineNo
)
648 if ValueList
[Index
] == 'True':
649 ValueList
[Index
] = '1'
650 elif ValueList
[Index
] == 'False':
651 ValueList
[Index
] = '0'
653 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
655 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
656 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
659 ## Retrieve all PCD settings in platform
661 if self
._Pcds
== None:
663 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
664 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
665 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
666 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
667 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
668 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
669 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
670 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
671 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
674 ## Retrieve [BuildOptions]
675 def _GetBuildOptions(self
):
676 if self
._BuildOptions
== None:
677 self
._BuildOptions
= sdict()
679 # Retrieve build option for EDKII style module
681 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
682 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
683 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
685 # Retrieve build option for EDK style module
687 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
688 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
689 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
690 return self
._BuildOptions
692 ## Retrieve non-dynamic PCD settings
694 # @param Type PCD type
696 # @retval a dict object contains settings of given PCD type
698 def _GetPcd(self
, Type
):
701 # tdict is a special dict kind of type, used for selecting correct
702 # PCD settings for certain ARCH
704 PcdDict
= tdict(True, 3)
706 # Find out all possible PCD candidates for self._Arch
707 RecordList
= self
._RawData
[Type
, self
._Arch
]
708 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
709 PcdSet
.add((PcdCName
, TokenSpaceGuid
, Dummy4
))
710 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
711 # Remove redundant PCD candidates
712 for PcdCName
, TokenSpaceGuid
, Dummy4
in PcdSet
:
713 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
716 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
717 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
720 self
._PCD
_TYPE
_STRING
_[Type
],
731 ## Retrieve dynamic PCD settings
733 # @param Type PCD type
735 # @retval a dict object contains settings of given PCD type
737 def _GetDynamicPcd(self
, Type
):
740 # tdict is a special dict kind of type, used for selecting correct
741 # PCD settings for certain ARCH and SKU
743 PcdDict
= tdict(True, 4)
745 # Find out all possible PCD candidates for self._Arch
746 RecordList
= self
._RawData
[Type
, self
._Arch
]
747 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
748 PcdList
.append((PcdCName
, TokenSpaceGuid
, Dummy4
))
749 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
750 # Remove redundant PCD candidates, per the ARCH and SKU
751 for PcdCName
, TokenSpaceGuid
, Dummy4
in PcdList
:
752 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
756 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
758 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', '', PcdValue
)
759 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
762 self
._PCD
_TYPE
_STRING
_[Type
],
767 {self
.SkuName
: SkuInfo
},
773 ## Retrieve dynamic HII PCD settings
775 # @param Type PCD type
777 # @retval a dict object contains settings of given PCD type
779 def _GetDynamicHiiPcd(self
, Type
):
782 # tdict is a special dict kind of type, used for selecting correct
783 # PCD settings for certain ARCH and SKU
785 PcdDict
= tdict(True, 4)
787 RecordList
= self
._RawData
[Type
, self
._Arch
]
788 # Find out all possible PCD candidates for self._Arch
789 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
790 PcdSet
.add((PcdCName
, TokenSpaceGuid
, Dummy4
))
791 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
792 # Remove redundant PCD candidates, per the ARCH and SKU
793 for PcdCName
, TokenSpaceGuid
, Dummy4
in PcdSet
:
794 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
797 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
798 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
799 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
802 self
._PCD
_TYPE
_STRING
_[Type
],
807 {self
.SkuName
: SkuInfo
},
813 ## Retrieve dynamic VPD PCD settings
815 # @param Type PCD type
817 # @retval a dict object contains settings of given PCD type
819 def _GetDynamicVpdPcd(self
, Type
):
822 # tdict is a special dict kind of type, used for selecting correct
823 # PCD settings for certain ARCH and SKU
825 PcdDict
= tdict(True, 4)
827 # Find out all possible PCD candidates for self._Arch
828 RecordList
= self
._RawData
[Type
, self
._Arch
]
829 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
830 PcdList
.append((PcdCName
, TokenSpaceGuid
, Dummy4
))
831 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
832 # Remove redundant PCD candidates, per the ARCH and SKU
833 for PcdCName
, TokenSpaceGuid
, Dummy4
in PcdList
:
834 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
838 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
839 # For the Integer & Boolean type, the optional data can only be InitialValue.
840 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
841 # until the DEC parser has been called.
843 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
845 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
846 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
849 self
._PCD
_TYPE
_STRING
_[Type
],
854 {self
.SkuName
: SkuInfo
},
860 ## Add external modules
862 # The external modules are mostly those listed in FDF file, which don't
865 # @param FilePath The path of module description file
867 def AddModule(self
, FilePath
):
868 FilePath
= NormPath(FilePath
)
869 if FilePath
not in self
.Modules
:
870 Module
= ModuleBuildClassObject()
871 Module
.MetaFile
= FilePath
872 self
.Modules
.append(Module
)
876 # The external PCDs are mostly those listed in FDF file to specify address
877 # or offset information.
879 # @param Name Name of the PCD
880 # @param Guid Token space guid of the PCD
881 # @param Value Value of the PCD
883 def AddPcd(self
, Name
, Guid
, Value
):
884 if (Name
, Guid
) not in self
.Pcds
:
885 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
886 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
888 _Macros
= property(_GetMacros
)
889 Arch
= property(_GetArch
, _SetArch
)
890 Platform
= property(_GetPlatformName
)
891 PlatformName
= property(_GetPlatformName
)
892 Guid
= property(_GetFileGuid
)
893 Version
= property(_GetVersion
)
894 DscSpecification
= property(_GetDscSpec
)
895 OutputDirectory
= property(_GetOutpuDir
)
896 SupArchList
= property(_GetSupArch
)
897 BuildTargets
= property(_GetBuildTarget
)
898 SkuName
= property(_GetSkuName
, _SetSkuName
)
899 FlashDefinition
= property(_GetFdfFile
)
900 BuildNumber
= property(_GetBuildNumber
)
901 MakefileName
= property(_GetMakefileName
)
902 BsBaseAddress
= property(_GetBsBaseAddress
)
903 RtBaseAddress
= property(_GetRtBaseAddress
)
904 LoadFixAddress
= property(_GetLoadFixAddress
)
905 RFCLanguages
= property(_GetRFCLanguages
)
906 ISOLanguages
= property(_GetISOLanguages
)
907 VpdToolGuid
= property(_GetVpdToolGuid
)
908 SkuIds
= property(_GetSkuIds
)
909 Modules
= property(_GetModules
)
910 LibraryInstances
= property(_GetLibraryInstances
)
911 LibraryClasses
= property(_GetLibraryClasses
)
912 Pcds
= property(_GetPcds
)
913 BuildOptions
= property(_GetBuildOptions
)
915 ## Platform build information from DEC file
917 # This class is used to retrieve information stored in database and convert them
918 # into PackageBuildClassObject form for easier use for AutoGen.
920 class DecBuildData(PackageBuildClassObject
):
921 # dict used to convert PCD type in database to string used by build tool
922 _PCD_TYPE_STRING_
= {
923 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
924 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
925 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
926 MODEL_PCD_DYNAMIC
: "Dynamic",
927 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
928 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
929 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
930 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
931 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
932 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
933 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
936 # dict used to convert part of [Defines] to members of DecBuildData directly
941 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
942 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
943 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
944 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
948 ## Constructor of DecBuildData
950 # Initialize object of DecBuildData
952 # @param FilePath The path of package description file
953 # @param RawData The raw data of DEC file
954 # @param BuildDataBase Database used to retrieve module information
955 # @param Arch The target architecture
956 # @param Platform (not used for DecBuildData)
957 # @param Macros Macros used for replacement in DSC file
959 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
961 self
._PackageDir
= File
.Dir
962 self
._RawData
= RawData
963 self
._Bdb
= BuildDataBase
965 self
._Target
= Target
966 self
._Toolchain
= Toolchain
970 def __setitem__(self
, key
, value
):
971 self
.__dict
__[self
._PROPERTY
_[key
]] = value
974 def __getitem__(self
, key
):
975 return self
.__dict
__[self
._PROPERTY
_[key
]]
978 def __contains__(self
, key
):
979 return key
in self
._PROPERTY
_
981 ## Set all internal used members of DecBuildData to None
984 self
._PackageName
= None
987 self
._PkgUniFile
= None
988 self
._Protocols
= None
991 self
._Includes
= None
992 self
._LibraryClasses
= None
996 ## Get current effective macros
997 def _GetMacros(self
):
998 if self
.__Macros
== None:
1000 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1001 return self
.__Macros
1009 # Changing the default ARCH to another may affect all other information
1010 # because all information in a platform may be ARCH-related. That's
1011 # why we need to clear all internal used members, in order to cause all
1012 # information to be re-retrieved.
1014 # @param Value The value of ARCH
1016 def _SetArch(self
, Value
):
1017 if self
._Arch
== Value
:
1022 ## Retrieve all information in [Defines] section
1024 # (Retriving all [Defines] information in one-shot is just to save time.)
1026 def _GetHeaderInfo(self
):
1027 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1028 for Record
in RecordList
:
1031 self
[Name
] = Record
[2]
1032 self
._Header
= 'DUMMY'
1034 ## Retrieve package name
1035 def _GetPackageName(self
):
1036 if self
._PackageName
== None:
1037 if self
._Header
== None:
1038 self
._GetHeaderInfo
()
1039 if self
._PackageName
== None:
1040 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1041 return self
._PackageName
1043 ## Retrieve file guid
1044 def _GetFileGuid(self
):
1045 if self
._Guid
== None:
1046 if self
._Header
== None:
1047 self
._GetHeaderInfo
()
1048 if self
._Guid
== None:
1049 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1052 ## Retrieve package version
1053 def _GetVersion(self
):
1054 if self
._Version
== None:
1055 if self
._Header
== None:
1056 self
._GetHeaderInfo
()
1057 if self
._Version
== None:
1059 return self
._Version
1061 ## Retrieve protocol definitions (name/value pairs)
1062 def _GetProtocol(self
):
1063 if self
._Protocols
== None:
1065 # tdict is a special kind of dict, used for selecting correct
1066 # protocol defition for given ARCH
1068 ProtocolDict
= tdict(True)
1070 # find out all protocol definitions for specific and 'common' arch
1071 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1072 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1073 if Name
not in NameList
:
1074 NameList
.append(Name
)
1075 ProtocolDict
[Arch
, Name
] = Guid
1076 # use sdict to keep the order
1077 self
._Protocols
= sdict()
1078 for Name
in NameList
:
1080 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1081 # will automatically turn to 'common' ARCH for trying
1083 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1084 return self
._Protocols
1086 ## Retrieve PPI definitions (name/value pairs)
1088 if self
._Ppis
== None:
1090 # tdict is a special kind of dict, used for selecting correct
1091 # PPI defition for given ARCH
1093 PpiDict
= tdict(True)
1095 # find out all PPI definitions for specific arch and 'common' arch
1096 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1097 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1098 if Name
not in NameList
:
1099 NameList
.append(Name
)
1100 PpiDict
[Arch
, Name
] = Guid
1101 # use sdict to keep the order
1102 self
._Ppis
= sdict()
1103 for Name
in NameList
:
1105 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1106 # will automatically turn to 'common' ARCH for trying
1108 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1111 ## Retrieve GUID definitions (name/value pairs)
1113 if self
._Guids
== None:
1115 # tdict is a special kind of dict, used for selecting correct
1116 # GUID defition for given ARCH
1118 GuidDict
= tdict(True)
1120 # find out all protocol definitions for specific and 'common' arch
1121 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1122 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1123 if Name
not in NameList
:
1124 NameList
.append(Name
)
1125 GuidDict
[Arch
, Name
] = Guid
1126 # use sdict to keep the order
1127 self
._Guids
= sdict()
1128 for Name
in NameList
:
1130 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1131 # will automatically turn to 'common' ARCH for trying
1133 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1136 ## Retrieve public include paths declared in this package
1137 def _GetInclude(self
):
1138 if self
._Includes
== None:
1140 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1141 Macros
= self
._Macros
1142 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1143 for Record
in RecordList
:
1144 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1147 ErrorCode
, ErrorInfo
= File
.Validate()
1149 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1151 # avoid duplicate include path
1152 if File
not in self
._Includes
:
1153 self
._Includes
.append(File
)
1154 return self
._Includes
1156 ## Retrieve library class declarations (not used in build at present)
1157 def _GetLibraryClass(self
):
1158 if self
._LibraryClasses
== None:
1160 # tdict is a special kind of dict, used for selecting correct
1161 # library class declaration for given ARCH
1163 LibraryClassDict
= tdict(True)
1164 LibraryClassSet
= set()
1165 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1166 Macros
= self
._Macros
1167 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1168 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1169 # check the file validation
1170 ErrorCode
, ErrorInfo
= File
.Validate()
1172 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1173 LibraryClassSet
.add(LibraryClass
)
1174 LibraryClassDict
[Arch
, LibraryClass
] = File
1175 self
._LibraryClasses
= sdict()
1176 for LibraryClass
in LibraryClassSet
:
1177 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1178 return self
._LibraryClasses
1180 ## Retrieve PCD declarations
1182 if self
._Pcds
== None:
1183 self
._Pcds
= sdict()
1184 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1185 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1186 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1187 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1188 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1191 ## Retrieve PCD declarations for given type
1192 def _GetPcd(self
, Type
):
1195 # tdict is a special kind of dict, used for selecting correct
1196 # PCD declaration for given ARCH
1198 PcdDict
= tdict(True, 3)
1199 # for summarizing PCD
1201 # find out all PCDs of the 'type'
1202 RecordList
= self
._RawData
[Type
, self
._Arch
]
1203 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1204 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1205 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1207 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1209 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1210 # will automatically turn to 'common' ARCH and try again
1212 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1216 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1218 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1221 self
._PCD
_TYPE
_STRING
_[Type
],
1233 _Macros
= property(_GetMacros
)
1234 Arch
= property(_GetArch
, _SetArch
)
1235 PackageName
= property(_GetPackageName
)
1236 Guid
= property(_GetFileGuid
)
1237 Version
= property(_GetVersion
)
1239 Protocols
= property(_GetProtocol
)
1240 Ppis
= property(_GetPpi
)
1241 Guids
= property(_GetGuid
)
1242 Includes
= property(_GetInclude
)
1243 LibraryClasses
= property(_GetLibraryClass
)
1244 Pcds
= property(_GetPcds
)
1246 ## Module build information from INF file
1248 # This class is used to retrieve information stored in database and convert them
1249 # into ModuleBuildClassObject form for easier use for AutoGen.
1251 class InfBuildData(ModuleBuildClassObject
):
1252 # dict used to convert PCD type in database to string used by build tool
1253 _PCD_TYPE_STRING_
= {
1254 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1255 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1256 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1257 MODEL_PCD_DYNAMIC
: "Dynamic",
1258 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1259 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1260 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1261 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1262 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1263 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1264 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1267 # dict used to convert part of [Defines] to members of InfBuildData directly
1272 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1273 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1274 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1278 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1279 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1280 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1281 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1282 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1283 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1284 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1285 TAB_INF_DEFINES_VERSION
: "_Version",
1286 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1287 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1289 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1292 # dict used to convert Component type to Module type
1295 "SECURITY_CORE" : "SEC",
1296 "PEI_CORE" : "PEI_CORE",
1297 "COMBINED_PEIM_DRIVER" : "PEIM",
1298 "PIC_PEIM" : "PEIM",
1299 "RELOCATABLE_PEIM" : "PEIM",
1300 "PE32_PEIM" : "PEIM",
1301 "BS_DRIVER" : "DXE_DRIVER",
1302 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1303 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1304 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1305 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1306 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1307 # "BS_DRIVER" : "UEFI_DRIVER",
1308 "APPLICATION" : "UEFI_APPLICATION",
1312 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1313 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1314 # dict used to convert old tool name used in [nmake] section to new ones
1322 ## Constructor of DscBuildData
1324 # Initialize object of DscBuildData
1326 # @param FilePath The path of platform description file
1327 # @param RawData The raw data of DSC file
1328 # @param BuildDataBase Database used to retrieve module/package information
1329 # @param Arch The target architecture
1330 # @param Platform The name of platform employing this module
1331 # @param Macros Macros used for replacement in DSC file
1333 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1334 self
.MetaFile
= FilePath
1335 self
._ModuleDir
= FilePath
.Dir
1336 self
._RawData
= RawData
1337 self
._Bdb
= BuildDatabase
1339 self
._Target
= Target
1340 self
._Toolchain
= Toolchain
1341 self
._Platform
= 'COMMON'
1342 self
._SourceOverridePath
= None
1343 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1344 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1348 def __setitem__(self
, key
, value
):
1349 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1352 def __getitem__(self
, key
):
1353 return self
.__dict
__[self
._PROPERTY
_[key
]]
1355 ## "in" test support
1356 def __contains__(self
, key
):
1357 return key
in self
._PROPERTY
_
1359 ## Set all internal used members of InfBuildData to None
1361 self
._Header
_ = None
1362 self
._AutoGenVersion
= None
1363 self
._BaseName
= None
1364 self
._DxsFile
= None
1365 self
._ModuleType
= None
1366 self
._ComponentType
= None
1367 self
._BuildType
= None
1369 self
._Version
= None
1370 self
._PcdIsDriver
= None
1371 self
._BinaryModule
= None
1373 self
._MakefileName
= None
1374 self
._CustomMakefile
= None
1375 self
._Specification
= None
1376 self
._LibraryClass
= None
1377 self
._ModuleEntryPointList
= None
1378 self
._ModuleUnloadImageList
= None
1379 self
._ConstructorList
= None
1380 self
._DestructorList
= None
1382 self
._Binaries
= None
1383 self
._Sources
= None
1384 self
._LibraryClasses
= None
1385 self
._Libraries
= None
1386 self
._Protocols
= None
1389 self
._Includes
= None
1390 self
._Packages
= None
1392 self
._BuildOptions
= None
1394 self
._DepexExpression
= None
1395 self
.__Macros
= None
1397 ## Get current effective macros
1398 def _GetMacros(self
):
1399 if self
.__Macros
== None:
1401 # EDK_GLOBAL defined macros can be applied to EDK module
1402 if self
.AutoGenVersion
< 0x00010005:
1403 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1404 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1405 return self
.__Macros
1413 # Changing the default ARCH to another may affect all other information
1414 # because all information in a platform may be ARCH-related. That's
1415 # why we need to clear all internal used members, in order to cause all
1416 # information to be re-retrieved.
1418 # @param Value The value of ARCH
1420 def _SetArch(self
, Value
):
1421 if self
._Arch
== Value
:
1426 ## Return the name of platform employing this module
1427 def _GetPlatform(self
):
1428 return self
._Platform
1430 ## Change the name of platform employing this module
1432 # Changing the default name of platform to another may affect some information
1433 # because they may be PLATFORM-related. That's why we need to clear all internal
1434 # used members, in order to cause all information to be re-retrieved.
1436 def _SetPlatform(self
, Value
):
1437 if self
._Platform
== Value
:
1439 self
._Platform
= Value
1442 ## Retrieve all information in [Defines] section
1444 # (Retriving all [Defines] information in one-shot is just to save time.)
1446 def _GetHeaderInfo(self
):
1447 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1448 for Record
in RecordList
:
1449 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1450 # items defined _PROPERTY_ don't need additional processing
1453 # some special items in [Defines] section need special treatment
1454 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1455 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1456 Name
= 'UEFI_SPECIFICATION_VERSION'
1457 if self
._Specification
== None:
1458 self
._Specification
= sdict()
1459 self
._Specification
[Name
] = GetHexVerValue(Value
)
1460 if self
._Specification
[Name
] == None:
1461 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1462 "'%s' format is not supported for %s" % (Value
, Name
),
1463 File
=self
.MetaFile
, Line
=Record
[-1])
1464 elif Name
== 'LIBRARY_CLASS':
1465 if self
._LibraryClass
== None:
1466 self
._LibraryClass
= []
1467 ValueList
= GetSplitValueList(Value
)
1468 LibraryClass
= ValueList
[0]
1469 if len(ValueList
) > 1:
1470 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1472 SupModuleList
= SUP_MODULE_LIST
1473 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1474 elif Name
== 'ENTRY_POINT':
1475 if self
._ModuleEntryPointList
== None:
1476 self
._ModuleEntryPointList
= []
1477 self
._ModuleEntryPointList
.append(Value
)
1478 elif Name
== 'UNLOAD_IMAGE':
1479 if self
._ModuleUnloadImageList
== None:
1480 self
._ModuleUnloadImageList
= []
1483 self
._ModuleUnloadImageList
.append(Value
)
1484 elif Name
== 'CONSTRUCTOR':
1485 if self
._ConstructorList
== None:
1486 self
._ConstructorList
= []
1489 self
._ConstructorList
.append(Value
)
1490 elif Name
== 'DESTRUCTOR':
1491 if self
._DestructorList
== None:
1492 self
._DestructorList
= []
1495 self
._DestructorList
.append(Value
)
1496 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1497 TokenList
= GetSplitValueList(Value
)
1498 if self
._CustomMakefile
== None:
1499 self
._CustomMakefile
= {}
1500 if len(TokenList
) < 2:
1501 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1502 self
._CustomMakefile
['GCC'] = TokenList
[0]
1504 if TokenList
[0] not in ['MSFT', 'GCC']:
1505 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1506 "No supported family [%s]" % TokenList
[0],
1507 File
=self
.MetaFile
, Line
=Record
[-1])
1508 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1510 if self
._Defs
== None:
1511 self
._Defs
= sdict()
1512 self
._Defs
[Name
] = Value
1515 # Retrieve information in sections specific to Edk.x modules
1517 if self
.AutoGenVersion
>= 0x00010005:
1518 if not self
._ModuleType
:
1519 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1520 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1521 if self
._ModuleType
not in SUP_MODULE_LIST
:
1522 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1523 for Record
in RecordList
:
1525 if Name
== "MODULE_TYPE":
1528 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1529 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1530 File
=self
.MetaFile
, Line
=LineNo
)
1531 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1532 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1533 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
)
1534 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1535 and 'PCI_CLASS_CODE' in self
._Defs
:
1536 self
._BuildType
= 'UEFI_OPTIONROM'
1537 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1538 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1539 self
._BuildType
= 'UEFI_HII'
1541 self
._BuildType
= self
._ModuleType
.upper()
1544 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1545 # check the file validation
1546 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1548 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1549 File
=self
.MetaFile
, Line
=LineNo
)
1550 if self
.Sources
== None:
1552 self
._Sources
.append(File
)
1554 if not self
._ComponentType
:
1555 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1556 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1557 self
._BuildType
= self
._ComponentType
.upper()
1558 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1559 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1560 if self
._ComponentType
== 'LIBRARY':
1561 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1562 # make use some [nmake] section macros
1563 Macros
= self
._Macros
1564 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1565 Macros
['PROCESSOR'] = self
._Arch
1566 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1567 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1568 Value
= ReplaceMacro(Value
, Macros
, True)
1569 if Name
== "IMAGE_ENTRY_POINT":
1570 if self
._ModuleEntryPointList
== None:
1571 self
._ModuleEntryPointList
= []
1572 self
._ModuleEntryPointList
.append(Value
)
1573 elif Name
== "DPX_SOURCE":
1574 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1575 # check the file validation
1576 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1578 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1579 File
=self
.MetaFile
, Line
=LineNo
)
1580 if self
.Sources
== None:
1582 self
._Sources
.append(File
)
1584 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1585 if len(ToolList
) == 0 or len(ToolList
) != 1:
1587 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1588 # File=self.MetaFile, Line=LineNo)
1590 if self
._BuildOptions
== None:
1591 self
._BuildOptions
= sdict()
1593 if ToolList
[0] in self
._TOOL
_CODE
_:
1594 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1597 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1598 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1599 #ignore not replaced macros in value
1600 ValueList
= GetSplitList(' ' + Value
, '/D')
1601 Dummy
= ValueList
[0]
1602 for Index
in range(1, len(ValueList
)):
1603 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1605 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1606 Value
= Dummy
.strip()
1607 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1608 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1610 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1611 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1612 # set _Header to non-None in order to avoid database re-querying
1613 self
._Header
_ = 'DUMMY'
1615 ## Retrieve file version
1616 def _GetInfVersion(self
):
1617 if self
._AutoGenVersion
== None:
1618 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1619 for Record
in RecordList
:
1620 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1621 self
._AutoGenVersion
= int(Record
[2], 0)
1623 if self
._AutoGenVersion
== None:
1624 self
._AutoGenVersion
= 0x00010000
1625 return self
._AutoGenVersion
1627 ## Retrieve BASE_NAME
1628 def _GetBaseName(self
):
1629 if self
._BaseName
== None:
1630 if self
._Header
_ == None:
1631 self
._GetHeaderInfo
()
1632 if self
._BaseName
== None:
1633 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1634 return self
._BaseName
1637 def _GetDxsFile(self
):
1638 if self
._DxsFile
== None:
1639 if self
._Header
_ == None:
1640 self
._GetHeaderInfo
()
1641 if self
._DxsFile
== None:
1643 return self
._DxsFile
1645 ## Retrieve MODULE_TYPE
1646 def _GetModuleType(self
):
1647 if self
._ModuleType
== None:
1648 if self
._Header
_ == None:
1649 self
._GetHeaderInfo
()
1650 if self
._ModuleType
== None:
1651 self
._ModuleType
= 'BASE'
1652 if self
._ModuleType
not in SUP_MODULE_LIST
:
1653 self
._ModuleType
= "USER_DEFINED"
1654 return self
._ModuleType
1656 ## Retrieve COMPONENT_TYPE
1657 def _GetComponentType(self
):
1658 if self
._ComponentType
== None:
1659 if self
._Header
_ == None:
1660 self
._GetHeaderInfo
()
1661 if self
._ComponentType
== None:
1662 self
._ComponentType
= 'USER_DEFINED'
1663 return self
._ComponentType
1665 ## Retrieve "BUILD_TYPE"
1666 def _GetBuildType(self
):
1667 if self
._BuildType
== None:
1668 if self
._Header
_ == None:
1669 self
._GetHeaderInfo
()
1670 if not self
._BuildType
:
1671 self
._BuildType
= "BASE"
1672 return self
._BuildType
1674 ## Retrieve file guid
1675 def _GetFileGuid(self
):
1676 if self
._Guid
== None:
1677 if self
._Header
_ == None:
1678 self
._GetHeaderInfo
()
1679 if self
._Guid
== None:
1680 self
._Guid
= '00000000-0000-0000-000000000000'
1683 ## Retrieve module version
1684 def _GetVersion(self
):
1685 if self
._Version
== None:
1686 if self
._Header
_ == None:
1687 self
._GetHeaderInfo
()
1688 if self
._Version
== None:
1689 self
._Version
= '0.0'
1690 return self
._Version
1692 ## Retrieve PCD_IS_DRIVER
1693 def _GetPcdIsDriver(self
):
1694 if self
._PcdIsDriver
== None:
1695 if self
._Header
_ == None:
1696 self
._GetHeaderInfo
()
1697 if self
._PcdIsDriver
== None:
1698 self
._PcdIsDriver
= ''
1699 return self
._PcdIsDriver
1702 def _GetShadow(self
):
1703 if self
._Shadow
== None:
1704 if self
._Header
_ == None:
1705 self
._GetHeaderInfo
()
1706 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1709 self
._Shadow
= False
1712 ## Retrieve CUSTOM_MAKEFILE
1713 def _GetMakefile(self
):
1714 if self
._CustomMakefile
== None:
1715 if self
._Header
_ == None:
1716 self
._GetHeaderInfo
()
1717 if self
._CustomMakefile
== None:
1718 self
._CustomMakefile
= {}
1719 return self
._CustomMakefile
1721 ## Retrieve EFI_SPECIFICATION_VERSION
1723 if self
._Specification
== None:
1724 if self
._Header
_ == None:
1725 self
._GetHeaderInfo
()
1726 if self
._Specification
== None:
1727 self
._Specification
= {}
1728 return self
._Specification
1730 ## Retrieve LIBRARY_CLASS
1731 def _GetLibraryClass(self
):
1732 if self
._LibraryClass
== None:
1733 if self
._Header
_ == None:
1734 self
._GetHeaderInfo
()
1735 if self
._LibraryClass
== None:
1736 self
._LibraryClass
= []
1737 return self
._LibraryClass
1739 ## Retrieve ENTRY_POINT
1740 def _GetEntryPoint(self
):
1741 if self
._ModuleEntryPointList
== None:
1742 if self
._Header
_ == None:
1743 self
._GetHeaderInfo
()
1744 if self
._ModuleEntryPointList
== None:
1745 self
._ModuleEntryPointList
= []
1746 return self
._ModuleEntryPointList
1748 ## Retrieve UNLOAD_IMAGE
1749 def _GetUnloadImage(self
):
1750 if self
._ModuleUnloadImageList
== None:
1751 if self
._Header
_ == None:
1752 self
._GetHeaderInfo
()
1753 if self
._ModuleUnloadImageList
== None:
1754 self
._ModuleUnloadImageList
= []
1755 return self
._ModuleUnloadImageList
1757 ## Retrieve CONSTRUCTOR
1758 def _GetConstructor(self
):
1759 if self
._ConstructorList
== None:
1760 if self
._Header
_ == None:
1761 self
._GetHeaderInfo
()
1762 if self
._ConstructorList
== None:
1763 self
._ConstructorList
= []
1764 return self
._ConstructorList
1766 ## Retrieve DESTRUCTOR
1767 def _GetDestructor(self
):
1768 if self
._DestructorList
== None:
1769 if self
._Header
_ == None:
1770 self
._GetHeaderInfo
()
1771 if self
._DestructorList
== None:
1772 self
._DestructorList
= []
1773 return self
._DestructorList
1775 ## Retrieve definies other than above ones
1776 def _GetDefines(self
):
1777 if self
._Defs
== None:
1778 if self
._Header
_ == None:
1779 self
._GetHeaderInfo
()
1780 if self
._Defs
== None:
1781 self
._Defs
= sdict()
1784 ## Retrieve binary files
1785 def _GetBinaryFiles(self
):
1786 if self
._Binaries
== None:
1788 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
1789 Macros
= self
._Macros
1790 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1791 Macros
['PROCESSOR'] = self
._Arch
1792 for Record
in RecordList
:
1793 FileType
= Record
[0]
1798 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
1800 Target
= TokenList
[0]
1801 if len(TokenList
) > 1:
1802 FeatureFlag
= Record
[1:]
1804 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
1805 # check the file validation
1806 ErrorCode
, ErrorInfo
= File
.Validate()
1808 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1809 self
._Binaries
.append(File
)
1810 return self
._Binaries
1812 ## Retrieve source files
1813 def _GetSourceFiles(self
):
1814 if self
._Sources
== None:
1816 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
1817 Macros
= self
._Macros
1818 for Record
in RecordList
:
1820 ToolChainFamily
= Record
[1]
1822 ToolCode
= Record
[3]
1823 FeatureFlag
= Record
[4]
1824 if self
.AutoGenVersion
< 0x00010005:
1825 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1826 Macros
['PROCESSOR'] = self
._Arch
1827 # old module source files (Edk)
1828 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
1829 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1830 # check the file validation
1831 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
1833 if File
.Ext
.lower() == '.h':
1834 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
1835 File
=self
.MetaFile
, Line
=LineNo
)
1838 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
1840 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
1841 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1842 # check the file validation
1843 ErrorCode
, ErrorInfo
= File
.Validate()
1845 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1847 self
._Sources
.append(File
)
1848 return self
._Sources
1850 ## Retrieve library classes employed by this module
1851 def _GetLibraryClassUses(self
):
1852 if self
._LibraryClasses
== None:
1853 self
._LibraryClasses
= sdict()
1854 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
1855 for Record
in RecordList
:
1857 Instance
= Record
[1]
1859 Instance
= NormPath(Instance
, self
._Macros
)
1860 self
._LibraryClasses
[Lib
] = Instance
1861 return self
._LibraryClasses
1863 ## Retrieve library names (for Edk.x style of modules)
1864 def _GetLibraryNames(self
):
1865 if self
._Libraries
== None:
1866 self
._Libraries
= []
1867 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
1868 for Record
in RecordList
:
1869 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
1870 # in case of name with '.lib' extension, which is unusual in Edk.x inf
1871 LibraryName
= os
.path
.splitext(LibraryName
)[0]
1872 if LibraryName
not in self
._Libraries
:
1873 self
._Libraries
.append(LibraryName
)
1874 return self
._Libraries
1876 ## Retrieve protocols consumed/produced by this module
1877 def _GetProtocols(self
):
1878 if self
._Protocols
== None:
1879 self
._Protocols
= sdict()
1880 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
1881 for Record
in RecordList
:
1883 Value
= ProtocolValue(CName
, self
.Packages
)
1885 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1886 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1887 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
1888 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1889 self
._Protocols
[CName
] = Value
1890 return self
._Protocols
1892 ## Retrieve PPIs consumed/produced by this module
1894 if self
._Ppis
== None:
1895 self
._Ppis
= sdict()
1896 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
1897 for Record
in RecordList
:
1899 Value
= PpiValue(CName
, self
.Packages
)
1901 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1902 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1903 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
1904 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1905 self
._Ppis
[CName
] = Value
1908 ## Retrieve GUIDs consumed/produced by this module
1909 def _GetGuids(self
):
1910 if self
._Guids
== None:
1911 self
._Guids
= sdict()
1912 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
1913 for Record
in RecordList
:
1915 Value
= GuidValue(CName
, self
.Packages
)
1917 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1918 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1919 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
1920 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1921 self
._Guids
[CName
] = Value
1924 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
1925 def _GetIncludes(self
):
1926 if self
._Includes
== None:
1928 if self
._SourceOverridePath
:
1929 self
._Includes
.append(self
._SourceOverridePath
)
1931 Macros
= self
._Macros
1932 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
1933 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
1935 Macros
['PROCESSOR'] = self
._Arch
1936 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
1937 for Record
in RecordList
:
1938 if Record
[0].find('EDK_SOURCE') > -1:
1939 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
1940 File
= NormPath(Record
[0], self
._Macros
)
1942 File
= os
.path
.join(self
._ModuleDir
, File
)
1944 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1945 File
= RealPath(os
.path
.normpath(File
))
1947 self
._Includes
.append(File
)
1949 #TRICK: let compiler to choose correct header file
1950 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
1951 File
= NormPath(Record
[0], self
._Macros
)
1953 File
= os
.path
.join(self
._ModuleDir
, File
)
1955 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1956 File
= RealPath(os
.path
.normpath(File
))
1958 self
._Includes
.append(File
)
1960 File
= NormPath(Record
[0], Macros
)
1962 File
= os
.path
.join(self
._ModuleDir
, File
)
1964 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1965 File
= RealPath(os
.path
.normpath(File
))
1967 self
._Includes
.append(File
)
1968 return self
._Includes
1970 ## Retrieve packages this module depends on
1971 def _GetPackages(self
):
1972 if self
._Packages
== None:
1974 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
1975 Macros
= self
._Macros
1976 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
1977 for Record
in RecordList
:
1978 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
1980 # check the file validation
1981 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
1983 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1984 # parse this package now. we need it to get protocol/ppi/guid value
1985 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
1986 self
._Packages
.append(Package
)
1987 return self
._Packages
1989 ## Retrieve PCDs used in this module
1991 if self
._Pcds
== None:
1992 self
._Pcds
= sdict()
1993 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1994 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1995 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1996 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1997 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2000 ## Retrieve build options specific to this module
2001 def _GetBuildOptions(self
):
2002 if self
._BuildOptions
== None:
2003 self
._BuildOptions
= sdict()
2004 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2005 for Record
in RecordList
:
2006 ToolChainFamily
= Record
[0]
2007 ToolChain
= Record
[1]
2009 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2010 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2012 # concatenate the option string if they're for the same tool
2013 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2014 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2015 return self
._BuildOptions
2017 ## Retrieve dependency expression
2018 def _GetDepex(self
):
2019 if self
._Depex
== None:
2020 self
._Depex
= tdict(False, 2)
2021 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2023 # If the module has only Binaries and no Sources, then ignore [Depex]
2024 if self
.Sources
== None or self
.Sources
== []:
2025 if self
.Binaries
!= None and self
.Binaries
!= []:
2028 # PEIM and DXE drivers must have a valid [Depex] section
2029 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2030 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2031 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2032 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2033 % self
.ModuleType
, File
=self
.MetaFile
)
2036 for Record
in RecordList
:
2037 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2039 ModuleType
= Record
[4]
2040 TokenList
= DepexStr
.split()
2041 if (Arch
, ModuleType
) not in Depex
:
2042 Depex
[Arch
, ModuleType
] = []
2043 DepexList
= Depex
[Arch
, ModuleType
]
2044 for Token
in TokenList
:
2045 if Token
in DEPEX_SUPPORTED_OPCODE
:
2046 DepexList
.append(Token
)
2047 elif Token
.endswith(".inf"): # module file name
2048 ModuleFile
= os
.path
.normpath(Token
)
2049 Module
= self
.BuildDatabase
[ModuleFile
]
2051 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2052 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2053 DepexList
.append(Module
.Guid
)
2055 # get the GUID value now
2056 Value
= ProtocolValue(Token
, self
.Packages
)
2058 Value
= PpiValue(Token
, self
.Packages
)
2060 Value
= GuidValue(Token
, self
.Packages
)
2062 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2063 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2064 "Value of [%s] is not found in" % Token
,
2065 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2066 DepexList
.append(Value
)
2067 for Arch
, ModuleType
in Depex
:
2068 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2071 ## Retrieve depedency expression
2072 def _GetDepexExpression(self
):
2073 if self
._DepexExpression
== None:
2074 self
._DepexExpression
= tdict(False, 2)
2075 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2076 DepexExpression
= sdict()
2077 for Record
in RecordList
:
2078 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2080 ModuleType
= Record
[4]
2081 TokenList
= DepexStr
.split()
2082 if (Arch
, ModuleType
) not in DepexExpression
:
2083 DepexExpression
[Arch
, ModuleType
] = ''
2084 for Token
in TokenList
:
2085 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2086 for Arch
, ModuleType
in DepexExpression
:
2087 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2088 return self
._DepexExpression
2090 ## Retrieve PCD for given type
2091 def _GetPcd(self
, Type
):
2093 PcdDict
= tdict(True, 4)
2095 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2096 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Dummy1
, LineNo
in RecordList
:
2097 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2098 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2099 # get the guid value
2100 if TokenSpaceGuid
not in self
.Guids
:
2101 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2103 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2104 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2105 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2106 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2107 self
.Guids
[TokenSpaceGuid
] = Value
2109 # resolve PCD type, value, datum info, etc. by getting its definition from package
2110 for PcdCName
, TokenSpaceGuid
in PcdList
:
2111 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2114 ValueList
= AnalyzePcdData(Setting
)
2115 DefaultValue
= ValueList
[0]
2116 Pcd
= PcdClassObject(
2126 self
.Guids
[TokenSpaceGuid
]
2129 # get necessary info from package declaring this PCD
2130 for Package
in self
.Packages
:
2132 # 'dynamic' in INF means its type is determined by platform;
2133 # if platform doesn't give its type, use 'lowest' one in the
2134 # following order, if any
2136 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2138 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2139 if Type
== MODEL_PCD_DYNAMIC
:
2141 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2142 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2148 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2149 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2151 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2154 # Check whether the token value exist or not.
2156 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2160 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2161 File
=self
.MetaFile
, Line
=LineNo
,
2165 # Check hexadecimal token value length and format.
2167 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2168 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2169 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2173 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2174 File
=self
.MetaFile
, Line
=LineNo
,
2179 # Check decimal token value length and format.
2183 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2184 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2188 "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
)),
2189 File
=self
.MetaFile
, Line
=LineNo
,
2196 "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
)),
2197 File
=self
.MetaFile
, Line
=LineNo
,
2201 Pcd
.DatumType
= PcdInPackage
.DatumType
2202 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2203 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2204 if Pcd
.DefaultValue
in [None, '']:
2205 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2211 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2212 File
=self
.MetaFile
, Line
=LineNo
,
2213 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2215 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2219 _Macros
= property(_GetMacros
)
2220 Arch
= property(_GetArch
, _SetArch
)
2221 Platform
= property(_GetPlatform
, _SetPlatform
)
2223 AutoGenVersion
= property(_GetInfVersion
)
2224 BaseName
= property(_GetBaseName
)
2225 ModuleType
= property(_GetModuleType
)
2226 ComponentType
= property(_GetComponentType
)
2227 BuildType
= property(_GetBuildType
)
2228 Guid
= property(_GetFileGuid
)
2229 Version
= property(_GetVersion
)
2230 PcdIsDriver
= property(_GetPcdIsDriver
)
2231 Shadow
= property(_GetShadow
)
2232 CustomMakefile
= property(_GetMakefile
)
2233 Specification
= property(_GetSpec
)
2234 LibraryClass
= property(_GetLibraryClass
)
2235 ModuleEntryPointList
= property(_GetEntryPoint
)
2236 ModuleUnloadImageList
= property(_GetUnloadImage
)
2237 ConstructorList
= property(_GetConstructor
)
2238 DestructorList
= property(_GetDestructor
)
2239 Defines
= property(_GetDefines
)
2240 DxsFile
= property(_GetDxsFile
)
2242 Binaries
= property(_GetBinaryFiles
)
2243 Sources
= property(_GetSourceFiles
)
2244 LibraryClasses
= property(_GetLibraryClassUses
)
2245 Libraries
= property(_GetLibraryNames
)
2246 Protocols
= property(_GetProtocols
)
2247 Ppis
= property(_GetPpis
)
2248 Guids
= property(_GetGuids
)
2249 Includes
= property(_GetIncludes
)
2250 Packages
= property(_GetPackages
)
2251 Pcds
= property(_GetPcds
)
2252 BuildOptions
= property(_GetBuildOptions
)
2253 Depex
= property(_GetDepex
)
2254 DepexExpression
= property(_GetDepexExpression
)
2258 # This class defined the build database for all modules, packages and platform.
2259 # It will call corresponding parser for the given file if it cannot find it in
2262 # @param DbPath Path of database file
2263 # @param GlobalMacros Global macros used for replacement during file parsing
2264 # @prarm RenewDb=False Create new database file if it's already there
2266 class WorkspaceDatabase(object):
2268 # default database file path
2269 _DB_PATH_
= "Conf/.cache/build.db"
2272 # internal class used for call corresponding file parser and caching the result
2273 # to avoid unnecessary re-parsing
2275 class BuildObjectFactory(object):
2278 ".inf" : MODEL_FILE_INF
,
2279 ".dec" : MODEL_FILE_DEC
,
2280 ".dsc" : MODEL_FILE_DSC
,
2285 MODEL_FILE_INF
: InfParser
,
2286 MODEL_FILE_DEC
: DecParser
,
2287 MODEL_FILE_DSC
: DscParser
,
2290 # convert to xxxBuildData object
2292 MODEL_FILE_INF
: InfBuildData
,
2293 MODEL_FILE_DEC
: DecBuildData
,
2294 MODEL_FILE_DSC
: DscBuildData
,
2297 _CACHE_
= {} # (FilePath, Arch) : <object>
2300 def __init__(self
, WorkspaceDb
):
2301 self
.WorkspaceDb
= WorkspaceDb
2303 # key = (FilePath, Arch=None)
2304 def __contains__(self
, Key
):
2310 return (FilePath
, Arch
) in self
._CACHE
_
2312 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2313 def __getitem__(self
, Key
):
2315 KeyLength
= len(Key
)
2329 # if it's generated before, just return the cached one
2330 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2331 if Key
in self
._CACHE
_:
2332 return self
._CACHE
_[Key
]
2336 if Ext
not in self
._FILE
_TYPE
_:
2338 FileType
= self
._FILE
_TYPE
_[Ext
]
2339 if FileType
not in self
._GENERATOR
_:
2342 # get the parser ready for this file
2343 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2346 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2348 # alwasy do post-process, in case of macros change
2349 MetaFile
.DoPostProcess()
2350 # object the build is based on
2351 BuildObject
= self
._GENERATOR
_[FileType
](
2359 self
._CACHE
_[Key
] = BuildObject
2362 # placeholder for file format conversion
2363 class TransformObjectFactory
:
2364 def __init__(self
, WorkspaceDb
):
2365 self
.WorkspaceDb
= WorkspaceDb
2367 # key = FilePath, Arch
2368 def __getitem__(self
, Key
):
2371 ## Constructor of WorkspaceDatabase
2373 # @param DbPath Path of database file
2374 # @param GlobalMacros Global macros used for replacement during file parsing
2375 # @prarm RenewDb=False Create new database file if it's already there
2377 def __init__(self
, DbPath
, RenewDb
=False):
2378 self
._DbClosedFlag
= False
2380 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2382 # don't create necessary path for db in memory
2383 if DbPath
!= ':memory:':
2384 DbDir
= os
.path
.split(DbPath
)[0]
2385 if not os
.path
.exists(DbDir
):
2388 # remove db file in case inconsistency between db and file in file system
2389 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2392 # create db with optimized parameters
2393 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2394 self
.Conn
.execute("PRAGMA synchronous=OFF")
2395 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2396 self
.Conn
.execute("PRAGMA count_changes=OFF")
2397 self
.Conn
.execute("PRAGMA cache_size=8192")
2398 #self.Conn.execute("PRAGMA page_size=8192")
2400 # to avoid non-ascii character conversion issue
2401 self
.Conn
.text_factory
= str
2402 self
.Cur
= self
.Conn
.cursor()
2404 # create table for internal uses
2405 self
.TblDataModel
= TableDataModel(self
.Cur
)
2406 self
.TblFile
= TableFile(self
.Cur
)
2407 self
.Platform
= None
2409 # conversion object for build or file format conversion purpose
2410 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2411 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2413 ## Check whether workspace database need to be renew.
2414 # The renew reason maybe:
2415 # 1) If user force to renew;
2416 # 2) If user do not force renew, and
2417 # a) If the time of last modified python source is newer than database file;
2418 # b) If the time of last modified frozen executable file is newer than database file;
2420 # @param force User force renew database
2421 # @param DbPath The absolute path of workspace database file
2423 # @return Bool value for whether need renew workspace databse
2425 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2426 # if database does not exist, we need do nothing
2427 if not os
.path
.exists(DbPath
): return False
2429 # if user force to renew database, then not check whether database is out of date
2430 if force
: return True
2433 # Check the time of last modified source file or build.exe
2434 # if is newer than time of database, then database need to be re-created.
2436 timeOfToolModified
= 0
2437 if hasattr(sys
, "frozen"):
2438 exePath
= os
.path
.abspath(sys
.executable
)
2439 timeOfToolModified
= os
.stat(exePath
).st_mtime
2441 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2442 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2443 if rootPath
== "" or rootPath
== None:
2444 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2445 determine whether database file is out of date!\n")
2447 # walk the root path of source or build's binary to get the time last modified.
2449 for root
, dirs
, files
in os
.walk (rootPath
):
2451 # bypass source control folder
2452 if dir.lower() in [".svn", "_svn", "cvs"]:
2456 ext
= os
.path
.splitext(file)[1]
2457 if ext
.lower() == ".py": # only check .py files
2458 fd
= os
.stat(os
.path
.join(root
, file))
2459 if timeOfToolModified
< fd
.st_mtime
:
2460 timeOfToolModified
= fd
.st_mtime
2461 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2462 EdkLogger
.verbose("\nWorkspace database is out of data!")
2467 ## Initialize build database
2468 def InitDatabase(self
):
2469 EdkLogger
.verbose("\nInitialize build database started ...")
2474 self
.TblDataModel
.Create(False)
2475 self
.TblFile
.Create(False)
2478 # Initialize table DataModel
2480 self
.TblDataModel
.InitTable()
2481 EdkLogger
.verbose("Initialize build database ... DONE!")
2485 # @param Table: The instance of the table to be queried
2487 def QueryTable(self
, Table
):
2493 ## Close entire database
2496 # Close the connection and cursor
2499 if not self
._DbClosedFlag
:
2503 self
._DbClosedFlag
= True
2505 ## Summarize all packages in the database
2506 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2507 self
.Platform
= Platform
2509 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2511 # Get Package related to Modules
2513 for Module
in Pa
.Modules
:
2514 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2515 for Package
in ModuleObj
.Packages
:
2516 if Package
not in PackageList
:
2517 PackageList
.append(Package
)
2519 # Get Packages related to Libraries
2521 for Lib
in Pa
.LibraryInstances
:
2522 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2523 for Package
in LibObj
.Packages
:
2524 if Package
not in PackageList
:
2525 PackageList
.append(Package
)
2529 ## Summarize all platforms in the database
2530 def _GetPlatformList(self
):
2532 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2534 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2537 if Platform
!= None:
2538 PlatformList
.append(Platform
)
2541 PlatformList
= property(_GetPlatformList
)
2545 # This acts like the main() function for the script, unless it is 'import'ed into another
2548 if __name__
== '__main__':