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 PLATFORM_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:
274 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
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 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
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 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
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 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
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 arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
467 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
468 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
470 Module
= ModuleBuildClassObject()
471 Module
.MetaFile
= ModuleFile
473 # get module override path
474 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
476 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
478 # Check if the source override path exists
479 if not os
.path
.isdir(Module
.SourceOverridePath
):
480 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
482 #Add to GlobalData Variables
483 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
485 # get module private library instance
486 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
487 for Record
in RecordList
:
488 LibraryClass
= Record
[0]
489 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
492 # check the file validation
493 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
495 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
498 if LibraryClass
== '' or LibraryClass
== 'NULL':
499 self
._NullLibraryNumber
+= 1
500 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
501 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
502 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
503 if LibraryPath
not in self
.LibraryInstances
:
504 self
.LibraryInstances
.append(LibraryPath
)
506 # get module private PCD setting
507 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
508 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
509 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
510 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
511 TokenList
= GetSplitValueList(Setting
)
512 DefaultValue
= TokenList
[0]
513 if len(TokenList
) > 1:
514 MaxDatumSize
= TokenList
[1]
517 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
518 Pcd
= PcdClassObject(
530 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
532 # get module private build options
533 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
534 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
535 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
536 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
538 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
539 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
541 self
._Modules
[ModuleFile
] = Module
544 ## Retrieve all possible library instances used in this platform
545 def _GetLibraryInstances(self
):
546 if self
._LibraryInstances
== None:
547 self
._GetLibraryClasses
()
548 return self
._LibraryInstances
550 ## Retrieve [LibraryClasses] information
551 def _GetLibraryClasses(self
):
552 if self
._LibraryClasses
== None:
553 self
._LibraryInstances
= []
555 # tdict is a special dict kind of type, used for selecting correct
556 # library instance for given library class and module type
558 LibraryClassDict
= tdict(True, 3)
559 # track all library class names
560 LibraryClassSet
= set()
561 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
562 Macros
= self
._Macros
563 for Record
in RecordList
:
564 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
565 if LibraryClass
== '' or LibraryClass
== 'NULL':
566 self
._NullLibraryNumber
+= 1
567 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
568 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
569 LibraryClassSet
.add(LibraryClass
)
570 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
571 # check the file validation
572 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
574 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
577 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
578 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
579 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
580 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
581 if LibraryInstance
not in self
._LibraryInstances
:
582 self
._LibraryInstances
.append(LibraryInstance
)
584 # resolve the specific library instance for each class and each module type
585 self
._LibraryClasses
= tdict(True)
586 for LibraryClass
in LibraryClassSet
:
587 # try all possible module types
588 for ModuleType
in SUP_MODULE_LIST
:
589 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
590 if LibraryInstance
== None:
592 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
594 # for Edk style library instances, which are listed in different section
595 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
596 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
597 for Record
in RecordList
:
598 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
600 # check the file validation
601 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
603 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
605 if File
not in self
._LibraryInstances
:
606 self
._LibraryInstances
.append(File
)
608 # we need the module name as the library class name, so we have
609 # to parse it here. (self._Bdb[] will trigger a file parse if it
610 # hasn't been parsed)
612 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
613 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
614 return self
._LibraryClasses
616 ## Retrieve all PCD settings in platform
618 if self
._Pcds
== None:
620 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
621 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
622 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
623 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
624 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
625 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
626 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
627 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
628 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
631 ## Retrieve [BuildOptions]
632 def _GetBuildOptions(self
):
633 if self
._BuildOptions
== None:
634 self
._BuildOptions
= sdict()
636 # Retrieve build option for EDKII style module
638 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
639 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
640 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
642 # Retrieve build option for EDK style module
644 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
645 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
646 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
647 return self
._BuildOptions
649 ## Retrieve non-dynamic PCD settings
651 # @param Type PCD type
653 # @retval a dict object contains settings of given PCD type
655 def _GetPcd(self
, Type
):
658 # tdict is a special dict kind of type, used for selecting correct
659 # PCD settings for certain ARCH
661 PcdDict
= tdict(True, 3)
663 # Find out all possible PCD candidates for self._Arch
664 RecordList
= self
._RawData
[Type
, self
._Arch
]
665 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
666 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
667 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
668 # Remove redundant PCD candidates
669 for PcdCName
, TokenSpaceGuid
in PcdSet
:
670 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
673 PcdValue
, DatumType
, MaxDatumSize
= AnalyzePcdData(Setting
)
674 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
677 self
._PCD
_TYPE
_STRING
_[Type
],
688 ## Retrieve dynamic PCD settings
690 # @param Type PCD type
692 # @retval a dict object contains settings of given PCD type
694 def _GetDynamicPcd(self
, Type
):
697 # tdict is a special dict kind of type, used for selecting correct
698 # PCD settings for certain ARCH and SKU
700 PcdDict
= tdict(True, 4)
702 # Find out all possible PCD candidates for self._Arch
703 RecordList
= self
._RawData
[Type
, self
._Arch
]
704 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
705 PcdList
.append((PcdCName
, TokenSpaceGuid
))
706 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
707 # Remove redundant PCD candidates, per the ARCH and SKU
708 for PcdCName
, TokenSpaceGuid
in PcdList
:
709 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
713 PcdValue
, DatumType
, MaxDatumSize
= AnalyzePcdData(Setting
)
715 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', '', PcdValue
)
716 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
719 self
._PCD
_TYPE
_STRING
_[Type
],
724 {self
.SkuName
: SkuInfo
},
730 ## Retrieve dynamic HII PCD settings
732 # @param Type PCD type
734 # @retval a dict object contains settings of given PCD type
736 def _GetDynamicHiiPcd(self
, Type
):
739 # tdict is a special dict kind of type, used for selecting correct
740 # PCD settings for certain ARCH and SKU
742 PcdDict
= tdict(True, 4)
744 RecordList
= self
._RawData
[Type
, self
._Arch
]
745 # Find out all possible PCD candidates for self._Arch
746 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
747 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
748 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
749 # Remove redundant PCD candidates, per the ARCH and SKU
750 for PcdCName
, TokenSpaceGuid
in PcdSet
:
751 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
754 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= AnalyzeHiiPcdData(Setting
)
755 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
756 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
759 self
._PCD
_TYPE
_STRING
_[Type
],
764 {self
.SkuName
: SkuInfo
},
770 ## Retrieve dynamic VPD PCD settings
772 # @param Type PCD type
774 # @retval a dict object contains settings of given PCD type
776 def _GetDynamicVpdPcd(self
, Type
):
779 # tdict is a special dict kind of type, used for selecting correct
780 # PCD settings for certain ARCH and SKU
782 PcdDict
= tdict(True, 4)
784 # Find out all possible PCD candidates for self._Arch
785 RecordList
= self
._RawData
[Type
, self
._Arch
]
786 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
787 PcdList
.append((PcdCName
, TokenSpaceGuid
))
788 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
789 # Remove redundant PCD candidates, per the ARCH and SKU
790 for PcdCName
, TokenSpaceGuid
in PcdList
:
791 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
795 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
796 # For the Integer & Boolean type, the optional data can only be InitialValue.
797 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
798 # until the DEC parser has been called.
800 VpdOffset
, MaxDatumSize
, InitialValue
= AnalyzeVpdPcdData(Setting
)
802 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
803 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
806 self
._PCD
_TYPE
_STRING
_[Type
],
811 {self
.SkuName
: SkuInfo
},
817 ## Add external modules
819 # The external modules are mostly those listed in FDF file, which don't
822 # @param FilePath The path of module description file
824 def AddModule(self
, FilePath
):
825 FilePath
= NormPath(FilePath
)
826 if FilePath
not in self
.Modules
:
827 Module
= ModuleBuildClassObject()
828 Module
.MetaFile
= FilePath
829 self
.Modules
.append(Module
)
833 # The external PCDs are mostly those listed in FDF file to specify address
834 # or offset information.
836 # @param Name Name of the PCD
837 # @param Guid Token space guid of the PCD
838 # @param Value Value of the PCD
840 def AddPcd(self
, Name
, Guid
, Value
):
841 if (Name
, Guid
) not in self
.Pcds
:
842 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
843 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
845 def IsPlatformPcdDeclared(self
, DecPcds
):
846 for PcdType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_FEATURE_FLAG
,
847 MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_VPD
,
848 MODEL_PCD_DYNAMIC_EX_DEFAULT
, MODEL_PCD_DYNAMIC_EX_HII
, MODEL_PCD_DYNAMIC_EX_VPD
):
849 RecordList
= self
._RawData
[PcdType
, self
._Arch
]
850 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
851 if (PcdCName
, TokenSpaceGuid
) not in DecPcds
:
852 EdkLogger
.error('build', PARSER_ERROR
,
853 "Pcd (%s.%s) defined in DSC is not declared in DEC files." % (TokenSpaceGuid
, PcdCName
),
854 File
=self
.MetaFile
, Line
=Dummy4
)
856 if PcdType
in (MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_VPD
):
857 if DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
== "VOID*":
858 PcdValue
= AnalyzeVpdPcdData(Setting
)[2]
860 PcdValue
= AnalyzeVpdPcdData(Setting
)[1]
861 elif PcdType
in (MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
):
862 PcdValue
= AnalyzeHiiPcdData(Setting
)[3]
864 PcdValue
= AnalyzePcdData(Setting
)[0]
866 Valid
, ErrStr
= CheckPcdDatum(DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, PcdValue
)
868 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=Dummy4
,
869 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
871 _Macros
= property(_GetMacros
)
872 Arch
= property(_GetArch
, _SetArch
)
873 Platform
= property(_GetPlatformName
)
874 PlatformName
= property(_GetPlatformName
)
875 Guid
= property(_GetFileGuid
)
876 Version
= property(_GetVersion
)
877 DscSpecification
= property(_GetDscSpec
)
878 OutputDirectory
= property(_GetOutpuDir
)
879 SupArchList
= property(_GetSupArch
)
880 BuildTargets
= property(_GetBuildTarget
)
881 SkuName
= property(_GetSkuName
, _SetSkuName
)
882 FlashDefinition
= property(_GetFdfFile
)
883 BuildNumber
= property(_GetBuildNumber
)
884 MakefileName
= property(_GetMakefileName
)
885 BsBaseAddress
= property(_GetBsBaseAddress
)
886 RtBaseAddress
= property(_GetRtBaseAddress
)
887 LoadFixAddress
= property(_GetLoadFixAddress
)
888 RFCLanguages
= property(_GetRFCLanguages
)
889 ISOLanguages
= property(_GetISOLanguages
)
890 VpdToolGuid
= property(_GetVpdToolGuid
)
891 SkuIds
= property(_GetSkuIds
)
892 Modules
= property(_GetModules
)
893 LibraryInstances
= property(_GetLibraryInstances
)
894 LibraryClasses
= property(_GetLibraryClasses
)
895 Pcds
= property(_GetPcds
)
896 BuildOptions
= property(_GetBuildOptions
)
898 ## Platform build information from DEC file
900 # This class is used to retrieve information stored in database and convert them
901 # into PackageBuildClassObject form for easier use for AutoGen.
903 class DecBuildData(PackageBuildClassObject
):
904 # dict used to convert PCD type in database to string used by build tool
905 _PCD_TYPE_STRING_
= {
906 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
907 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
908 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
909 MODEL_PCD_DYNAMIC
: "Dynamic",
910 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
911 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
912 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
913 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
914 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
915 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
916 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
919 # dict used to convert part of [Defines] to members of DecBuildData directly
924 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
925 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
926 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
927 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
931 ## Constructor of DecBuildData
933 # Initialize object of DecBuildData
935 # @param FilePath The path of package description file
936 # @param RawData The raw data of DEC file
937 # @param BuildDataBase Database used to retrieve module information
938 # @param Arch The target architecture
939 # @param Platform (not used for DecBuildData)
940 # @param Macros Macros used for replacement in DSC file
942 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
944 self
._PackageDir
= File
.Dir
945 self
._RawData
= RawData
946 self
._Bdb
= BuildDataBase
948 self
._Target
= Target
949 self
._Toolchain
= Toolchain
953 def __setitem__(self
, key
, value
):
954 self
.__dict
__[self
._PROPERTY
_[key
]] = value
957 def __getitem__(self
, key
):
958 return self
.__dict
__[self
._PROPERTY
_[key
]]
961 def __contains__(self
, key
):
962 return key
in self
._PROPERTY
_
964 ## Set all internal used members of DecBuildData to None
967 self
._PackageName
= None
970 self
._PkgUniFile
= None
971 self
._Protocols
= None
974 self
._Includes
= None
975 self
._LibraryClasses
= None
979 ## Get current effective macros
980 def _GetMacros(self
):
981 if self
.__Macros
== None:
983 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
992 # Changing the default ARCH to another may affect all other information
993 # because all information in a platform may be ARCH-related. That's
994 # why we need to clear all internal used members, in order to cause all
995 # information to be re-retrieved.
997 # @param Value The value of ARCH
999 def _SetArch(self
, Value
):
1000 if self
._Arch
== Value
:
1005 ## Retrieve all information in [Defines] section
1007 # (Retriving all [Defines] information in one-shot is just to save time.)
1009 def _GetHeaderInfo(self
):
1010 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1011 for Record
in RecordList
:
1014 self
[Name
] = Record
[2]
1015 self
._Header
= 'DUMMY'
1017 ## Retrieve package name
1018 def _GetPackageName(self
):
1019 if self
._PackageName
== None:
1020 if self
._Header
== None:
1021 self
._GetHeaderInfo
()
1022 if self
._PackageName
== None:
1023 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1024 return self
._PackageName
1026 ## Retrieve file guid
1027 def _GetFileGuid(self
):
1028 if self
._Guid
== None:
1029 if self
._Header
== None:
1030 self
._GetHeaderInfo
()
1031 if self
._Guid
== None:
1032 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1035 ## Retrieve package version
1036 def _GetVersion(self
):
1037 if self
._Version
== None:
1038 if self
._Header
== None:
1039 self
._GetHeaderInfo
()
1040 if self
._Version
== None:
1042 return self
._Version
1044 ## Retrieve protocol definitions (name/value pairs)
1045 def _GetProtocol(self
):
1046 if self
._Protocols
== None:
1048 # tdict is a special kind of dict, used for selecting correct
1049 # protocol defition for given ARCH
1051 ProtocolDict
= tdict(True)
1053 # find out all protocol definitions for specific and 'common' arch
1054 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1055 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1056 if Name
not in NameList
:
1057 NameList
.append(Name
)
1058 ProtocolDict
[Arch
, Name
] = Guid
1059 # use sdict to keep the order
1060 self
._Protocols
= sdict()
1061 for Name
in NameList
:
1063 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1064 # will automatically turn to 'common' ARCH for trying
1066 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1067 return self
._Protocols
1069 ## Retrieve PPI definitions (name/value pairs)
1071 if self
._Ppis
== None:
1073 # tdict is a special kind of dict, used for selecting correct
1074 # PPI defition for given ARCH
1076 PpiDict
= tdict(True)
1078 # find out all PPI definitions for specific arch and 'common' arch
1079 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1080 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1081 if Name
not in NameList
:
1082 NameList
.append(Name
)
1083 PpiDict
[Arch
, Name
] = Guid
1084 # use sdict to keep the order
1085 self
._Ppis
= sdict()
1086 for Name
in NameList
:
1088 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1089 # will automatically turn to 'common' ARCH for trying
1091 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1094 ## Retrieve GUID definitions (name/value pairs)
1096 if self
._Guids
== None:
1098 # tdict is a special kind of dict, used for selecting correct
1099 # GUID defition for given ARCH
1101 GuidDict
= tdict(True)
1103 # find out all protocol definitions for specific and 'common' arch
1104 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1105 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1106 if Name
not in NameList
:
1107 NameList
.append(Name
)
1108 GuidDict
[Arch
, Name
] = Guid
1109 # use sdict to keep the order
1110 self
._Guids
= sdict()
1111 for Name
in NameList
:
1113 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1114 # will automatically turn to 'common' ARCH for trying
1116 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1119 ## Retrieve public include paths declared in this package
1120 def _GetInclude(self
):
1121 if self
._Includes
== None:
1123 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1124 Macros
= self
._Macros
1125 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1126 for Record
in RecordList
:
1127 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1130 ErrorCode
, ErrorInfo
= File
.Validate()
1132 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1134 # avoid duplicate include path
1135 if File
not in self
._Includes
:
1136 self
._Includes
.append(File
)
1137 return self
._Includes
1139 ## Retrieve library class declarations (not used in build at present)
1140 def _GetLibraryClass(self
):
1141 if self
._LibraryClasses
== None:
1143 # tdict is a special kind of dict, used for selecting correct
1144 # library class declaration for given ARCH
1146 LibraryClassDict
= tdict(True)
1147 LibraryClassSet
= set()
1148 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1149 Macros
= self
._Macros
1150 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1151 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1152 # check the file validation
1153 ErrorCode
, ErrorInfo
= File
.Validate()
1155 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1156 LibraryClassSet
.add(LibraryClass
)
1157 LibraryClassDict
[Arch
, LibraryClass
] = File
1158 self
._LibraryClasses
= sdict()
1159 for LibraryClass
in LibraryClassSet
:
1160 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1161 return self
._LibraryClasses
1163 ## Retrieve PCD declarations
1165 if self
._Pcds
== None:
1166 self
._Pcds
= sdict()
1167 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1168 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1169 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1170 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1171 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1174 ## Retrieve PCD declarations for given type
1175 def _GetPcd(self
, Type
):
1178 # tdict is a special kind of dict, used for selecting correct
1179 # PCD declaration for given ARCH
1181 PcdDict
= tdict(True, 3)
1182 # for summarizing PCD
1184 # find out all PCDs of the 'type'
1185 RecordList
= self
._RawData
[Type
, self
._Arch
]
1186 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1187 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1188 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1190 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1192 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1193 # will automatically turn to 'common' ARCH and try again
1195 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1199 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1201 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1204 self
._PCD
_TYPE
_STRING
_[Type
],
1216 _Macros
= property(_GetMacros
)
1217 Arch
= property(_GetArch
, _SetArch
)
1218 PackageName
= property(_GetPackageName
)
1219 Guid
= property(_GetFileGuid
)
1220 Version
= property(_GetVersion
)
1222 Protocols
= property(_GetProtocol
)
1223 Ppis
= property(_GetPpi
)
1224 Guids
= property(_GetGuid
)
1225 Includes
= property(_GetInclude
)
1226 LibraryClasses
= property(_GetLibraryClass
)
1227 Pcds
= property(_GetPcds
)
1229 ## Module build information from INF file
1231 # This class is used to retrieve information stored in database and convert them
1232 # into ModuleBuildClassObject form for easier use for AutoGen.
1234 class InfBuildData(ModuleBuildClassObject
):
1235 # dict used to convert PCD type in database to string used by build tool
1236 _PCD_TYPE_STRING_
= {
1237 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1238 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1239 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1240 MODEL_PCD_DYNAMIC
: "Dynamic",
1241 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1242 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1243 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1244 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1245 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1246 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1247 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1250 # dict used to convert part of [Defines] to members of InfBuildData directly
1255 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1256 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1257 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1261 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1262 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1263 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1264 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1265 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1266 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1267 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1268 TAB_INF_DEFINES_VERSION
: "_Version",
1269 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1270 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1272 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1275 # dict used to convert Component type to Module type
1278 "SECURITY_CORE" : "SEC",
1279 "PEI_CORE" : "PEI_CORE",
1280 "COMBINED_PEIM_DRIVER" : "PEIM",
1281 "PIC_PEIM" : "PEIM",
1282 "RELOCATABLE_PEIM" : "PEIM",
1283 "PE32_PEIM" : "PEIM",
1284 "BS_DRIVER" : "DXE_DRIVER",
1285 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1286 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1287 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1288 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1289 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1290 # "BS_DRIVER" : "UEFI_DRIVER",
1291 "APPLICATION" : "UEFI_APPLICATION",
1295 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1296 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1297 # dict used to convert old tool name used in [nmake] section to new ones
1305 ## Constructor of DscBuildData
1307 # Initialize object of DscBuildData
1309 # @param FilePath The path of platform description file
1310 # @param RawData The raw data of DSC file
1311 # @param BuildDataBase Database used to retrieve module/package information
1312 # @param Arch The target architecture
1313 # @param Platform The name of platform employing this module
1314 # @param Macros Macros used for replacement in DSC file
1316 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1317 self
.MetaFile
= FilePath
1318 self
._ModuleDir
= FilePath
.Dir
1319 self
._RawData
= RawData
1320 self
._Bdb
= BuildDatabase
1322 self
._Target
= Target
1323 self
._Toolchain
= Toolchain
1324 self
._Platform
= 'COMMON'
1325 self
._SourceOverridePath
= None
1326 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1327 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1331 def __setitem__(self
, key
, value
):
1332 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1335 def __getitem__(self
, key
):
1336 return self
.__dict
__[self
._PROPERTY
_[key
]]
1338 ## "in" test support
1339 def __contains__(self
, key
):
1340 return key
in self
._PROPERTY
_
1342 ## Set all internal used members of InfBuildData to None
1344 self
._Header
_ = None
1345 self
._AutoGenVersion
= None
1346 self
._BaseName
= None
1347 self
._DxsFile
= None
1348 self
._ModuleType
= None
1349 self
._ComponentType
= None
1350 self
._BuildType
= None
1352 self
._Version
= None
1353 self
._PcdIsDriver
= None
1354 self
._BinaryModule
= None
1356 self
._MakefileName
= None
1357 self
._CustomMakefile
= None
1358 self
._Specification
= None
1359 self
._LibraryClass
= None
1360 self
._ModuleEntryPointList
= None
1361 self
._ModuleUnloadImageList
= None
1362 self
._ConstructorList
= None
1363 self
._DestructorList
= None
1365 self
._Binaries
= None
1366 self
._Sources
= None
1367 self
._LibraryClasses
= None
1368 self
._Libraries
= None
1369 self
._Protocols
= None
1372 self
._Includes
= None
1373 self
._Packages
= None
1375 self
._BuildOptions
= None
1377 self
._DepexExpression
= None
1378 self
.__Macros
= None
1380 ## Get current effective macros
1381 def _GetMacros(self
):
1382 if self
.__Macros
== None:
1384 # EDK_GLOBAL defined macros can be applied to EDK module
1385 if self
.AutoGenVersion
< 0x00010005:
1386 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1387 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1388 return self
.__Macros
1396 # Changing the default ARCH to another may affect all other information
1397 # because all information in a platform may be ARCH-related. That's
1398 # why we need to clear all internal used members, in order to cause all
1399 # information to be re-retrieved.
1401 # @param Value The value of ARCH
1403 def _SetArch(self
, Value
):
1404 if self
._Arch
== Value
:
1409 ## Return the name of platform employing this module
1410 def _GetPlatform(self
):
1411 return self
._Platform
1413 ## Change the name of platform employing this module
1415 # Changing the default name of platform to another may affect some information
1416 # because they may be PLATFORM-related. That's why we need to clear all internal
1417 # used members, in order to cause all information to be re-retrieved.
1419 def _SetPlatform(self
, Value
):
1420 if self
._Platform
== Value
:
1422 self
._Platform
= Value
1425 ## Retrieve all information in [Defines] section
1427 # (Retriving all [Defines] information in one-shot is just to save time.)
1429 def _GetHeaderInfo(self
):
1430 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1431 for Record
in RecordList
:
1432 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1433 # items defined _PROPERTY_ don't need additional processing
1436 # some special items in [Defines] section need special treatment
1437 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1438 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1439 Name
= 'UEFI_SPECIFICATION_VERSION'
1440 if self
._Specification
== None:
1441 self
._Specification
= sdict()
1442 self
._Specification
[Name
] = GetHexVerValue(Value
)
1443 if self
._Specification
[Name
] == None:
1444 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1445 "'%s' format is not supported for %s" % (Value
, Name
),
1446 File
=self
.MetaFile
, Line
=Record
[-1])
1447 elif Name
== 'LIBRARY_CLASS':
1448 if self
._LibraryClass
== None:
1449 self
._LibraryClass
= []
1450 ValueList
= GetSplitValueList(Value
)
1451 LibraryClass
= ValueList
[0]
1452 if len(ValueList
) > 1:
1453 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1455 SupModuleList
= SUP_MODULE_LIST
1456 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1457 elif Name
== 'ENTRY_POINT':
1458 if self
._ModuleEntryPointList
== None:
1459 self
._ModuleEntryPointList
= []
1460 self
._ModuleEntryPointList
.append(Value
)
1461 elif Name
== 'UNLOAD_IMAGE':
1462 if self
._ModuleUnloadImageList
== None:
1463 self
._ModuleUnloadImageList
= []
1466 self
._ModuleUnloadImageList
.append(Value
)
1467 elif Name
== 'CONSTRUCTOR':
1468 if self
._ConstructorList
== None:
1469 self
._ConstructorList
= []
1472 self
._ConstructorList
.append(Value
)
1473 elif Name
== 'DESTRUCTOR':
1474 if self
._DestructorList
== None:
1475 self
._DestructorList
= []
1478 self
._DestructorList
.append(Value
)
1479 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1480 TokenList
= GetSplitValueList(Value
)
1481 if self
._CustomMakefile
== None:
1482 self
._CustomMakefile
= {}
1483 if len(TokenList
) < 2:
1484 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1485 self
._CustomMakefile
['GCC'] = TokenList
[0]
1487 if TokenList
[0] not in ['MSFT', 'GCC']:
1488 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1489 "No supported family [%s]" % TokenList
[0],
1490 File
=self
.MetaFile
, Line
=Record
[-1])
1491 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1493 if self
._Defs
== None:
1494 self
._Defs
= sdict()
1495 self
._Defs
[Name
] = Value
1498 # Retrieve information in sections specific to Edk.x modules
1500 if self
.AutoGenVersion
>= 0x00010005:
1501 if not self
._ModuleType
:
1502 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1503 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1504 if self
._ModuleType
not in SUP_MODULE_LIST
:
1505 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1506 for Record
in RecordList
:
1508 if Name
== "MODULE_TYPE":
1511 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1512 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1513 File
=self
.MetaFile
, Line
=LineNo
)
1514 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1515 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1516 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
)
1517 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1518 and 'PCI_CLASS_CODE' in self
._Defs
:
1519 self
._BuildType
= 'UEFI_OPTIONROM'
1520 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1521 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1522 self
._BuildType
= 'UEFI_HII'
1524 self
._BuildType
= self
._ModuleType
.upper()
1527 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1528 # check the file validation
1529 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1531 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1532 File
=self
.MetaFile
, Line
=LineNo
)
1533 if self
.Sources
== None:
1535 self
._Sources
.append(File
)
1537 if not self
._ComponentType
:
1538 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1539 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1540 self
._BuildType
= self
._ComponentType
.upper()
1541 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1542 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1543 if self
._ComponentType
== 'LIBRARY':
1544 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1545 # make use some [nmake] section macros
1546 Macros
= self
._Macros
1547 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1548 Macros
['PROCESSOR'] = self
._Arch
1549 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1550 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1551 Value
= ReplaceMacro(Value
, Macros
, True)
1552 if Name
== "IMAGE_ENTRY_POINT":
1553 if self
._ModuleEntryPointList
== None:
1554 self
._ModuleEntryPointList
= []
1555 self
._ModuleEntryPointList
.append(Value
)
1556 elif Name
== "DPX_SOURCE":
1557 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1558 # check the file validation
1559 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1561 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1562 File
=self
.MetaFile
, Line
=LineNo
)
1563 if self
.Sources
== None:
1565 self
._Sources
.append(File
)
1567 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1568 if len(ToolList
) == 0 or len(ToolList
) != 1:
1570 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1571 # File=self.MetaFile, Line=LineNo)
1573 if self
._BuildOptions
== None:
1574 self
._BuildOptions
= sdict()
1576 if ToolList
[0] in self
._TOOL
_CODE
_:
1577 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1580 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1581 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1582 #ignore not replaced macros in value
1583 ValueList
= GetSplitList(' ' + Value
, '/D')
1584 Dummy
= ValueList
[0]
1585 for Index
in range(1, len(ValueList
)):
1586 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1588 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1589 Value
= Dummy
.strip()
1590 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1591 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1593 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1594 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1595 # set _Header to non-None in order to avoid database re-querying
1596 self
._Header
_ = 'DUMMY'
1598 ## Retrieve file version
1599 def _GetInfVersion(self
):
1600 if self
._AutoGenVersion
== None:
1601 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1602 for Record
in RecordList
:
1603 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1604 self
._AutoGenVersion
= int(Record
[2], 0)
1606 if self
._AutoGenVersion
== None:
1607 self
._AutoGenVersion
= 0x00010000
1608 return self
._AutoGenVersion
1610 ## Retrieve BASE_NAME
1611 def _GetBaseName(self
):
1612 if self
._BaseName
== None:
1613 if self
._Header
_ == None:
1614 self
._GetHeaderInfo
()
1615 if self
._BaseName
== None:
1616 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1617 return self
._BaseName
1620 def _GetDxsFile(self
):
1621 if self
._DxsFile
== None:
1622 if self
._Header
_ == None:
1623 self
._GetHeaderInfo
()
1624 if self
._DxsFile
== None:
1626 return self
._DxsFile
1628 ## Retrieve MODULE_TYPE
1629 def _GetModuleType(self
):
1630 if self
._ModuleType
== None:
1631 if self
._Header
_ == None:
1632 self
._GetHeaderInfo
()
1633 if self
._ModuleType
== None:
1634 self
._ModuleType
= 'BASE'
1635 if self
._ModuleType
not in SUP_MODULE_LIST
:
1636 self
._ModuleType
= "USER_DEFINED"
1637 return self
._ModuleType
1639 ## Retrieve COMPONENT_TYPE
1640 def _GetComponentType(self
):
1641 if self
._ComponentType
== None:
1642 if self
._Header
_ == None:
1643 self
._GetHeaderInfo
()
1644 if self
._ComponentType
== None:
1645 self
._ComponentType
= 'USER_DEFINED'
1646 return self
._ComponentType
1648 ## Retrieve "BUILD_TYPE"
1649 def _GetBuildType(self
):
1650 if self
._BuildType
== None:
1651 if self
._Header
_ == None:
1652 self
._GetHeaderInfo
()
1653 if not self
._BuildType
:
1654 self
._BuildType
= "BASE"
1655 return self
._BuildType
1657 ## Retrieve file guid
1658 def _GetFileGuid(self
):
1659 if self
._Guid
== None:
1660 if self
._Header
_ == None:
1661 self
._GetHeaderInfo
()
1662 if self
._Guid
== None:
1663 self
._Guid
= '00000000-0000-0000-000000000000'
1666 ## Retrieve module version
1667 def _GetVersion(self
):
1668 if self
._Version
== None:
1669 if self
._Header
_ == None:
1670 self
._GetHeaderInfo
()
1671 if self
._Version
== None:
1672 self
._Version
= '0.0'
1673 return self
._Version
1675 ## Retrieve PCD_IS_DRIVER
1676 def _GetPcdIsDriver(self
):
1677 if self
._PcdIsDriver
== None:
1678 if self
._Header
_ == None:
1679 self
._GetHeaderInfo
()
1680 if self
._PcdIsDriver
== None:
1681 self
._PcdIsDriver
= ''
1682 return self
._PcdIsDriver
1685 def _GetShadow(self
):
1686 if self
._Shadow
== None:
1687 if self
._Header
_ == None:
1688 self
._GetHeaderInfo
()
1689 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1692 self
._Shadow
= False
1695 ## Retrieve CUSTOM_MAKEFILE
1696 def _GetMakefile(self
):
1697 if self
._CustomMakefile
== None:
1698 if self
._Header
_ == None:
1699 self
._GetHeaderInfo
()
1700 if self
._CustomMakefile
== None:
1701 self
._CustomMakefile
= {}
1702 return self
._CustomMakefile
1704 ## Retrieve EFI_SPECIFICATION_VERSION
1706 if self
._Specification
== None:
1707 if self
._Header
_ == None:
1708 self
._GetHeaderInfo
()
1709 if self
._Specification
== None:
1710 self
._Specification
= {}
1711 return self
._Specification
1713 ## Retrieve LIBRARY_CLASS
1714 def _GetLibraryClass(self
):
1715 if self
._LibraryClass
== None:
1716 if self
._Header
_ == None:
1717 self
._GetHeaderInfo
()
1718 if self
._LibraryClass
== None:
1719 self
._LibraryClass
= []
1720 return self
._LibraryClass
1722 ## Retrieve ENTRY_POINT
1723 def _GetEntryPoint(self
):
1724 if self
._ModuleEntryPointList
== None:
1725 if self
._Header
_ == None:
1726 self
._GetHeaderInfo
()
1727 if self
._ModuleEntryPointList
== None:
1728 self
._ModuleEntryPointList
= []
1729 return self
._ModuleEntryPointList
1731 ## Retrieve UNLOAD_IMAGE
1732 def _GetUnloadImage(self
):
1733 if self
._ModuleUnloadImageList
== None:
1734 if self
._Header
_ == None:
1735 self
._GetHeaderInfo
()
1736 if self
._ModuleUnloadImageList
== None:
1737 self
._ModuleUnloadImageList
= []
1738 return self
._ModuleUnloadImageList
1740 ## Retrieve CONSTRUCTOR
1741 def _GetConstructor(self
):
1742 if self
._ConstructorList
== None:
1743 if self
._Header
_ == None:
1744 self
._GetHeaderInfo
()
1745 if self
._ConstructorList
== None:
1746 self
._ConstructorList
= []
1747 return self
._ConstructorList
1749 ## Retrieve DESTRUCTOR
1750 def _GetDestructor(self
):
1751 if self
._DestructorList
== None:
1752 if self
._Header
_ == None:
1753 self
._GetHeaderInfo
()
1754 if self
._DestructorList
== None:
1755 self
._DestructorList
= []
1756 return self
._DestructorList
1758 ## Retrieve definies other than above ones
1759 def _GetDefines(self
):
1760 if self
._Defs
== None:
1761 if self
._Header
_ == None:
1762 self
._GetHeaderInfo
()
1763 if self
._Defs
== None:
1764 self
._Defs
= sdict()
1767 ## Retrieve binary files
1768 def _GetBinaryFiles(self
):
1769 if self
._Binaries
== None:
1771 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
1772 Macros
= self
._Macros
1773 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1774 Macros
['PROCESSOR'] = self
._Arch
1775 for Record
in RecordList
:
1776 FileType
= Record
[0]
1781 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
1783 Target
= TokenList
[0]
1784 if len(TokenList
) > 1:
1785 FeatureFlag
= Record
[1:]
1787 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
1788 # check the file validation
1789 ErrorCode
, ErrorInfo
= File
.Validate()
1791 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1792 self
._Binaries
.append(File
)
1793 return self
._Binaries
1795 ## Retrieve source files
1796 def _GetSourceFiles(self
):
1797 if self
._Sources
== None:
1799 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
1800 Macros
= self
._Macros
1801 for Record
in RecordList
:
1803 ToolChainFamily
= Record
[1]
1805 ToolCode
= Record
[3]
1806 FeatureFlag
= Record
[4]
1807 if self
.AutoGenVersion
< 0x00010005:
1808 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1809 Macros
['PROCESSOR'] = self
._Arch
1810 # old module source files (Edk)
1811 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
1812 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1813 # check the file validation
1814 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
1816 if File
.Ext
.lower() == '.h':
1817 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
1818 File
=self
.MetaFile
, Line
=LineNo
)
1821 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
1823 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
1824 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1825 # check the file validation
1826 ErrorCode
, ErrorInfo
= File
.Validate()
1828 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1830 self
._Sources
.append(File
)
1831 return self
._Sources
1833 ## Retrieve library classes employed by this module
1834 def _GetLibraryClassUses(self
):
1835 if self
._LibraryClasses
== None:
1836 self
._LibraryClasses
= sdict()
1837 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
1838 for Record
in RecordList
:
1840 Instance
= Record
[1]
1842 Instance
= NormPath(Instance
, self
._Macros
)
1843 self
._LibraryClasses
[Lib
] = Instance
1844 return self
._LibraryClasses
1846 ## Retrieve library names (for Edk.x style of modules)
1847 def _GetLibraryNames(self
):
1848 if self
._Libraries
== None:
1849 self
._Libraries
= []
1850 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
1851 for Record
in RecordList
:
1852 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
1853 # in case of name with '.lib' extension, which is unusual in Edk.x inf
1854 LibraryName
= os
.path
.splitext(LibraryName
)[0]
1855 if LibraryName
not in self
._Libraries
:
1856 self
._Libraries
.append(LibraryName
)
1857 return self
._Libraries
1859 ## Retrieve protocols consumed/produced by this module
1860 def _GetProtocols(self
):
1861 if self
._Protocols
== None:
1862 self
._Protocols
= sdict()
1863 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
1864 for Record
in RecordList
:
1866 Value
= ProtocolValue(CName
, self
.Packages
)
1868 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1869 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1870 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
1871 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1872 self
._Protocols
[CName
] = Value
1873 return self
._Protocols
1875 ## Retrieve PPIs consumed/produced by this module
1877 if self
._Ppis
== None:
1878 self
._Ppis
= sdict()
1879 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
1880 for Record
in RecordList
:
1882 Value
= PpiValue(CName
, self
.Packages
)
1884 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1885 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1886 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
1887 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1888 self
._Ppis
[CName
] = Value
1891 ## Retrieve GUIDs consumed/produced by this module
1892 def _GetGuids(self
):
1893 if self
._Guids
== None:
1894 self
._Guids
= sdict()
1895 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
1896 for Record
in RecordList
:
1898 Value
= GuidValue(CName
, self
.Packages
)
1900 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1901 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1902 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
1903 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1904 self
._Guids
[CName
] = Value
1907 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
1908 def _GetIncludes(self
):
1909 if self
._Includes
== None:
1911 if self
._SourceOverridePath
:
1912 self
._Includes
.append(self
._SourceOverridePath
)
1914 Macros
= self
._Macros
1915 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
1916 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
1918 Macros
['PROCESSOR'] = self
._Arch
1919 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
1920 for Record
in RecordList
:
1921 if Record
[0].find('EDK_SOURCE') > -1:
1922 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
1923 File
= NormPath(Record
[0], self
._Macros
)
1925 File
= os
.path
.join(self
._ModuleDir
, File
)
1927 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1928 File
= RealPath(os
.path
.normpath(File
))
1930 self
._Includes
.append(File
)
1932 #TRICK: let compiler to choose correct header file
1933 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
1934 File
= NormPath(Record
[0], self
._Macros
)
1936 File
= os
.path
.join(self
._ModuleDir
, File
)
1938 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1939 File
= RealPath(os
.path
.normpath(File
))
1941 self
._Includes
.append(File
)
1943 File
= NormPath(Record
[0], Macros
)
1945 File
= os
.path
.join(self
._ModuleDir
, File
)
1947 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1948 File
= RealPath(os
.path
.normpath(File
))
1950 self
._Includes
.append(File
)
1951 return self
._Includes
1953 ## Retrieve packages this module depends on
1954 def _GetPackages(self
):
1955 if self
._Packages
== None:
1957 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
1958 Macros
= self
._Macros
1959 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
1960 for Record
in RecordList
:
1961 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
1963 # check the file validation
1964 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
1966 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1967 # parse this package now. we need it to get protocol/ppi/guid value
1968 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
1969 self
._Packages
.append(Package
)
1970 return self
._Packages
1972 ## Retrieve PCDs used in this module
1974 if self
._Pcds
== None:
1975 self
._Pcds
= sdict()
1976 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1977 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1978 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1979 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1980 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1983 ## Retrieve build options specific to this module
1984 def _GetBuildOptions(self
):
1985 if self
._BuildOptions
== None:
1986 self
._BuildOptions
= sdict()
1987 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
1988 for Record
in RecordList
:
1989 ToolChainFamily
= Record
[0]
1990 ToolChain
= Record
[1]
1992 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1993 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
1995 # concatenate the option string if they're for the same tool
1996 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1997 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
1998 return self
._BuildOptions
2000 ## Retrieve dependency expression
2001 def _GetDepex(self
):
2002 if self
._Depex
== None:
2003 self
._Depex
= tdict(False, 2)
2004 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2006 # If the module has only Binaries and no Sources, then ignore [Depex]
2007 if self
.Sources
== None or self
.Sources
== []:
2008 if self
.Binaries
!= None and self
.Binaries
!= []:
2011 # PEIM and DXE drivers must have a valid [Depex] section
2012 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2013 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2014 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2015 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2016 % self
.ModuleType
, File
=self
.MetaFile
)
2019 for Record
in RecordList
:
2020 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2022 ModuleType
= Record
[4]
2023 TokenList
= DepexStr
.split()
2024 if (Arch
, ModuleType
) not in Depex
:
2025 Depex
[Arch
, ModuleType
] = []
2026 DepexList
= Depex
[Arch
, ModuleType
]
2027 for Token
in TokenList
:
2028 if Token
in DEPEX_SUPPORTED_OPCODE
:
2029 DepexList
.append(Token
)
2030 elif Token
.endswith(".inf"): # module file name
2031 ModuleFile
= os
.path
.normpath(Token
)
2032 Module
= self
.BuildDatabase
[ModuleFile
]
2034 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2035 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2036 DepexList
.append(Module
.Guid
)
2038 # get the GUID value now
2039 Value
= ProtocolValue(Token
, self
.Packages
)
2041 Value
= PpiValue(Token
, self
.Packages
)
2043 Value
= GuidValue(Token
, self
.Packages
)
2045 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2046 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2047 "Value of [%s] is not found in" % Token
,
2048 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2049 DepexList
.append(Value
)
2050 for Arch
, ModuleType
in Depex
:
2051 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2054 ## Retrieve depedency expression
2055 def _GetDepexExpression(self
):
2056 if self
._DepexExpression
== None:
2057 self
._DepexExpression
= tdict(False, 2)
2058 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2059 DepexExpression
= sdict()
2060 for Record
in RecordList
:
2061 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2063 ModuleType
= Record
[4]
2064 TokenList
= DepexStr
.split()
2065 if (Arch
, ModuleType
) not in DepexExpression
:
2066 DepexExpression
[Arch
, ModuleType
] = ''
2067 for Token
in TokenList
:
2068 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2069 for Arch
, ModuleType
in DepexExpression
:
2070 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2071 return self
._DepexExpression
2073 ## Retrieve PCD for given type
2074 def _GetPcd(self
, Type
):
2076 PcdDict
= tdict(True, 4)
2078 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2079 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Dummy1
, LineNo
in RecordList
:
2080 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2081 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2082 # get the guid value
2083 if TokenSpaceGuid
not in self
.Guids
:
2084 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2086 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2087 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2088 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2089 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2090 self
.Guids
[TokenSpaceGuid
] = Value
2092 # resolve PCD type, value, datum info, etc. by getting its definition from package
2093 for PcdCName
, TokenSpaceGuid
in PcdList
:
2094 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2097 ValueList
= AnalyzePcdData(Setting
)
2098 DefaultValue
= ValueList
[0]
2099 Pcd
= PcdClassObject(
2109 self
.Guids
[TokenSpaceGuid
]
2112 # get necessary info from package declaring this PCD
2113 for Package
in self
.Packages
:
2115 # 'dynamic' in INF means its type is determined by platform;
2116 # if platform doesn't give its type, use 'lowest' one in the
2117 # following order, if any
2119 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2121 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2122 if Type
== MODEL_PCD_DYNAMIC
:
2124 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2125 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2131 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2132 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2134 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2137 # Check whether the token value exist or not.
2139 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2143 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2144 File
=self
.MetaFile
, Line
=LineNo
,
2148 # Check hexadecimal token value length and format.
2150 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2151 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2152 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2156 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2157 File
=self
.MetaFile
, Line
=LineNo
,
2162 # Check decimal token value length and format.
2166 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2167 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2171 "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
)),
2172 File
=self
.MetaFile
, Line
=LineNo
,
2179 "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
)),
2180 File
=self
.MetaFile
, Line
=LineNo
,
2184 Pcd
.DatumType
= PcdInPackage
.DatumType
2185 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2186 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2187 if Pcd
.DefaultValue
in [None, '']:
2188 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2194 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2195 File
=self
.MetaFile
, Line
=LineNo
,
2196 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2198 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2202 _Macros
= property(_GetMacros
)
2203 Arch
= property(_GetArch
, _SetArch
)
2204 Platform
= property(_GetPlatform
, _SetPlatform
)
2206 AutoGenVersion
= property(_GetInfVersion
)
2207 BaseName
= property(_GetBaseName
)
2208 ModuleType
= property(_GetModuleType
)
2209 ComponentType
= property(_GetComponentType
)
2210 BuildType
= property(_GetBuildType
)
2211 Guid
= property(_GetFileGuid
)
2212 Version
= property(_GetVersion
)
2213 PcdIsDriver
= property(_GetPcdIsDriver
)
2214 Shadow
= property(_GetShadow
)
2215 CustomMakefile
= property(_GetMakefile
)
2216 Specification
= property(_GetSpec
)
2217 LibraryClass
= property(_GetLibraryClass
)
2218 ModuleEntryPointList
= property(_GetEntryPoint
)
2219 ModuleUnloadImageList
= property(_GetUnloadImage
)
2220 ConstructorList
= property(_GetConstructor
)
2221 DestructorList
= property(_GetDestructor
)
2222 Defines
= property(_GetDefines
)
2223 DxsFile
= property(_GetDxsFile
)
2225 Binaries
= property(_GetBinaryFiles
)
2226 Sources
= property(_GetSourceFiles
)
2227 LibraryClasses
= property(_GetLibraryClassUses
)
2228 Libraries
= property(_GetLibraryNames
)
2229 Protocols
= property(_GetProtocols
)
2230 Ppis
= property(_GetPpis
)
2231 Guids
= property(_GetGuids
)
2232 Includes
= property(_GetIncludes
)
2233 Packages
= property(_GetPackages
)
2234 Pcds
= property(_GetPcds
)
2235 BuildOptions
= property(_GetBuildOptions
)
2236 Depex
= property(_GetDepex
)
2237 DepexExpression
= property(_GetDepexExpression
)
2241 # This class defined the build database for all modules, packages and platform.
2242 # It will call corresponding parser for the given file if it cannot find it in
2245 # @param DbPath Path of database file
2246 # @param GlobalMacros Global macros used for replacement during file parsing
2247 # @prarm RenewDb=False Create new database file if it's already there
2249 class WorkspaceDatabase(object):
2251 # default database file path
2252 _DB_PATH_
= "Conf/.cache/build.db"
2255 # internal class used for call corresponding file parser and caching the result
2256 # to avoid unnecessary re-parsing
2258 class BuildObjectFactory(object):
2261 ".inf" : MODEL_FILE_INF
,
2262 ".dec" : MODEL_FILE_DEC
,
2263 ".dsc" : MODEL_FILE_DSC
,
2268 MODEL_FILE_INF
: InfParser
,
2269 MODEL_FILE_DEC
: DecParser
,
2270 MODEL_FILE_DSC
: DscParser
,
2273 # convert to xxxBuildData object
2275 MODEL_FILE_INF
: InfBuildData
,
2276 MODEL_FILE_DEC
: DecBuildData
,
2277 MODEL_FILE_DSC
: DscBuildData
,
2280 _CACHE_
= {} # (FilePath, Arch) : <object>
2283 def __init__(self
, WorkspaceDb
):
2284 self
.WorkspaceDb
= WorkspaceDb
2286 # key = (FilePath, Arch=None)
2287 def __contains__(self
, Key
):
2293 return (FilePath
, Arch
) in self
._CACHE
_
2295 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2296 def __getitem__(self
, Key
):
2298 KeyLength
= len(Key
)
2312 # if it's generated before, just return the cached one
2313 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2314 if Key
in self
._CACHE
_:
2315 return self
._CACHE
_[Key
]
2319 if Ext
not in self
._FILE
_TYPE
_:
2321 FileType
= self
._FILE
_TYPE
_[Ext
]
2322 if FileType
not in self
._GENERATOR
_:
2325 # get the parser ready for this file
2326 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2329 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2331 # alwasy do post-process, in case of macros change
2332 MetaFile
.DoPostProcess()
2333 # object the build is based on
2334 BuildObject
= self
._GENERATOR
_[FileType
](
2342 self
._CACHE
_[Key
] = BuildObject
2345 # placeholder for file format conversion
2346 class TransformObjectFactory
:
2347 def __init__(self
, WorkspaceDb
):
2348 self
.WorkspaceDb
= WorkspaceDb
2350 # key = FilePath, Arch
2351 def __getitem__(self
, Key
):
2354 ## Constructor of WorkspaceDatabase
2356 # @param DbPath Path of database file
2357 # @param GlobalMacros Global macros used for replacement during file parsing
2358 # @prarm RenewDb=False Create new database file if it's already there
2360 def __init__(self
, DbPath
, RenewDb
=False):
2361 self
._DbClosedFlag
= False
2363 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2365 # don't create necessary path for db in memory
2366 if DbPath
!= ':memory:':
2367 DbDir
= os
.path
.split(DbPath
)[0]
2368 if not os
.path
.exists(DbDir
):
2371 # remove db file in case inconsistency between db and file in file system
2372 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2375 # create db with optimized parameters
2376 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2377 self
.Conn
.execute("PRAGMA synchronous=OFF")
2378 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2379 self
.Conn
.execute("PRAGMA count_changes=OFF")
2380 self
.Conn
.execute("PRAGMA cache_size=8192")
2381 #self.Conn.execute("PRAGMA page_size=8192")
2383 # to avoid non-ascii character conversion issue
2384 self
.Conn
.text_factory
= str
2385 self
.Cur
= self
.Conn
.cursor()
2387 # create table for internal uses
2388 self
.TblDataModel
= TableDataModel(self
.Cur
)
2389 self
.TblFile
= TableFile(self
.Cur
)
2390 self
.Platform
= None
2392 # conversion object for build or file format conversion purpose
2393 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2394 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2396 ## Check whether workspace database need to be renew.
2397 # The renew reason maybe:
2398 # 1) If user force to renew;
2399 # 2) If user do not force renew, and
2400 # a) If the time of last modified python source is newer than database file;
2401 # b) If the time of last modified frozen executable file is newer than database file;
2403 # @param force User force renew database
2404 # @param DbPath The absolute path of workspace database file
2406 # @return Bool value for whether need renew workspace databse
2408 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2409 # if database does not exist, we need do nothing
2410 if not os
.path
.exists(DbPath
): return False
2412 # if user force to renew database, then not check whether database is out of date
2413 if force
: return True
2416 # Check the time of last modified source file or build.exe
2417 # if is newer than time of database, then database need to be re-created.
2419 timeOfToolModified
= 0
2420 if hasattr(sys
, "frozen"):
2421 exePath
= os
.path
.abspath(sys
.executable
)
2422 timeOfToolModified
= os
.stat(exePath
).st_mtime
2424 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2425 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2426 if rootPath
== "" or rootPath
== None:
2427 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2428 determine whether database file is out of date!\n")
2430 # walk the root path of source or build's binary to get the time last modified.
2432 for root
, dirs
, files
in os
.walk (rootPath
):
2434 # bypass source control folder
2435 if dir.lower() in [".svn", "_svn", "cvs"]:
2439 ext
= os
.path
.splitext(file)[1]
2440 if ext
.lower() == ".py": # only check .py files
2441 fd
= os
.stat(os
.path
.join(root
, file))
2442 if timeOfToolModified
< fd
.st_mtime
:
2443 timeOfToolModified
= fd
.st_mtime
2444 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2445 EdkLogger
.verbose("\nWorkspace database is out of data!")
2450 ## Initialize build database
2451 def InitDatabase(self
):
2452 EdkLogger
.verbose("\nInitialize build database started ...")
2457 self
.TblDataModel
.Create(False)
2458 self
.TblFile
.Create(False)
2461 # Initialize table DataModel
2463 self
.TblDataModel
.InitTable()
2464 EdkLogger
.verbose("Initialize build database ... DONE!")
2468 # @param Table: The instance of the table to be queried
2470 def QueryTable(self
, Table
):
2476 ## Close entire database
2479 # Close the connection and cursor
2482 if not self
._DbClosedFlag
:
2486 self
._DbClosedFlag
= True
2488 ## Summarize all packages in the database
2489 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2490 self
.Platform
= Platform
2492 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2494 # Get Package related to Modules
2496 for Module
in Pa
.Modules
:
2497 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2498 for Package
in ModuleObj
.Packages
:
2499 if Package
not in PackageList
:
2500 PackageList
.append(Package
)
2502 # Get Packages related to Libraries
2504 for Lib
in Pa
.LibraryInstances
:
2505 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2506 for Package
in LibObj
.Packages
:
2507 if Package
not in PackageList
:
2508 PackageList
.append(Package
)
2512 ## Summarize all platforms in the database
2513 def _GetPlatformList(self
):
2515 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2517 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2520 if Platform
!= None:
2521 PlatformList
.append(Platform
)
2524 PlatformList
= property(_GetPlatformList
)
2528 # This acts like the main() function for the script, unless it is 'import'ed into another
2531 if __name__
== '__main__':