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 *
38 ## Platform build information from DSC file
40 # This class is used to retrieve information stored in database and convert them
41 # into PlatformBuildClassObject form for easier use for AutoGen.
43 class DscBuildData(PlatformBuildClassObject
):
44 # dict used to convert PCD type in database to string used by build tool
46 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
47 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
48 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
49 MODEL_PCD_DYNAMIC
: "Dynamic",
50 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
51 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
52 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
53 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
54 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
55 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
56 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
59 # dict used to convert part of [Defines] to members of DscBuildData directly
64 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
65 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
66 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
67 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
68 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
69 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
70 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
71 #TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
72 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
73 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
74 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
75 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
76 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
77 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
78 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
81 # used to compose dummy library class name for those forced library instances
82 _NullLibraryNumber
= 0
84 ## Constructor of DscBuildData
86 # Initialize object of DscBuildData
88 # @param FilePath The path of platform description file
89 # @param RawData The raw data of DSC file
90 # @param BuildDataBase Database used to retrieve module/package information
91 # @param Arch The target architecture
92 # @param Platform (not used for DscBuildData)
93 # @param Macros Macros used for replacement in DSC file
95 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
96 self
.MetaFile
= FilePath
97 self
._RawData
= RawData
98 self
._Bdb
= BuildDataBase
100 self
._Target
= Target
101 self
._Toolchain
= Toolchain
105 def __setitem__(self
, key
, value
):
106 self
.__dict
__[self
._PROPERTY
_[key
]] = value
109 def __getitem__(self
, key
):
110 return self
.__dict
__[self
._PROPERTY
_[key
]]
113 def __contains__(self
, key
):
114 return key
in self
._PROPERTY
_
116 ## Set all internal used members of DscBuildData to None
119 self
._PlatformName
= None
122 self
._DscSpecification
= None
123 self
._OutputDirectory
= None
124 self
._SupArchList
= None
125 self
._BuildTargets
= None
127 self
._FlashDefinition
= None
128 self
._BuildNumber
= None
129 self
._MakefileName
= None
130 self
._BsBaseAddress
= None
131 self
._RtBaseAddress
= None
134 self
._LibraryInstances
= None
135 self
._LibraryClasses
= None
137 self
._BuildOptions
= None
138 self
._LoadFixAddress
= None
139 self
._RFCLanguages
= None
140 self
._ISOLanguages
= None
141 self
._VpdToolGuid
= None
144 ## Get current effective macros
145 def _GetMacros(self
):
146 if self
.__Macros
== None:
148 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
149 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
150 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
159 # Changing the default ARCH to another may affect all other information
160 # because all information in a platform may be ARCH-related. That's
161 # why we need to clear all internal used members, in order to cause all
162 # information to be re-retrieved.
164 # @param Value The value of ARCH
166 def _SetArch(self
, Value
):
167 if self
._Arch
== Value
:
172 ## Retrieve all information in [Defines] section
174 # (Retriving all [Defines] information in one-shot is just to save time.)
176 def _GetHeaderInfo(self
):
177 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
178 for Record
in RecordList
:
180 # items defined _PROPERTY_ don't need additional processing
182 self
[Name
] = Record
[2]
183 # some special items in [Defines] section need special treatment
184 elif Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
185 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
186 if ' ' in self
._OutputDirectory
:
187 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
188 File
=self
.MetaFile
, Line
=Record
[-1],
189 ExtraData
=self
._OutputDirectory
)
190 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
191 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
192 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
194 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
196 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
197 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
198 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
199 self
._BuildTargets
= GetSplitValueList(Record
[2])
200 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
201 if self
._SkuName
== None:
202 self
._SkuName
= Record
[2]
203 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
205 self
._LoadFixAddress
= int (Record
[2], 0)
207 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
208 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
209 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
210 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"',
211 File
=self
.MetaFile
, Line
=Record
[-1])
212 LanguageCodes
= Record
[2][1:-1]
213 if not LanguageCodes
:
214 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
215 File
=self
.MetaFile
, Line
=Record
[-1])
216 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
217 # check whether there is empty entries in the list
218 if None in LanguageList
:
219 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
220 File
=self
.MetaFile
, Line
=Record
[-1])
221 self
._RFCLanguages
= LanguageList
222 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
223 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
224 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
225 File
=self
.MetaFile
, Line
=Record
[-1])
226 LanguageCodes
= Record
[2][1:-1]
227 if not LanguageCodes
:
228 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
229 File
=self
.MetaFile
, Line
=Record
[-1])
230 if len(LanguageCodes
)%3:
231 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
232 File
=self
.MetaFile
, Line
=Record
[-1])
234 for i
in range(0, len(LanguageCodes
), 3):
235 LanguageList
.append(LanguageCodes
[i
:i
+3])
236 self
._ISOLanguages
= LanguageList
237 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
239 # try to convert GUID to a real UUID value to see whether the GUID is format
240 # for VPD_TOOL_GUID is correct.
245 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
246 self
._VpdToolGuid
= Record
[2]
247 # set _Header to non-None in order to avoid database re-querying
248 self
._Header
= 'DUMMY'
250 ## Retrieve platform name
251 def _GetPlatformName(self
):
252 if self
._PlatformName
== None:
253 if self
._Header
== None:
254 self
._GetHeaderInfo
()
255 if self
._PlatformName
== None:
256 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
257 return self
._PlatformName
259 ## Retrieve file guid
260 def _GetFileGuid(self
):
261 if self
._Guid
== None:
262 if self
._Header
== None:
263 self
._GetHeaderInfo
()
264 if self
._Guid
== None:
265 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No FILE_GUID", File
=self
.MetaFile
)
268 ## Retrieve platform version
269 def _GetVersion(self
):
270 if self
._Version
== None:
271 if self
._Header
== None:
272 self
._GetHeaderInfo
()
273 if self
._Version
== None:
277 ## Retrieve platform description file version
278 def _GetDscSpec(self
):
279 if self
._DscSpecification
== None:
280 if self
._Header
== None:
281 self
._GetHeaderInfo
()
282 if self
._DscSpecification
== None:
283 self
._DscSpecification
= ''
284 return self
._DscSpecification
286 ## Retrieve OUTPUT_DIRECTORY
287 def _GetOutpuDir(self
):
288 if self
._OutputDirectory
== None:
289 if self
._Header
== None:
290 self
._GetHeaderInfo
()
291 if self
._OutputDirectory
== None:
292 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
293 return self
._OutputDirectory
295 ## Retrieve SUPPORTED_ARCHITECTURES
296 def _GetSupArch(self
):
297 if self
._SupArchList
== None:
298 if self
._Header
== None:
299 self
._GetHeaderInfo
()
300 if self
._SupArchList
== None:
301 self
._SupArchList
= ARCH_LIST
302 return self
._SupArchList
304 ## Retrieve BUILD_TARGETS
305 def _GetBuildTarget(self
):
306 if self
._BuildTargets
== None:
307 if self
._Header
== None:
308 self
._GetHeaderInfo
()
309 if self
._BuildTargets
== None:
310 self
._BuildTargets
= ['DEBUG', 'RELEASE', 'NOOPT']
311 return self
._BuildTargets
313 ## Retrieve SKUID_IDENTIFIER
314 def _GetSkuName(self
):
315 if self
._SkuName
== None:
316 if self
._Header
== None:
317 self
._GetHeaderInfo
()
318 if self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
:
319 self
._SkuName
= 'DEFAULT'
322 ## Override SKUID_IDENTIFIER
323 def _SetSkuName(self
, Value
):
324 if Value
in self
.SkuIds
:
325 self
._SkuName
= Value
326 # Needs to re-retrieve the PCD information
329 def _GetFdfFile(self
):
330 if self
._FlashDefinition
== None:
331 if self
._Header
== None:
332 self
._GetHeaderInfo
()
333 if self
._FlashDefinition
== None:
334 self
._FlashDefinition
= ''
335 return self
._FlashDefinition
337 ## Retrieve FLASH_DEFINITION
338 def _GetBuildNumber(self
):
339 if self
._BuildNumber
== None:
340 if self
._Header
== None:
341 self
._GetHeaderInfo
()
342 if self
._BuildNumber
== None:
343 self
._BuildNumber
= ''
344 return self
._BuildNumber
346 ## Retrieve MAKEFILE_NAME
347 def _GetMakefileName(self
):
348 if self
._MakefileName
== None:
349 if self
._Header
== None:
350 self
._GetHeaderInfo
()
351 if self
._MakefileName
== None:
352 self
._MakefileName
= ''
353 return self
._MakefileName
355 ## Retrieve BsBaseAddress
356 def _GetBsBaseAddress(self
):
357 if self
._BsBaseAddress
== None:
358 if self
._Header
== None:
359 self
._GetHeaderInfo
()
360 if self
._BsBaseAddress
== None:
361 self
._BsBaseAddress
= ''
362 return self
._BsBaseAddress
364 ## Retrieve RtBaseAddress
365 def _GetRtBaseAddress(self
):
366 if self
._RtBaseAddress
== None:
367 if self
._Header
== None:
368 self
._GetHeaderInfo
()
369 if self
._RtBaseAddress
== None:
370 self
._RtBaseAddress
= ''
371 return self
._RtBaseAddress
373 ## Retrieve the top address for the load fix address
374 def _GetLoadFixAddress(self
):
375 if self
._LoadFixAddress
== None:
376 if self
._Header
== None:
377 self
._GetHeaderInfo
()
379 if self
._LoadFixAddress
== None:
380 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
383 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
385 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
388 # If command line defined, should override the value in DSC file.
390 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
392 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
394 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']))
396 if self
._LoadFixAddress
< 0:
397 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
398 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
399 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
401 return self
._LoadFixAddress
403 ## Retrieve RFCLanguage filter
404 def _GetRFCLanguages(self
):
405 if self
._RFCLanguages
== None:
406 if self
._Header
== None:
407 self
._GetHeaderInfo
()
408 if self
._RFCLanguages
== None:
409 self
._RFCLanguages
= []
410 return self
._RFCLanguages
412 ## Retrieve ISOLanguage filter
413 def _GetISOLanguages(self
):
414 if self
._ISOLanguages
== None:
415 if self
._Header
== None:
416 self
._GetHeaderInfo
()
417 if self
._ISOLanguages
== None:
418 self
._ISOLanguages
= []
419 return self
._ISOLanguages
420 ## Retrieve the GUID string for VPD tool
421 def _GetVpdToolGuid(self
):
422 if self
._VpdToolGuid
== None:
423 if self
._Header
== None:
424 self
._GetHeaderInfo
()
425 if self
._VpdToolGuid
== None:
426 self
._VpdToolGuid
= ''
427 return self
._VpdToolGuid
429 ## Retrieve [SkuIds] section information
430 def _GetSkuIds(self
):
431 if self
._SkuIds
== None:
432 self
._SkuIds
= sdict()
433 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
434 for Record
in RecordList
:
435 if Record
[0] in [None, '']:
436 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
437 File
=self
.MetaFile
, Line
=Record
[-1])
438 if Record
[1] in [None, '']:
439 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
440 File
=self
.MetaFile
, Line
=Record
[-1])
441 self
._SkuIds
[Record
[1]] = Record
[0]
442 if 'DEFAULT' not in self
._SkuIds
:
443 self
._SkuIds
['DEFAULT'] = '0'
446 ## Retrieve [Components] section information
447 def _GetModules(self
):
448 if self
._Modules
!= None:
451 self
._Modules
= sdict()
452 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
453 Macros
= self
._Macros
454 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
455 for Record
in RecordList
:
456 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
460 # check the file validation
461 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
463 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
466 if ModuleFile
in self
._Modules
:
467 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
469 Module
= ModuleBuildClassObject()
470 Module
.MetaFile
= ModuleFile
472 # get module override path
473 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
475 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
477 # Check if the source override path exists
478 if not os
.path
.isdir(Module
.SourceOverridePath
):
479 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
481 #Add to GlobalData Variables
482 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
484 # get module private library instance
485 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
486 for Record
in RecordList
:
487 LibraryClass
= Record
[0]
488 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
491 # check the file validation
492 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
494 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
497 if LibraryClass
== '' or LibraryClass
== 'NULL':
498 self
._NullLibraryNumber
+= 1
499 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
500 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
501 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
502 if LibraryPath
not in self
.LibraryInstances
:
503 self
.LibraryInstances
.append(LibraryPath
)
505 # get module private PCD setting
506 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
507 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
508 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
509 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
510 TokenList
= GetSplitValueList(Setting
)
511 DefaultValue
= TokenList
[0]
512 if len(TokenList
) > 1:
513 MaxDatumSize
= TokenList
[1]
516 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
517 Pcd
= PcdClassObject(
529 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
531 # get module private build options
532 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
533 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
534 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
535 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
537 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
538 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
540 self
._Modules
[ModuleFile
] = Module
543 ## Retrieve all possible library instances used in this platform
544 def _GetLibraryInstances(self
):
545 if self
._LibraryInstances
== None:
546 self
._GetLibraryClasses
()
547 return self
._LibraryInstances
549 ## Retrieve [LibraryClasses] information
550 def _GetLibraryClasses(self
):
551 if self
._LibraryClasses
== None:
552 self
._LibraryInstances
= []
554 # tdict is a special dict kind of type, used for selecting correct
555 # library instance for given library class and module type
557 LibraryClassDict
= tdict(True, 3)
558 # track all library class names
559 LibraryClassSet
= set()
560 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
561 Macros
= self
._Macros
562 for Record
in RecordList
:
563 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
564 if LibraryClass
== '' or LibraryClass
== 'NULL':
565 self
._NullLibraryNumber
+= 1
566 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
567 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
568 LibraryClassSet
.add(LibraryClass
)
569 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
570 # check the file validation
571 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
573 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
576 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
577 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
578 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
579 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
580 if LibraryInstance
not in self
._LibraryInstances
:
581 self
._LibraryInstances
.append(LibraryInstance
)
583 # resolve the specific library instance for each class and each module type
584 self
._LibraryClasses
= tdict(True)
585 for LibraryClass
in LibraryClassSet
:
586 # try all possible module types
587 for ModuleType
in SUP_MODULE_LIST
:
588 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
589 if LibraryInstance
== None:
591 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
593 # for Edk style library instances, which are listed in different section
594 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
595 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
596 for Record
in RecordList
:
597 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
599 # check the file validation
600 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
602 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
604 if File
not in self
._LibraryInstances
:
605 self
._LibraryInstances
.append(File
)
607 # we need the module name as the library class name, so we have
608 # to parse it here. (self._Bdb[] will trigger a file parse if it
609 # hasn't been parsed)
611 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
612 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
613 return self
._LibraryClasses
615 ## Retrieve all PCD settings in platform
617 if self
._Pcds
== None:
619 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
620 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
621 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
622 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
623 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
624 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
625 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
626 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
627 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
630 ## Retrieve [BuildOptions]
631 def _GetBuildOptions(self
):
632 if self
._BuildOptions
== None:
633 self
._BuildOptions
= sdict()
635 # Retrieve build option for EDKII style module
637 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
638 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
639 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
641 # Retrieve build option for EDK style module
643 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
644 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
645 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
646 return self
._BuildOptions
648 ## Retrieve non-dynamic PCD settings
650 # @param Type PCD type
652 # @retval a dict object contains settings of given PCD type
654 def _GetPcd(self
, Type
):
657 # tdict is a special dict kind of type, used for selecting correct
658 # PCD settings for certain ARCH
660 PcdDict
= tdict(True, 3)
662 # Find out all possible PCD candidates for self._Arch
663 RecordList
= self
._RawData
[Type
, self
._Arch
]
664 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
665 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
666 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
667 # Remove redundant PCD candidates
668 for PcdCName
, TokenSpaceGuid
in PcdSet
:
669 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
672 PcdValue
, DatumType
, MaxDatumSize
= AnalyzePcdData(Setting
)
673 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
676 self
._PCD
_TYPE
_STRING
_[Type
],
687 ## Retrieve dynamic PCD settings
689 # @param Type PCD type
691 # @retval a dict object contains settings of given PCD type
693 def _GetDynamicPcd(self
, Type
):
696 # tdict is a special dict kind of type, used for selecting correct
697 # PCD settings for certain ARCH and SKU
699 PcdDict
= tdict(True, 4)
701 # Find out all possible PCD candidates for self._Arch
702 RecordList
= self
._RawData
[Type
, self
._Arch
]
703 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
704 PcdList
.append((PcdCName
, TokenSpaceGuid
))
705 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
706 # Remove redundant PCD candidates, per the ARCH and SKU
707 for PcdCName
, TokenSpaceGuid
in PcdList
:
708 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
712 PcdValue
, DatumType
, MaxDatumSize
= AnalyzePcdData(Setting
)
714 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', '', PcdValue
)
715 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
718 self
._PCD
_TYPE
_STRING
_[Type
],
723 {self
.SkuName
: SkuInfo
},
729 ## Retrieve dynamic HII PCD settings
731 # @param Type PCD type
733 # @retval a dict object contains settings of given PCD type
735 def _GetDynamicHiiPcd(self
, Type
):
738 # tdict is a special dict kind of type, used for selecting correct
739 # PCD settings for certain ARCH and SKU
741 PcdDict
= tdict(True, 4)
743 RecordList
= self
._RawData
[Type
, self
._Arch
]
744 # Find out all possible PCD candidates for self._Arch
745 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
746 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
747 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
748 # Remove redundant PCD candidates, per the ARCH and SKU
749 for PcdCName
, TokenSpaceGuid
in PcdSet
:
750 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
753 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= AnalyzeHiiPcdData(Setting
)
754 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
755 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
758 self
._PCD
_TYPE
_STRING
_[Type
],
763 {self
.SkuName
: SkuInfo
},
769 ## Retrieve dynamic VPD PCD settings
771 # @param Type PCD type
773 # @retval a dict object contains settings of given PCD type
775 def _GetDynamicVpdPcd(self
, Type
):
778 # tdict is a special dict kind of type, used for selecting correct
779 # PCD settings for certain ARCH and SKU
781 PcdDict
= tdict(True, 4)
783 # Find out all possible PCD candidates for self._Arch
784 RecordList
= self
._RawData
[Type
, self
._Arch
]
785 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
786 PcdList
.append((PcdCName
, TokenSpaceGuid
))
787 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
788 # Remove redundant PCD candidates, per the ARCH and SKU
789 for PcdCName
, TokenSpaceGuid
in PcdList
:
790 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
794 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
795 # For the Integer & Boolean type, the optional data can only be InitialValue.
796 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
797 # until the DEC parser has been called.
799 VpdOffset
, MaxDatumSize
, InitialValue
= AnalyzeVpdPcdData(Setting
)
801 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
802 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
805 self
._PCD
_TYPE
_STRING
_[Type
],
810 {self
.SkuName
: SkuInfo
},
816 ## Add external modules
818 # The external modules are mostly those listed in FDF file, which don't
821 # @param FilePath The path of module description file
823 def AddModule(self
, FilePath
):
824 FilePath
= NormPath(FilePath
)
825 if FilePath
not in self
.Modules
:
826 Module
= ModuleBuildClassObject()
827 Module
.MetaFile
= FilePath
828 self
.Modules
.append(Module
)
832 # The external PCDs are mostly those listed in FDF file to specify address
833 # or offset information.
835 # @param Name Name of the PCD
836 # @param Guid Token space guid of the PCD
837 # @param Value Value of the PCD
839 def AddPcd(self
, Name
, Guid
, Value
):
840 if (Name
, Guid
) not in self
.Pcds
:
841 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
842 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
844 _Macros
= property(_GetMacros
)
845 Arch
= property(_GetArch
, _SetArch
)
846 Platform
= property(_GetPlatformName
)
847 PlatformName
= property(_GetPlatformName
)
848 Guid
= property(_GetFileGuid
)
849 Version
= property(_GetVersion
)
850 DscSpecification
= property(_GetDscSpec
)
851 OutputDirectory
= property(_GetOutpuDir
)
852 SupArchList
= property(_GetSupArch
)
853 BuildTargets
= property(_GetBuildTarget
)
854 SkuName
= property(_GetSkuName
, _SetSkuName
)
855 FlashDefinition
= property(_GetFdfFile
)
856 BuildNumber
= property(_GetBuildNumber
)
857 MakefileName
= property(_GetMakefileName
)
858 BsBaseAddress
= property(_GetBsBaseAddress
)
859 RtBaseAddress
= property(_GetRtBaseAddress
)
860 LoadFixAddress
= property(_GetLoadFixAddress
)
861 RFCLanguages
= property(_GetRFCLanguages
)
862 ISOLanguages
= property(_GetISOLanguages
)
863 VpdToolGuid
= property(_GetVpdToolGuid
)
864 SkuIds
= property(_GetSkuIds
)
865 Modules
= property(_GetModules
)
866 LibraryInstances
= property(_GetLibraryInstances
)
867 LibraryClasses
= property(_GetLibraryClasses
)
868 Pcds
= property(_GetPcds
)
869 BuildOptions
= property(_GetBuildOptions
)
871 ## Platform build information from DEC file
873 # This class is used to retrieve information stored in database and convert them
874 # into PackageBuildClassObject form for easier use for AutoGen.
876 class DecBuildData(PackageBuildClassObject
):
877 # dict used to convert PCD type in database to string used by build tool
878 _PCD_TYPE_STRING_
= {
879 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
880 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
881 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
882 MODEL_PCD_DYNAMIC
: "Dynamic",
883 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
884 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
885 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
886 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
887 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
888 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
889 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
892 # dict used to convert part of [Defines] to members of DecBuildData directly
897 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
898 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
899 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
900 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
904 ## Constructor of DecBuildData
906 # Initialize object of DecBuildData
908 # @param FilePath The path of package description file
909 # @param RawData The raw data of DEC file
910 # @param BuildDataBase Database used to retrieve module information
911 # @param Arch The target architecture
912 # @param Platform (not used for DecBuildData)
913 # @param Macros Macros used for replacement in DSC file
915 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
917 self
._PackageDir
= File
.Dir
918 self
._RawData
= RawData
919 self
._Bdb
= BuildDataBase
921 self
._Target
= Target
922 self
._Toolchain
= Toolchain
926 def __setitem__(self
, key
, value
):
927 self
.__dict
__[self
._PROPERTY
_[key
]] = value
930 def __getitem__(self
, key
):
931 return self
.__dict
__[self
._PROPERTY
_[key
]]
934 def __contains__(self
, key
):
935 return key
in self
._PROPERTY
_
937 ## Set all internal used members of DecBuildData to None
940 self
._PackageName
= None
943 self
._PkgUniFile
= None
944 self
._Protocols
= None
947 self
._Includes
= None
948 self
._LibraryClasses
= None
952 ## Get current effective macros
953 def _GetMacros(self
):
954 if self
.__Macros
== None:
956 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
965 # Changing the default ARCH to another may affect all other information
966 # because all information in a platform may be ARCH-related. That's
967 # why we need to clear all internal used members, in order to cause all
968 # information to be re-retrieved.
970 # @param Value The value of ARCH
972 def _SetArch(self
, Value
):
973 if self
._Arch
== Value
:
978 ## Retrieve all information in [Defines] section
980 # (Retriving all [Defines] information in one-shot is just to save time.)
982 def _GetHeaderInfo(self
):
983 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
984 for Record
in RecordList
:
987 self
[Name
] = Record
[2]
988 self
._Header
= 'DUMMY'
990 ## Retrieve package name
991 def _GetPackageName(self
):
992 if self
._PackageName
== None:
993 if self
._Header
== None:
994 self
._GetHeaderInfo
()
995 if self
._PackageName
== None:
996 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
997 return self
._PackageName
999 ## Retrieve file guid
1000 def _GetFileGuid(self
):
1001 if self
._Guid
== None:
1002 if self
._Header
== None:
1003 self
._GetHeaderInfo
()
1004 if self
._Guid
== None:
1005 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1008 ## Retrieve package version
1009 def _GetVersion(self
):
1010 if self
._Version
== None:
1011 if self
._Header
== None:
1012 self
._GetHeaderInfo
()
1013 if self
._Version
== None:
1015 return self
._Version
1017 ## Retrieve protocol definitions (name/value pairs)
1018 def _GetProtocol(self
):
1019 if self
._Protocols
== None:
1021 # tdict is a special kind of dict, used for selecting correct
1022 # protocol defition for given ARCH
1024 ProtocolDict
= tdict(True)
1026 # find out all protocol definitions for specific and 'common' arch
1027 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1028 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1029 if Name
not in NameList
:
1030 NameList
.append(Name
)
1031 ProtocolDict
[Arch
, Name
] = Guid
1032 # use sdict to keep the order
1033 self
._Protocols
= sdict()
1034 for Name
in NameList
:
1036 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1037 # will automatically turn to 'common' ARCH for trying
1039 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1040 return self
._Protocols
1042 ## Retrieve PPI definitions (name/value pairs)
1044 if self
._Ppis
== None:
1046 # tdict is a special kind of dict, used for selecting correct
1047 # PPI defition for given ARCH
1049 PpiDict
= tdict(True)
1051 # find out all PPI definitions for specific arch and 'common' arch
1052 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1053 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1054 if Name
not in NameList
:
1055 NameList
.append(Name
)
1056 PpiDict
[Arch
, Name
] = Guid
1057 # use sdict to keep the order
1058 self
._Ppis
= sdict()
1059 for Name
in NameList
:
1061 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1062 # will automatically turn to 'common' ARCH for trying
1064 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1067 ## Retrieve GUID definitions (name/value pairs)
1069 if self
._Guids
== None:
1071 # tdict is a special kind of dict, used for selecting correct
1072 # GUID defition for given ARCH
1074 GuidDict
= tdict(True)
1076 # find out all protocol definitions for specific and 'common' arch
1077 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1078 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1079 if Name
not in NameList
:
1080 NameList
.append(Name
)
1081 GuidDict
[Arch
, Name
] = Guid
1082 # use sdict to keep the order
1083 self
._Guids
= sdict()
1084 for Name
in NameList
:
1086 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1087 # will automatically turn to 'common' ARCH for trying
1089 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1092 ## Retrieve public include paths declared in this package
1093 def _GetInclude(self
):
1094 if self
._Includes
== None:
1096 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1097 Macros
= self
._Macros
1098 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1099 for Record
in RecordList
:
1100 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1103 ErrorCode
, ErrorInfo
= File
.Validate()
1105 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1107 # avoid duplicate include path
1108 if File
not in self
._Includes
:
1109 self
._Includes
.append(File
)
1110 return self
._Includes
1112 ## Retrieve library class declarations (not used in build at present)
1113 def _GetLibraryClass(self
):
1114 if self
._LibraryClasses
== None:
1116 # tdict is a special kind of dict, used for selecting correct
1117 # library class declaration for given ARCH
1119 LibraryClassDict
= tdict(True)
1120 LibraryClassSet
= set()
1121 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1122 Macros
= self
._Macros
1123 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1124 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1125 # check the file validation
1126 ErrorCode
, ErrorInfo
= File
.Validate()
1128 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1129 LibraryClassSet
.add(LibraryClass
)
1130 LibraryClassDict
[Arch
, LibraryClass
] = File
1131 self
._LibraryClasses
= sdict()
1132 for LibraryClass
in LibraryClassSet
:
1133 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1134 return self
._LibraryClasses
1136 ## Retrieve PCD declarations
1138 if self
._Pcds
== None:
1139 self
._Pcds
= sdict()
1140 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1141 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1142 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1143 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1144 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1147 ## Retrieve PCD declarations for given type
1148 def _GetPcd(self
, Type
):
1151 # tdict is a special kind of dict, used for selecting correct
1152 # PCD declaration for given ARCH
1154 PcdDict
= tdict(True, 3)
1155 # for summarizing PCD
1157 # find out all PCDs of the 'type'
1158 RecordList
= self
._RawData
[Type
, self
._Arch
]
1159 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1160 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1161 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1163 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1165 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1166 # will automatically turn to 'common' ARCH and try again
1168 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1172 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1174 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1177 self
._PCD
_TYPE
_STRING
_[Type
],
1189 _Macros
= property(_GetMacros
)
1190 Arch
= property(_GetArch
, _SetArch
)
1191 PackageName
= property(_GetPackageName
)
1192 Guid
= property(_GetFileGuid
)
1193 Version
= property(_GetVersion
)
1195 Protocols
= property(_GetProtocol
)
1196 Ppis
= property(_GetPpi
)
1197 Guids
= property(_GetGuid
)
1198 Includes
= property(_GetInclude
)
1199 LibraryClasses
= property(_GetLibraryClass
)
1200 Pcds
= property(_GetPcds
)
1202 ## Module build information from INF file
1204 # This class is used to retrieve information stored in database and convert them
1205 # into ModuleBuildClassObject form for easier use for AutoGen.
1207 class InfBuildData(ModuleBuildClassObject
):
1208 # dict used to convert PCD type in database to string used by build tool
1209 _PCD_TYPE_STRING_
= {
1210 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1211 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1212 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1213 MODEL_PCD_DYNAMIC
: "Dynamic",
1214 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1215 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1216 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1217 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1218 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1219 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1220 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1223 # dict used to convert part of [Defines] to members of InfBuildData directly
1228 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1229 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1230 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1234 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1235 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1236 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1237 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1238 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1239 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1240 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1241 TAB_INF_DEFINES_VERSION
: "_Version",
1242 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1243 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1245 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1248 # dict used to convert Component type to Module type
1251 "SECURITY_CORE" : "SEC",
1252 "PEI_CORE" : "PEI_CORE",
1253 "COMBINED_PEIM_DRIVER" : "PEIM",
1254 "PIC_PEIM" : "PEIM",
1255 "RELOCATABLE_PEIM" : "PEIM",
1256 "PE32_PEIM" : "PEIM",
1257 "BS_DRIVER" : "DXE_DRIVER",
1258 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1259 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1260 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1261 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1262 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1263 # "BS_DRIVER" : "UEFI_DRIVER",
1264 "APPLICATION" : "UEFI_APPLICATION",
1268 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1269 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1270 # dict used to convert old tool name used in [nmake] section to new ones
1278 ## Constructor of DscBuildData
1280 # Initialize object of DscBuildData
1282 # @param FilePath The path of platform description file
1283 # @param RawData The raw data of DSC file
1284 # @param BuildDataBase Database used to retrieve module/package information
1285 # @param Arch The target architecture
1286 # @param Platform The name of platform employing this module
1287 # @param Macros Macros used for replacement in DSC file
1289 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1290 self
.MetaFile
= FilePath
1291 self
._ModuleDir
= FilePath
.Dir
1292 self
._RawData
= RawData
1293 self
._Bdb
= BuildDatabase
1295 self
._Target
= Target
1296 self
._Toolchain
= Toolchain
1297 self
._Platform
= 'COMMON'
1298 self
._SourceOverridePath
= None
1299 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1300 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1304 def __setitem__(self
, key
, value
):
1305 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1308 def __getitem__(self
, key
):
1309 return self
.__dict
__[self
._PROPERTY
_[key
]]
1311 ## "in" test support
1312 def __contains__(self
, key
):
1313 return key
in self
._PROPERTY
_
1315 ## Set all internal used members of InfBuildData to None
1317 self
._Header
_ = None
1318 self
._AutoGenVersion
= None
1319 self
._BaseName
= None
1320 self
._DxsFile
= None
1321 self
._ModuleType
= None
1322 self
._ComponentType
= None
1323 self
._BuildType
= None
1325 self
._Version
= None
1326 self
._PcdIsDriver
= None
1327 self
._BinaryModule
= None
1329 self
._MakefileName
= None
1330 self
._CustomMakefile
= None
1331 self
._Specification
= None
1332 self
._LibraryClass
= None
1333 self
._ModuleEntryPointList
= None
1334 self
._ModuleUnloadImageList
= None
1335 self
._ConstructorList
= None
1336 self
._DestructorList
= None
1338 self
._Binaries
= None
1339 self
._Sources
= None
1340 self
._LibraryClasses
= None
1341 self
._Libraries
= None
1342 self
._Protocols
= None
1345 self
._Includes
= None
1346 self
._Packages
= None
1348 self
._BuildOptions
= None
1350 self
._DepexExpression
= None
1351 self
.__Macros
= None
1353 ## Get current effective macros
1354 def _GetMacros(self
):
1355 if self
.__Macros
== None:
1357 # EDK_GLOBAL defined macros can be applied to EDK module
1358 if self
.AutoGenVersion
< 0x00010005:
1359 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1360 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1361 return self
.__Macros
1369 # Changing the default ARCH to another may affect all other information
1370 # because all information in a platform may be ARCH-related. That's
1371 # why we need to clear all internal used members, in order to cause all
1372 # information to be re-retrieved.
1374 # @param Value The value of ARCH
1376 def _SetArch(self
, Value
):
1377 if self
._Arch
== Value
:
1382 ## Return the name of platform employing this module
1383 def _GetPlatform(self
):
1384 return self
._Platform
1386 ## Change the name of platform employing this module
1388 # Changing the default name of platform to another may affect some information
1389 # because they may be PLATFORM-related. That's why we need to clear all internal
1390 # used members, in order to cause all information to be re-retrieved.
1392 def _SetPlatform(self
, Value
):
1393 if self
._Platform
== Value
:
1395 self
._Platform
= Value
1398 ## Retrieve all information in [Defines] section
1400 # (Retriving all [Defines] information in one-shot is just to save time.)
1402 def _GetHeaderInfo(self
):
1403 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1404 for Record
in RecordList
:
1405 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1406 # items defined _PROPERTY_ don't need additional processing
1409 # some special items in [Defines] section need special treatment
1410 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1411 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1412 Name
= 'UEFI_SPECIFICATION_VERSION'
1413 if self
._Specification
== None:
1414 self
._Specification
= sdict()
1415 self
._Specification
[Name
] = GetHexVerValue(Value
)
1416 if self
._Specification
[Name
] == None:
1417 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1418 "'%s' format is not supported for %s" % (Value
, Name
),
1419 File
=self
.MetaFile
, Line
=Record
[-1])
1420 elif Name
== 'LIBRARY_CLASS':
1421 if self
._LibraryClass
== None:
1422 self
._LibraryClass
= []
1423 ValueList
= GetSplitValueList(Value
)
1424 LibraryClass
= ValueList
[0]
1425 if len(ValueList
) > 1:
1426 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1428 SupModuleList
= SUP_MODULE_LIST
1429 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1430 elif Name
== 'ENTRY_POINT':
1431 if self
._ModuleEntryPointList
== None:
1432 self
._ModuleEntryPointList
= []
1433 self
._ModuleEntryPointList
.append(Value
)
1434 elif Name
== 'UNLOAD_IMAGE':
1435 if self
._ModuleUnloadImageList
== None:
1436 self
._ModuleUnloadImageList
= []
1439 self
._ModuleUnloadImageList
.append(Value
)
1440 elif Name
== 'CONSTRUCTOR':
1441 if self
._ConstructorList
== None:
1442 self
._ConstructorList
= []
1445 self
._ConstructorList
.append(Value
)
1446 elif Name
== 'DESTRUCTOR':
1447 if self
._DestructorList
== None:
1448 self
._DestructorList
= []
1451 self
._DestructorList
.append(Value
)
1452 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1453 TokenList
= GetSplitValueList(Value
)
1454 if self
._CustomMakefile
== None:
1455 self
._CustomMakefile
= {}
1456 if len(TokenList
) < 2:
1457 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1458 self
._CustomMakefile
['GCC'] = TokenList
[0]
1460 if TokenList
[0] not in ['MSFT', 'GCC']:
1461 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1462 "No supported family [%s]" % TokenList
[0],
1463 File
=self
.MetaFile
, Line
=Record
[-1])
1464 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1466 if self
._Defs
== None:
1467 self
._Defs
= sdict()
1468 self
._Defs
[Name
] = Value
1471 # Retrieve information in sections specific to Edk.x modules
1473 if self
.AutoGenVersion
>= 0x00010005:
1474 if not self
._ModuleType
:
1475 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1476 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1477 if self
._ModuleType
not in SUP_MODULE_LIST
:
1478 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1479 for Record
in RecordList
:
1481 if Name
== "MODULE_TYPE":
1484 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1485 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1486 File
=self
.MetaFile
, Line
=LineNo
)
1487 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1488 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1489 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
)
1490 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1491 and 'PCI_CLASS_CODE' in self
._Defs
:
1492 self
._BuildType
= 'UEFI_OPTIONROM'
1493 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1494 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1495 self
._BuildType
= 'UEFI_HII'
1497 self
._BuildType
= self
._ModuleType
.upper()
1500 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1501 # check the file validation
1502 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1504 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1505 File
=self
.MetaFile
, Line
=LineNo
)
1506 if self
.Sources
== None:
1508 self
._Sources
.append(File
)
1510 if not self
._ComponentType
:
1511 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1512 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1513 self
._BuildType
= self
._ComponentType
.upper()
1514 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1515 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1516 if self
._ComponentType
== 'LIBRARY':
1517 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1518 # make use some [nmake] section macros
1519 Macros
= self
._Macros
1520 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1521 Macros
['PROCESSOR'] = self
._Arch
1522 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1523 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1524 Value
= ReplaceMacro(Value
, Macros
, True)
1525 if Name
== "IMAGE_ENTRY_POINT":
1526 if self
._ModuleEntryPointList
== None:
1527 self
._ModuleEntryPointList
= []
1528 self
._ModuleEntryPointList
.append(Value
)
1529 elif Name
== "DPX_SOURCE":
1530 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1531 # check the file validation
1532 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1534 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1535 File
=self
.MetaFile
, Line
=LineNo
)
1536 if self
.Sources
== None:
1538 self
._Sources
.append(File
)
1540 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1541 if len(ToolList
) == 0 or len(ToolList
) != 1:
1543 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1544 # File=self.MetaFile, Line=LineNo)
1546 if self
._BuildOptions
== None:
1547 self
._BuildOptions
= sdict()
1549 if ToolList
[0] in self
._TOOL
_CODE
_:
1550 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1553 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1554 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1555 #ignore not replaced macros in value
1556 ValueList
= GetSplitList(' ' + Value
, '/D')
1557 Dummy
= ValueList
[0]
1558 for Index
in range(1, len(ValueList
)):
1559 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1561 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1562 Value
= Dummy
.strip()
1563 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1564 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1566 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1567 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1568 # set _Header to non-None in order to avoid database re-querying
1569 self
._Header
_ = 'DUMMY'
1571 ## Retrieve file version
1572 def _GetInfVersion(self
):
1573 if self
._AutoGenVersion
== None:
1574 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1575 for Record
in RecordList
:
1576 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1577 self
._AutoGenVersion
= int(Record
[2], 0)
1579 if self
._AutoGenVersion
== None:
1580 self
._AutoGenVersion
= 0x00010000
1581 return self
._AutoGenVersion
1583 ## Retrieve BASE_NAME
1584 def _GetBaseName(self
):
1585 if self
._BaseName
== None:
1586 if self
._Header
_ == None:
1587 self
._GetHeaderInfo
()
1588 if self
._BaseName
== None:
1589 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1590 return self
._BaseName
1593 def _GetDxsFile(self
):
1594 if self
._DxsFile
== None:
1595 if self
._Header
_ == None:
1596 self
._GetHeaderInfo
()
1597 if self
._DxsFile
== None:
1599 return self
._DxsFile
1601 ## Retrieve MODULE_TYPE
1602 def _GetModuleType(self
):
1603 if self
._ModuleType
== None:
1604 if self
._Header
_ == None:
1605 self
._GetHeaderInfo
()
1606 if self
._ModuleType
== None:
1607 self
._ModuleType
= 'BASE'
1608 if self
._ModuleType
not in SUP_MODULE_LIST
:
1609 self
._ModuleType
= "USER_DEFINED"
1610 return self
._ModuleType
1612 ## Retrieve COMPONENT_TYPE
1613 def _GetComponentType(self
):
1614 if self
._ComponentType
== None:
1615 if self
._Header
_ == None:
1616 self
._GetHeaderInfo
()
1617 if self
._ComponentType
== None:
1618 self
._ComponentType
= 'USER_DEFINED'
1619 return self
._ComponentType
1621 ## Retrieve "BUILD_TYPE"
1622 def _GetBuildType(self
):
1623 if self
._BuildType
== None:
1624 if self
._Header
_ == None:
1625 self
._GetHeaderInfo
()
1626 if not self
._BuildType
:
1627 self
._BuildType
= "BASE"
1628 return self
._BuildType
1630 ## Retrieve file guid
1631 def _GetFileGuid(self
):
1632 if self
._Guid
== None:
1633 if self
._Header
_ == None:
1634 self
._GetHeaderInfo
()
1635 if self
._Guid
== None:
1636 self
._Guid
= '00000000-0000-0000-000000000000'
1639 ## Retrieve module version
1640 def _GetVersion(self
):
1641 if self
._Version
== None:
1642 if self
._Header
_ == None:
1643 self
._GetHeaderInfo
()
1644 if self
._Version
== None:
1645 self
._Version
= '0.0'
1646 return self
._Version
1648 ## Retrieve PCD_IS_DRIVER
1649 def _GetPcdIsDriver(self
):
1650 if self
._PcdIsDriver
== None:
1651 if self
._Header
_ == None:
1652 self
._GetHeaderInfo
()
1653 if self
._PcdIsDriver
== None:
1654 self
._PcdIsDriver
= ''
1655 return self
._PcdIsDriver
1658 def _GetShadow(self
):
1659 if self
._Shadow
== None:
1660 if self
._Header
_ == None:
1661 self
._GetHeaderInfo
()
1662 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1665 self
._Shadow
= False
1668 ## Retrieve CUSTOM_MAKEFILE
1669 def _GetMakefile(self
):
1670 if self
._CustomMakefile
== None:
1671 if self
._Header
_ == None:
1672 self
._GetHeaderInfo
()
1673 if self
._CustomMakefile
== None:
1674 self
._CustomMakefile
= {}
1675 return self
._CustomMakefile
1677 ## Retrieve EFI_SPECIFICATION_VERSION
1679 if self
._Specification
== None:
1680 if self
._Header
_ == None:
1681 self
._GetHeaderInfo
()
1682 if self
._Specification
== None:
1683 self
._Specification
= {}
1684 return self
._Specification
1686 ## Retrieve LIBRARY_CLASS
1687 def _GetLibraryClass(self
):
1688 if self
._LibraryClass
== None:
1689 if self
._Header
_ == None:
1690 self
._GetHeaderInfo
()
1691 if self
._LibraryClass
== None:
1692 self
._LibraryClass
= []
1693 return self
._LibraryClass
1695 ## Retrieve ENTRY_POINT
1696 def _GetEntryPoint(self
):
1697 if self
._ModuleEntryPointList
== None:
1698 if self
._Header
_ == None:
1699 self
._GetHeaderInfo
()
1700 if self
._ModuleEntryPointList
== None:
1701 self
._ModuleEntryPointList
= []
1702 return self
._ModuleEntryPointList
1704 ## Retrieve UNLOAD_IMAGE
1705 def _GetUnloadImage(self
):
1706 if self
._ModuleUnloadImageList
== None:
1707 if self
._Header
_ == None:
1708 self
._GetHeaderInfo
()
1709 if self
._ModuleUnloadImageList
== None:
1710 self
._ModuleUnloadImageList
= []
1711 return self
._ModuleUnloadImageList
1713 ## Retrieve CONSTRUCTOR
1714 def _GetConstructor(self
):
1715 if self
._ConstructorList
== None:
1716 if self
._Header
_ == None:
1717 self
._GetHeaderInfo
()
1718 if self
._ConstructorList
== None:
1719 self
._ConstructorList
= []
1720 return self
._ConstructorList
1722 ## Retrieve DESTRUCTOR
1723 def _GetDestructor(self
):
1724 if self
._DestructorList
== None:
1725 if self
._Header
_ == None:
1726 self
._GetHeaderInfo
()
1727 if self
._DestructorList
== None:
1728 self
._DestructorList
= []
1729 return self
._DestructorList
1731 ## Retrieve definies other than above ones
1732 def _GetDefines(self
):
1733 if self
._Defs
== None:
1734 if self
._Header
_ == None:
1735 self
._GetHeaderInfo
()
1736 if self
._Defs
== None:
1737 self
._Defs
= sdict()
1740 ## Retrieve binary files
1741 def _GetBinaryFiles(self
):
1742 if self
._Binaries
== None:
1744 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
1745 Macros
= self
._Macros
1746 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1747 Macros
['PROCESSOR'] = self
._Arch
1748 for Record
in RecordList
:
1749 FileType
= Record
[0]
1754 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
1756 Target
= TokenList
[0]
1757 if len(TokenList
) > 1:
1758 FeatureFlag
= Record
[1:]
1760 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
1761 # check the file validation
1762 ErrorCode
, ErrorInfo
= File
.Validate()
1764 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1765 self
._Binaries
.append(File
)
1766 return self
._Binaries
1768 ## Retrieve source files
1769 def _GetSourceFiles(self
):
1770 if self
._Sources
== None:
1772 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
1773 Macros
= self
._Macros
1774 for Record
in RecordList
:
1776 ToolChainFamily
= Record
[1]
1778 ToolCode
= Record
[3]
1779 FeatureFlag
= Record
[4]
1780 if self
.AutoGenVersion
< 0x00010005:
1781 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1782 Macros
['PROCESSOR'] = self
._Arch
1783 # old module source files (Edk)
1784 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
1785 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1786 # check the file validation
1787 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
1789 if File
.Ext
.lower() == '.h':
1790 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
1791 File
=self
.MetaFile
, Line
=LineNo
)
1794 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
1796 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
1797 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1798 # check the file validation
1799 ErrorCode
, ErrorInfo
= File
.Validate()
1801 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1803 self
._Sources
.append(File
)
1804 return self
._Sources
1806 ## Retrieve library classes employed by this module
1807 def _GetLibraryClassUses(self
):
1808 if self
._LibraryClasses
== None:
1809 self
._LibraryClasses
= sdict()
1810 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
1811 for Record
in RecordList
:
1813 Instance
= Record
[1]
1815 Instance
= NormPath(Instance
, self
._Macros
)
1816 self
._LibraryClasses
[Lib
] = Instance
1817 return self
._LibraryClasses
1819 ## Retrieve library names (for Edk.x style of modules)
1820 def _GetLibraryNames(self
):
1821 if self
._Libraries
== None:
1822 self
._Libraries
= []
1823 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
1824 for Record
in RecordList
:
1825 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
1826 # in case of name with '.lib' extension, which is unusual in Edk.x inf
1827 LibraryName
= os
.path
.splitext(LibraryName
)[0]
1828 if LibraryName
not in self
._Libraries
:
1829 self
._Libraries
.append(LibraryName
)
1830 return self
._Libraries
1832 ## Retrieve protocols consumed/produced by this module
1833 def _GetProtocols(self
):
1834 if self
._Protocols
== None:
1835 self
._Protocols
= sdict()
1836 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
1837 for Record
in RecordList
:
1839 Value
= ProtocolValue(CName
, self
.Packages
)
1841 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1842 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1843 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
1844 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1845 self
._Protocols
[CName
] = Value
1846 return self
._Protocols
1848 ## Retrieve PPIs consumed/produced by this module
1850 if self
._Ppis
== None:
1851 self
._Ppis
= sdict()
1852 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
1853 for Record
in RecordList
:
1855 Value
= PpiValue(CName
, self
.Packages
)
1857 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1858 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1859 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
1860 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1861 self
._Ppis
[CName
] = Value
1864 ## Retrieve GUIDs consumed/produced by this module
1865 def _GetGuids(self
):
1866 if self
._Guids
== None:
1867 self
._Guids
= sdict()
1868 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
1869 for Record
in RecordList
:
1871 Value
= GuidValue(CName
, self
.Packages
)
1873 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1874 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1875 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
1876 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1877 self
._Guids
[CName
] = Value
1880 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
1881 def _GetIncludes(self
):
1882 if self
._Includes
== None:
1884 if self
._SourceOverridePath
:
1885 self
._Includes
.append(self
._SourceOverridePath
)
1887 Macros
= self
._Macros
1888 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
1889 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
1891 Macros
['PROCESSOR'] = self
._Arch
1892 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
1893 for Record
in RecordList
:
1894 if Record
[0].find('EDK_SOURCE') > -1:
1895 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
1896 File
= NormPath(Record
[0], self
._Macros
)
1898 File
= os
.path
.join(self
._ModuleDir
, File
)
1900 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1901 File
= RealPath(os
.path
.normpath(File
))
1903 self
._Includes
.append(File
)
1905 #TRICK: let compiler to choose correct header file
1906 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
1907 File
= NormPath(Record
[0], self
._Macros
)
1909 File
= os
.path
.join(self
._ModuleDir
, File
)
1911 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1912 File
= RealPath(os
.path
.normpath(File
))
1914 self
._Includes
.append(File
)
1916 File
= NormPath(Record
[0], Macros
)
1918 File
= os
.path
.join(self
._ModuleDir
, File
)
1920 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1921 File
= RealPath(os
.path
.normpath(File
))
1923 self
._Includes
.append(File
)
1924 return self
._Includes
1926 ## Retrieve packages this module depends on
1927 def _GetPackages(self
):
1928 if self
._Packages
== None:
1930 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
1931 Macros
= self
._Macros
1932 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
1933 for Record
in RecordList
:
1934 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
1936 # check the file validation
1937 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
1939 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1940 # parse this package now. we need it to get protocol/ppi/guid value
1941 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
1942 self
._Packages
.append(Package
)
1943 return self
._Packages
1945 ## Retrieve PCDs used in this module
1947 if self
._Pcds
== None:
1948 self
._Pcds
= sdict()
1949 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1950 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1951 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1952 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1953 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1956 ## Retrieve build options specific to this module
1957 def _GetBuildOptions(self
):
1958 if self
._BuildOptions
== None:
1959 self
._BuildOptions
= sdict()
1960 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
1961 for Record
in RecordList
:
1962 ToolChainFamily
= Record
[0]
1963 ToolChain
= Record
[1]
1965 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1966 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
1968 # concatenate the option string if they're for the same tool
1969 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1970 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
1971 return self
._BuildOptions
1973 ## Retrieve dependency expression
1974 def _GetDepex(self
):
1975 if self
._Depex
== None:
1976 self
._Depex
= tdict(False, 2)
1977 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1979 # If the module has only Binaries and no Sources, then ignore [Depex]
1980 if self
.Sources
== None or self
.Sources
== []:
1981 if self
.Binaries
!= None and self
.Binaries
!= []:
1984 # PEIM and DXE drivers must have a valid [Depex] section
1985 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
1986 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
1987 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
1988 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
1989 % self
.ModuleType
, File
=self
.MetaFile
)
1992 for Record
in RecordList
:
1993 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
1995 ModuleType
= Record
[4]
1996 TokenList
= DepexStr
.split()
1997 if (Arch
, ModuleType
) not in Depex
:
1998 Depex
[Arch
, ModuleType
] = []
1999 DepexList
= Depex
[Arch
, ModuleType
]
2000 for Token
in TokenList
:
2001 if Token
in DEPEX_SUPPORTED_OPCODE
:
2002 DepexList
.append(Token
)
2003 elif Token
.endswith(".inf"): # module file name
2004 ModuleFile
= os
.path
.normpath(Token
)
2005 Module
= self
.BuildDatabase
[ModuleFile
]
2007 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2008 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2009 DepexList
.append(Module
.Guid
)
2011 # get the GUID value now
2012 Value
= ProtocolValue(Token
, self
.Packages
)
2014 Value
= PpiValue(Token
, self
.Packages
)
2016 Value
= GuidValue(Token
, self
.Packages
)
2018 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2019 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2020 "Value of [%s] is not found in" % Token
,
2021 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2022 DepexList
.append(Value
)
2023 for Arch
, ModuleType
in Depex
:
2024 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2027 ## Retrieve depedency expression
2028 def _GetDepexExpression(self
):
2029 if self
._DepexExpression
== None:
2030 self
._DepexExpression
= tdict(False, 2)
2031 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2032 DepexExpression
= sdict()
2033 for Record
in RecordList
:
2034 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2036 ModuleType
= Record
[4]
2037 TokenList
= DepexStr
.split()
2038 if (Arch
, ModuleType
) not in DepexExpression
:
2039 DepexExpression
[Arch
, ModuleType
] = ''
2040 for Token
in TokenList
:
2041 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2042 for Arch
, ModuleType
in DepexExpression
:
2043 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2044 return self
._DepexExpression
2046 ## Retrieve PCD for given type
2047 def _GetPcd(self
, Type
):
2049 PcdDict
= tdict(True, 4)
2051 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2052 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Dummy1
, LineNo
in RecordList
:
2053 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2054 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2055 # get the guid value
2056 if TokenSpaceGuid
not in self
.Guids
:
2057 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2059 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2060 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2061 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2062 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2063 self
.Guids
[TokenSpaceGuid
] = Value
2065 # resolve PCD type, value, datum info, etc. by getting its definition from package
2066 for PcdCName
, TokenSpaceGuid
in PcdList
:
2067 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2070 ValueList
= AnalyzePcdData(Setting
)
2071 DefaultValue
= ValueList
[0]
2072 Pcd
= PcdClassObject(
2082 self
.Guids
[TokenSpaceGuid
]
2085 # get necessary info from package declaring this PCD
2086 for Package
in self
.Packages
:
2088 # 'dynamic' in INF means its type is determined by platform;
2089 # if platform doesn't give its type, use 'lowest' one in the
2090 # following order, if any
2092 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2094 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2095 if Type
== MODEL_PCD_DYNAMIC
:
2097 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2098 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2104 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2105 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2107 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2110 # Check whether the token value exist or not.
2112 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2116 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2117 File
=self
.MetaFile
, Line
=LineNo
,
2121 # Check hexadecimal token value length and format.
2123 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2124 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2125 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2129 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2130 File
=self
.MetaFile
, Line
=LineNo
,
2135 # Check decimal token value length and format.
2139 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2140 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2144 "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
)),
2145 File
=self
.MetaFile
, Line
=LineNo
,
2152 "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
)),
2153 File
=self
.MetaFile
, Line
=LineNo
,
2157 Pcd
.DatumType
= PcdInPackage
.DatumType
2158 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2159 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2160 if Pcd
.DefaultValue
in [None, '']:
2161 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2167 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2168 File
=self
.MetaFile
, Line
=LineNo
,
2169 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2171 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2175 _Macros
= property(_GetMacros
)
2176 Arch
= property(_GetArch
, _SetArch
)
2177 Platform
= property(_GetPlatform
, _SetPlatform
)
2179 AutoGenVersion
= property(_GetInfVersion
)
2180 BaseName
= property(_GetBaseName
)
2181 ModuleType
= property(_GetModuleType
)
2182 ComponentType
= property(_GetComponentType
)
2183 BuildType
= property(_GetBuildType
)
2184 Guid
= property(_GetFileGuid
)
2185 Version
= property(_GetVersion
)
2186 PcdIsDriver
= property(_GetPcdIsDriver
)
2187 Shadow
= property(_GetShadow
)
2188 CustomMakefile
= property(_GetMakefile
)
2189 Specification
= property(_GetSpec
)
2190 LibraryClass
= property(_GetLibraryClass
)
2191 ModuleEntryPointList
= property(_GetEntryPoint
)
2192 ModuleUnloadImageList
= property(_GetUnloadImage
)
2193 ConstructorList
= property(_GetConstructor
)
2194 DestructorList
= property(_GetDestructor
)
2195 Defines
= property(_GetDefines
)
2196 DxsFile
= property(_GetDxsFile
)
2198 Binaries
= property(_GetBinaryFiles
)
2199 Sources
= property(_GetSourceFiles
)
2200 LibraryClasses
= property(_GetLibraryClassUses
)
2201 Libraries
= property(_GetLibraryNames
)
2202 Protocols
= property(_GetProtocols
)
2203 Ppis
= property(_GetPpis
)
2204 Guids
= property(_GetGuids
)
2205 Includes
= property(_GetIncludes
)
2206 Packages
= property(_GetPackages
)
2207 Pcds
= property(_GetPcds
)
2208 BuildOptions
= property(_GetBuildOptions
)
2209 Depex
= property(_GetDepex
)
2210 DepexExpression
= property(_GetDepexExpression
)
2214 # This class defined the build database for all modules, packages and platform.
2215 # It will call corresponding parser for the given file if it cannot find it in
2218 # @param DbPath Path of database file
2219 # @param GlobalMacros Global macros used for replacement during file parsing
2220 # @prarm RenewDb=False Create new database file if it's already there
2222 class WorkspaceDatabase(object):
2224 # default database file path
2225 _DB_PATH_
= "Conf/.cache/build.db"
2228 # internal class used for call corresponding file parser and caching the result
2229 # to avoid unnecessary re-parsing
2231 class BuildObjectFactory(object):
2234 ".inf" : MODEL_FILE_INF
,
2235 ".dec" : MODEL_FILE_DEC
,
2236 ".dsc" : MODEL_FILE_DSC
,
2241 MODEL_FILE_INF
: InfParser
,
2242 MODEL_FILE_DEC
: DecParser
,
2243 MODEL_FILE_DSC
: DscParser
,
2246 # convert to xxxBuildData object
2248 MODEL_FILE_INF
: InfBuildData
,
2249 MODEL_FILE_DEC
: DecBuildData
,
2250 MODEL_FILE_DSC
: DscBuildData
,
2253 _CACHE_
= {} # (FilePath, Arch) : <object>
2256 def __init__(self
, WorkspaceDb
):
2257 self
.WorkspaceDb
= WorkspaceDb
2259 # key = (FilePath, Arch=None)
2260 def __contains__(self
, Key
):
2266 return (FilePath
, Arch
) in self
._CACHE
_
2268 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2269 def __getitem__(self
, Key
):
2271 KeyLength
= len(Key
)
2285 # if it's generated before, just return the cached one
2286 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2287 if Key
in self
._CACHE
_:
2288 return self
._CACHE
_[Key
]
2292 if Ext
not in self
._FILE
_TYPE
_:
2294 FileType
= self
._FILE
_TYPE
_[Ext
]
2295 if FileType
not in self
._GENERATOR
_:
2298 # get the parser ready for this file
2299 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2302 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2304 # alwasy do post-process, in case of macros change
2305 MetaFile
.DoPostProcess()
2306 # object the build is based on
2307 BuildObject
= self
._GENERATOR
_[FileType
](
2315 self
._CACHE
_[Key
] = BuildObject
2318 # placeholder for file format conversion
2319 class TransformObjectFactory
:
2320 def __init__(self
, WorkspaceDb
):
2321 self
.WorkspaceDb
= WorkspaceDb
2323 # key = FilePath, Arch
2324 def __getitem__(self
, Key
):
2327 ## Constructor of WorkspaceDatabase
2329 # @param DbPath Path of database file
2330 # @param GlobalMacros Global macros used for replacement during file parsing
2331 # @prarm RenewDb=False Create new database file if it's already there
2333 def __init__(self
, DbPath
, RenewDb
=False):
2334 self
._DbClosedFlag
= False
2336 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2338 # don't create necessary path for db in memory
2339 if DbPath
!= ':memory:':
2340 DbDir
= os
.path
.split(DbPath
)[0]
2341 if not os
.path
.exists(DbDir
):
2344 # remove db file in case inconsistency between db and file in file system
2345 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2348 # create db with optimized parameters
2349 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2350 self
.Conn
.execute("PRAGMA synchronous=OFF")
2351 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2352 self
.Conn
.execute("PRAGMA count_changes=OFF")
2353 self
.Conn
.execute("PRAGMA cache_size=8192")
2354 #self.Conn.execute("PRAGMA page_size=8192")
2356 # to avoid non-ascii character conversion issue
2357 self
.Conn
.text_factory
= str
2358 self
.Cur
= self
.Conn
.cursor()
2360 # create table for internal uses
2361 self
.TblDataModel
= TableDataModel(self
.Cur
)
2362 self
.TblFile
= TableFile(self
.Cur
)
2363 self
.Platform
= None
2365 # conversion object for build or file format conversion purpose
2366 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2367 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2369 ## Check whether workspace database need to be renew.
2370 # The renew reason maybe:
2371 # 1) If user force to renew;
2372 # 2) If user do not force renew, and
2373 # a) If the time of last modified python source is newer than database file;
2374 # b) If the time of last modified frozen executable file is newer than database file;
2376 # @param force User force renew database
2377 # @param DbPath The absolute path of workspace database file
2379 # @return Bool value for whether need renew workspace databse
2381 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2382 # if database does not exist, we need do nothing
2383 if not os
.path
.exists(DbPath
): return False
2385 # if user force to renew database, then not check whether database is out of date
2386 if force
: return True
2389 # Check the time of last modified source file or build.exe
2390 # if is newer than time of database, then database need to be re-created.
2392 timeOfToolModified
= 0
2393 if hasattr(sys
, "frozen"):
2394 exePath
= os
.path
.abspath(sys
.executable
)
2395 timeOfToolModified
= os
.stat(exePath
).st_mtime
2397 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2398 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2399 if rootPath
== "" or rootPath
== None:
2400 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2401 determine whether database file is out of date!\n")
2403 # walk the root path of source or build's binary to get the time last modified.
2405 for root
, dirs
, files
in os
.walk (rootPath
):
2407 # bypass source control folder
2408 if dir.lower() in [".svn", "_svn", "cvs"]:
2412 ext
= os
.path
.splitext(file)[1]
2413 if ext
.lower() == ".py": # only check .py files
2414 fd
= os
.stat(os
.path
.join(root
, file))
2415 if timeOfToolModified
< fd
.st_mtime
:
2416 timeOfToolModified
= fd
.st_mtime
2417 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2418 EdkLogger
.verbose("\nWorkspace database is out of data!")
2423 ## Initialize build database
2424 def InitDatabase(self
):
2425 EdkLogger
.verbose("\nInitialize build database started ...")
2430 self
.TblDataModel
.Create(False)
2431 self
.TblFile
.Create(False)
2434 # Initialize table DataModel
2436 self
.TblDataModel
.InitTable()
2437 EdkLogger
.verbose("Initialize build database ... DONE!")
2441 # @param Table: The instance of the table to be queried
2443 def QueryTable(self
, Table
):
2449 ## Close entire database
2452 # Close the connection and cursor
2455 if not self
._DbClosedFlag
:
2459 self
._DbClosedFlag
= True
2461 ## Summarize all packages in the database
2462 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2463 self
.Platform
= Platform
2465 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2467 # Get Package related to Modules
2469 for Module
in Pa
.Modules
:
2470 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2471 for Package
in ModuleObj
.Packages
:
2472 if Package
not in PackageList
:
2473 PackageList
.append(Package
)
2475 # Get Packages related to Libraries
2477 for Lib
in Pa
.LibraryInstances
:
2478 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2479 for Package
in LibObj
.Packages
:
2480 if Package
not in PackageList
:
2481 PackageList
.append(Package
)
2485 ## Summarize all platforms in the database
2486 def _GetPlatformList(self
):
2488 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2490 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2493 if Platform
!= None:
2494 PlatformList
.append(Platform
)
2497 PlatformList
= property(_GetPlatformList
)
2501 # This acts like the main() function for the script, unless it is 'import'ed into another
2504 if __name__
== '__main__':