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 _Macros
= property(_GetMacros
)
857 Arch
= property(_GetArch
, _SetArch
)
858 Platform
= property(_GetPlatformName
)
859 PlatformName
= property(_GetPlatformName
)
860 Guid
= property(_GetFileGuid
)
861 Version
= property(_GetVersion
)
862 DscSpecification
= property(_GetDscSpec
)
863 OutputDirectory
= property(_GetOutpuDir
)
864 SupArchList
= property(_GetSupArch
)
865 BuildTargets
= property(_GetBuildTarget
)
866 SkuName
= property(_GetSkuName
, _SetSkuName
)
867 FlashDefinition
= property(_GetFdfFile
)
868 BuildNumber
= property(_GetBuildNumber
)
869 MakefileName
= property(_GetMakefileName
)
870 BsBaseAddress
= property(_GetBsBaseAddress
)
871 RtBaseAddress
= property(_GetRtBaseAddress
)
872 LoadFixAddress
= property(_GetLoadFixAddress
)
873 RFCLanguages
= property(_GetRFCLanguages
)
874 ISOLanguages
= property(_GetISOLanguages
)
875 VpdToolGuid
= property(_GetVpdToolGuid
)
876 SkuIds
= property(_GetSkuIds
)
877 Modules
= property(_GetModules
)
878 LibraryInstances
= property(_GetLibraryInstances
)
879 LibraryClasses
= property(_GetLibraryClasses
)
880 Pcds
= property(_GetPcds
)
881 BuildOptions
= property(_GetBuildOptions
)
883 ## Platform build information from DEC file
885 # This class is used to retrieve information stored in database and convert them
886 # into PackageBuildClassObject form for easier use for AutoGen.
888 class DecBuildData(PackageBuildClassObject
):
889 # dict used to convert PCD type in database to string used by build tool
890 _PCD_TYPE_STRING_
= {
891 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
892 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
893 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
894 MODEL_PCD_DYNAMIC
: "Dynamic",
895 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
896 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
897 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
898 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
899 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
900 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
901 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
904 # dict used to convert part of [Defines] to members of DecBuildData directly
909 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
910 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
911 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
912 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
916 ## Constructor of DecBuildData
918 # Initialize object of DecBuildData
920 # @param FilePath The path of package description file
921 # @param RawData The raw data of DEC file
922 # @param BuildDataBase Database used to retrieve module information
923 # @param Arch The target architecture
924 # @param Platform (not used for DecBuildData)
925 # @param Macros Macros used for replacement in DSC file
927 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
929 self
._PackageDir
= File
.Dir
930 self
._RawData
= RawData
931 self
._Bdb
= BuildDataBase
933 self
._Target
= Target
934 self
._Toolchain
= Toolchain
938 def __setitem__(self
, key
, value
):
939 self
.__dict
__[self
._PROPERTY
_[key
]] = value
942 def __getitem__(self
, key
):
943 return self
.__dict
__[self
._PROPERTY
_[key
]]
946 def __contains__(self
, key
):
947 return key
in self
._PROPERTY
_
949 ## Set all internal used members of DecBuildData to None
952 self
._PackageName
= None
955 self
._PkgUniFile
= None
956 self
._Protocols
= None
959 self
._Includes
= None
960 self
._LibraryClasses
= None
964 ## Get current effective macros
965 def _GetMacros(self
):
966 if self
.__Macros
== None:
968 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
977 # Changing the default ARCH to another may affect all other information
978 # because all information in a platform may be ARCH-related. That's
979 # why we need to clear all internal used members, in order to cause all
980 # information to be re-retrieved.
982 # @param Value The value of ARCH
984 def _SetArch(self
, Value
):
985 if self
._Arch
== Value
:
990 ## Retrieve all information in [Defines] section
992 # (Retriving all [Defines] information in one-shot is just to save time.)
994 def _GetHeaderInfo(self
):
995 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
996 for Record
in RecordList
:
999 self
[Name
] = Record
[2]
1000 self
._Header
= 'DUMMY'
1002 ## Retrieve package name
1003 def _GetPackageName(self
):
1004 if self
._PackageName
== None:
1005 if self
._Header
== None:
1006 self
._GetHeaderInfo
()
1007 if self
._PackageName
== None:
1008 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1009 return self
._PackageName
1011 ## Retrieve file guid
1012 def _GetFileGuid(self
):
1013 if self
._Guid
== None:
1014 if self
._Header
== None:
1015 self
._GetHeaderInfo
()
1016 if self
._Guid
== None:
1017 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1020 ## Retrieve package version
1021 def _GetVersion(self
):
1022 if self
._Version
== None:
1023 if self
._Header
== None:
1024 self
._GetHeaderInfo
()
1025 if self
._Version
== None:
1027 return self
._Version
1029 ## Retrieve protocol definitions (name/value pairs)
1030 def _GetProtocol(self
):
1031 if self
._Protocols
== None:
1033 # tdict is a special kind of dict, used for selecting correct
1034 # protocol defition for given ARCH
1036 ProtocolDict
= tdict(True)
1038 # find out all protocol definitions for specific and 'common' arch
1039 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1040 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1041 if Name
not in NameList
:
1042 NameList
.append(Name
)
1043 ProtocolDict
[Arch
, Name
] = Guid
1044 # use sdict to keep the order
1045 self
._Protocols
= sdict()
1046 for Name
in NameList
:
1048 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1049 # will automatically turn to 'common' ARCH for trying
1051 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1052 return self
._Protocols
1054 ## Retrieve PPI definitions (name/value pairs)
1056 if self
._Ppis
== None:
1058 # tdict is a special kind of dict, used for selecting correct
1059 # PPI defition for given ARCH
1061 PpiDict
= tdict(True)
1063 # find out all PPI definitions for specific arch and 'common' arch
1064 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1065 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1066 if Name
not in NameList
:
1067 NameList
.append(Name
)
1068 PpiDict
[Arch
, Name
] = Guid
1069 # use sdict to keep the order
1070 self
._Ppis
= sdict()
1071 for Name
in NameList
:
1073 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1074 # will automatically turn to 'common' ARCH for trying
1076 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1079 ## Retrieve GUID definitions (name/value pairs)
1081 if self
._Guids
== None:
1083 # tdict is a special kind of dict, used for selecting correct
1084 # GUID defition for given ARCH
1086 GuidDict
= tdict(True)
1088 # find out all protocol definitions for specific and 'common' arch
1089 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1090 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1091 if Name
not in NameList
:
1092 NameList
.append(Name
)
1093 GuidDict
[Arch
, Name
] = Guid
1094 # use sdict to keep the order
1095 self
._Guids
= sdict()
1096 for Name
in NameList
:
1098 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1099 # will automatically turn to 'common' ARCH for trying
1101 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1104 ## Retrieve public include paths declared in this package
1105 def _GetInclude(self
):
1106 if self
._Includes
== None:
1108 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1109 Macros
= self
._Macros
1110 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1111 for Record
in RecordList
:
1112 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1115 ErrorCode
, ErrorInfo
= File
.Validate()
1117 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1119 # avoid duplicate include path
1120 if File
not in self
._Includes
:
1121 self
._Includes
.append(File
)
1122 return self
._Includes
1124 ## Retrieve library class declarations (not used in build at present)
1125 def _GetLibraryClass(self
):
1126 if self
._LibraryClasses
== None:
1128 # tdict is a special kind of dict, used for selecting correct
1129 # library class declaration for given ARCH
1131 LibraryClassDict
= tdict(True)
1132 LibraryClassSet
= set()
1133 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1134 Macros
= self
._Macros
1135 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1136 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1137 # check the file validation
1138 ErrorCode
, ErrorInfo
= File
.Validate()
1140 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1141 LibraryClassSet
.add(LibraryClass
)
1142 LibraryClassDict
[Arch
, LibraryClass
] = File
1143 self
._LibraryClasses
= sdict()
1144 for LibraryClass
in LibraryClassSet
:
1145 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1146 return self
._LibraryClasses
1148 ## Retrieve PCD declarations
1150 if self
._Pcds
== None:
1151 self
._Pcds
= sdict()
1152 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1153 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1154 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1155 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1156 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1159 ## Retrieve PCD declarations for given type
1160 def _GetPcd(self
, Type
):
1163 # tdict is a special kind of dict, used for selecting correct
1164 # PCD declaration for given ARCH
1166 PcdDict
= tdict(True, 3)
1167 # for summarizing PCD
1169 # find out all PCDs of the 'type'
1170 RecordList
= self
._RawData
[Type
, self
._Arch
]
1171 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1172 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1173 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1175 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1177 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1178 # will automatically turn to 'common' ARCH and try again
1180 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1184 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1186 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1189 self
._PCD
_TYPE
_STRING
_[Type
],
1201 _Macros
= property(_GetMacros
)
1202 Arch
= property(_GetArch
, _SetArch
)
1203 PackageName
= property(_GetPackageName
)
1204 Guid
= property(_GetFileGuid
)
1205 Version
= property(_GetVersion
)
1207 Protocols
= property(_GetProtocol
)
1208 Ppis
= property(_GetPpi
)
1209 Guids
= property(_GetGuid
)
1210 Includes
= property(_GetInclude
)
1211 LibraryClasses
= property(_GetLibraryClass
)
1212 Pcds
= property(_GetPcds
)
1214 ## Module build information from INF file
1216 # This class is used to retrieve information stored in database and convert them
1217 # into ModuleBuildClassObject form for easier use for AutoGen.
1219 class InfBuildData(ModuleBuildClassObject
):
1220 # dict used to convert PCD type in database to string used by build tool
1221 _PCD_TYPE_STRING_
= {
1222 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1223 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1224 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1225 MODEL_PCD_DYNAMIC
: "Dynamic",
1226 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1227 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1228 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1229 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1230 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1231 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1232 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1235 # dict used to convert part of [Defines] to members of InfBuildData directly
1240 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1241 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1242 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1246 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1247 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1248 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1249 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1250 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1251 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1252 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1253 TAB_INF_DEFINES_VERSION
: "_Version",
1254 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1255 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1257 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1260 # dict used to convert Component type to Module type
1263 "SECURITY_CORE" : "SEC",
1264 "PEI_CORE" : "PEI_CORE",
1265 "COMBINED_PEIM_DRIVER" : "PEIM",
1266 "PIC_PEIM" : "PEIM",
1267 "RELOCATABLE_PEIM" : "PEIM",
1268 "PE32_PEIM" : "PEIM",
1269 "BS_DRIVER" : "DXE_DRIVER",
1270 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1271 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1272 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1273 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1274 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1275 # "BS_DRIVER" : "UEFI_DRIVER",
1276 "APPLICATION" : "UEFI_APPLICATION",
1280 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1281 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1282 # dict used to convert old tool name used in [nmake] section to new ones
1290 ## Constructor of DscBuildData
1292 # Initialize object of DscBuildData
1294 # @param FilePath The path of platform description file
1295 # @param RawData The raw data of DSC file
1296 # @param BuildDataBase Database used to retrieve module/package information
1297 # @param Arch The target architecture
1298 # @param Platform The name of platform employing this module
1299 # @param Macros Macros used for replacement in DSC file
1301 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1302 self
.MetaFile
= FilePath
1303 self
._ModuleDir
= FilePath
.Dir
1304 self
._RawData
= RawData
1305 self
._Bdb
= BuildDatabase
1307 self
._Target
= Target
1308 self
._Toolchain
= Toolchain
1309 self
._Platform
= 'COMMON'
1310 self
._SourceOverridePath
= None
1311 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1312 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1316 def __setitem__(self
, key
, value
):
1317 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1320 def __getitem__(self
, key
):
1321 return self
.__dict
__[self
._PROPERTY
_[key
]]
1323 ## "in" test support
1324 def __contains__(self
, key
):
1325 return key
in self
._PROPERTY
_
1327 ## Set all internal used members of InfBuildData to None
1329 self
._Header
_ = None
1330 self
._AutoGenVersion
= None
1331 self
._BaseName
= None
1332 self
._DxsFile
= None
1333 self
._ModuleType
= None
1334 self
._ComponentType
= None
1335 self
._BuildType
= None
1337 self
._Version
= None
1338 self
._PcdIsDriver
= None
1339 self
._BinaryModule
= None
1341 self
._MakefileName
= None
1342 self
._CustomMakefile
= None
1343 self
._Specification
= None
1344 self
._LibraryClass
= None
1345 self
._ModuleEntryPointList
= None
1346 self
._ModuleUnloadImageList
= None
1347 self
._ConstructorList
= None
1348 self
._DestructorList
= None
1350 self
._Binaries
= None
1351 self
._Sources
= None
1352 self
._LibraryClasses
= None
1353 self
._Libraries
= None
1354 self
._Protocols
= None
1357 self
._Includes
= None
1358 self
._Packages
= None
1360 self
._BuildOptions
= None
1362 self
._DepexExpression
= None
1363 self
.__Macros
= None
1365 ## Get current effective macros
1366 def _GetMacros(self
):
1367 if self
.__Macros
== None:
1369 # EDK_GLOBAL defined macros can be applied to EDK module
1370 if self
.AutoGenVersion
< 0x00010005:
1371 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1372 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1373 return self
.__Macros
1381 # Changing the default ARCH to another may affect all other information
1382 # because all information in a platform may be ARCH-related. That's
1383 # why we need to clear all internal used members, in order to cause all
1384 # information to be re-retrieved.
1386 # @param Value The value of ARCH
1388 def _SetArch(self
, Value
):
1389 if self
._Arch
== Value
:
1394 ## Return the name of platform employing this module
1395 def _GetPlatform(self
):
1396 return self
._Platform
1398 ## Change the name of platform employing this module
1400 # Changing the default name of platform to another may affect some information
1401 # because they may be PLATFORM-related. That's why we need to clear all internal
1402 # used members, in order to cause all information to be re-retrieved.
1404 def _SetPlatform(self
, Value
):
1405 if self
._Platform
== Value
:
1407 self
._Platform
= Value
1410 ## Retrieve all information in [Defines] section
1412 # (Retriving all [Defines] information in one-shot is just to save time.)
1414 def _GetHeaderInfo(self
):
1415 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1416 for Record
in RecordList
:
1417 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1418 # items defined _PROPERTY_ don't need additional processing
1421 # some special items in [Defines] section need special treatment
1422 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1423 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1424 Name
= 'UEFI_SPECIFICATION_VERSION'
1425 if self
._Specification
== None:
1426 self
._Specification
= sdict()
1427 self
._Specification
[Name
] = GetHexVerValue(Value
)
1428 if self
._Specification
[Name
] == None:
1429 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1430 "'%s' format is not supported for %s" % (Value
, Name
),
1431 File
=self
.MetaFile
, Line
=Record
[-1])
1432 elif Name
== 'LIBRARY_CLASS':
1433 if self
._LibraryClass
== None:
1434 self
._LibraryClass
= []
1435 ValueList
= GetSplitValueList(Value
)
1436 LibraryClass
= ValueList
[0]
1437 if len(ValueList
) > 1:
1438 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1440 SupModuleList
= SUP_MODULE_LIST
1441 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1442 elif Name
== 'ENTRY_POINT':
1443 if self
._ModuleEntryPointList
== None:
1444 self
._ModuleEntryPointList
= []
1445 self
._ModuleEntryPointList
.append(Value
)
1446 elif Name
== 'UNLOAD_IMAGE':
1447 if self
._ModuleUnloadImageList
== None:
1448 self
._ModuleUnloadImageList
= []
1451 self
._ModuleUnloadImageList
.append(Value
)
1452 elif Name
== 'CONSTRUCTOR':
1453 if self
._ConstructorList
== None:
1454 self
._ConstructorList
= []
1457 self
._ConstructorList
.append(Value
)
1458 elif Name
== 'DESTRUCTOR':
1459 if self
._DestructorList
== None:
1460 self
._DestructorList
= []
1463 self
._DestructorList
.append(Value
)
1464 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1465 TokenList
= GetSplitValueList(Value
)
1466 if self
._CustomMakefile
== None:
1467 self
._CustomMakefile
= {}
1468 if len(TokenList
) < 2:
1469 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1470 self
._CustomMakefile
['GCC'] = TokenList
[0]
1472 if TokenList
[0] not in ['MSFT', 'GCC']:
1473 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1474 "No supported family [%s]" % TokenList
[0],
1475 File
=self
.MetaFile
, Line
=Record
[-1])
1476 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1478 if self
._Defs
== None:
1479 self
._Defs
= sdict()
1480 self
._Defs
[Name
] = Value
1483 # Retrieve information in sections specific to Edk.x modules
1485 if self
.AutoGenVersion
>= 0x00010005:
1486 if not self
._ModuleType
:
1487 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1488 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1489 if self
._ModuleType
not in SUP_MODULE_LIST
:
1490 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1491 for Record
in RecordList
:
1493 if Name
== "MODULE_TYPE":
1496 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1497 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1498 File
=self
.MetaFile
, Line
=LineNo
)
1499 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1500 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1501 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
)
1502 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1503 and 'PCI_CLASS_CODE' in self
._Defs
:
1504 self
._BuildType
= 'UEFI_OPTIONROM'
1505 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1506 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1507 self
._BuildType
= 'UEFI_HII'
1509 self
._BuildType
= self
._ModuleType
.upper()
1512 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1513 # check the file validation
1514 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1516 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1517 File
=self
.MetaFile
, Line
=LineNo
)
1518 if self
.Sources
== None:
1520 self
._Sources
.append(File
)
1522 if not self
._ComponentType
:
1523 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1524 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1525 self
._BuildType
= self
._ComponentType
.upper()
1526 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1527 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1528 if self
._ComponentType
== 'LIBRARY':
1529 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1530 # make use some [nmake] section macros
1531 Macros
= self
._Macros
1532 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1533 Macros
['PROCESSOR'] = self
._Arch
1534 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1535 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1536 Value
= ReplaceMacro(Value
, Macros
, True)
1537 if Name
== "IMAGE_ENTRY_POINT":
1538 if self
._ModuleEntryPointList
== None:
1539 self
._ModuleEntryPointList
= []
1540 self
._ModuleEntryPointList
.append(Value
)
1541 elif Name
== "DPX_SOURCE":
1542 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1543 # check the file validation
1544 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1546 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1547 File
=self
.MetaFile
, Line
=LineNo
)
1548 if self
.Sources
== None:
1550 self
._Sources
.append(File
)
1552 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1553 if len(ToolList
) == 0 or len(ToolList
) != 1:
1555 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1556 # File=self.MetaFile, Line=LineNo)
1558 if self
._BuildOptions
== None:
1559 self
._BuildOptions
= sdict()
1561 if ToolList
[0] in self
._TOOL
_CODE
_:
1562 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1565 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1566 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1567 #ignore not replaced macros in value
1568 ValueList
= GetSplitList(' ' + Value
, '/D')
1569 Dummy
= ValueList
[0]
1570 for Index
in range(1, len(ValueList
)):
1571 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1573 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1574 Value
= Dummy
.strip()
1575 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1576 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1578 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1579 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1580 # set _Header to non-None in order to avoid database re-querying
1581 self
._Header
_ = 'DUMMY'
1583 ## Retrieve file version
1584 def _GetInfVersion(self
):
1585 if self
._AutoGenVersion
== None:
1586 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1587 for Record
in RecordList
:
1588 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1589 self
._AutoGenVersion
= int(Record
[2], 0)
1591 if self
._AutoGenVersion
== None:
1592 self
._AutoGenVersion
= 0x00010000
1593 return self
._AutoGenVersion
1595 ## Retrieve BASE_NAME
1596 def _GetBaseName(self
):
1597 if self
._BaseName
== None:
1598 if self
._Header
_ == None:
1599 self
._GetHeaderInfo
()
1600 if self
._BaseName
== None:
1601 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1602 return self
._BaseName
1605 def _GetDxsFile(self
):
1606 if self
._DxsFile
== None:
1607 if self
._Header
_ == None:
1608 self
._GetHeaderInfo
()
1609 if self
._DxsFile
== None:
1611 return self
._DxsFile
1613 ## Retrieve MODULE_TYPE
1614 def _GetModuleType(self
):
1615 if self
._ModuleType
== None:
1616 if self
._Header
_ == None:
1617 self
._GetHeaderInfo
()
1618 if self
._ModuleType
== None:
1619 self
._ModuleType
= 'BASE'
1620 if self
._ModuleType
not in SUP_MODULE_LIST
:
1621 self
._ModuleType
= "USER_DEFINED"
1622 return self
._ModuleType
1624 ## Retrieve COMPONENT_TYPE
1625 def _GetComponentType(self
):
1626 if self
._ComponentType
== None:
1627 if self
._Header
_ == None:
1628 self
._GetHeaderInfo
()
1629 if self
._ComponentType
== None:
1630 self
._ComponentType
= 'USER_DEFINED'
1631 return self
._ComponentType
1633 ## Retrieve "BUILD_TYPE"
1634 def _GetBuildType(self
):
1635 if self
._BuildType
== None:
1636 if self
._Header
_ == None:
1637 self
._GetHeaderInfo
()
1638 if not self
._BuildType
:
1639 self
._BuildType
= "BASE"
1640 return self
._BuildType
1642 ## Retrieve file guid
1643 def _GetFileGuid(self
):
1644 if self
._Guid
== None:
1645 if self
._Header
_ == None:
1646 self
._GetHeaderInfo
()
1647 if self
._Guid
== None:
1648 self
._Guid
= '00000000-0000-0000-000000000000'
1651 ## Retrieve module version
1652 def _GetVersion(self
):
1653 if self
._Version
== None:
1654 if self
._Header
_ == None:
1655 self
._GetHeaderInfo
()
1656 if self
._Version
== None:
1657 self
._Version
= '0.0'
1658 return self
._Version
1660 ## Retrieve PCD_IS_DRIVER
1661 def _GetPcdIsDriver(self
):
1662 if self
._PcdIsDriver
== None:
1663 if self
._Header
_ == None:
1664 self
._GetHeaderInfo
()
1665 if self
._PcdIsDriver
== None:
1666 self
._PcdIsDriver
= ''
1667 return self
._PcdIsDriver
1670 def _GetShadow(self
):
1671 if self
._Shadow
== None:
1672 if self
._Header
_ == None:
1673 self
._GetHeaderInfo
()
1674 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1677 self
._Shadow
= False
1680 ## Retrieve CUSTOM_MAKEFILE
1681 def _GetMakefile(self
):
1682 if self
._CustomMakefile
== None:
1683 if self
._Header
_ == None:
1684 self
._GetHeaderInfo
()
1685 if self
._CustomMakefile
== None:
1686 self
._CustomMakefile
= {}
1687 return self
._CustomMakefile
1689 ## Retrieve EFI_SPECIFICATION_VERSION
1691 if self
._Specification
== None:
1692 if self
._Header
_ == None:
1693 self
._GetHeaderInfo
()
1694 if self
._Specification
== None:
1695 self
._Specification
= {}
1696 return self
._Specification
1698 ## Retrieve LIBRARY_CLASS
1699 def _GetLibraryClass(self
):
1700 if self
._LibraryClass
== None:
1701 if self
._Header
_ == None:
1702 self
._GetHeaderInfo
()
1703 if self
._LibraryClass
== None:
1704 self
._LibraryClass
= []
1705 return self
._LibraryClass
1707 ## Retrieve ENTRY_POINT
1708 def _GetEntryPoint(self
):
1709 if self
._ModuleEntryPointList
== None:
1710 if self
._Header
_ == None:
1711 self
._GetHeaderInfo
()
1712 if self
._ModuleEntryPointList
== None:
1713 self
._ModuleEntryPointList
= []
1714 return self
._ModuleEntryPointList
1716 ## Retrieve UNLOAD_IMAGE
1717 def _GetUnloadImage(self
):
1718 if self
._ModuleUnloadImageList
== None:
1719 if self
._Header
_ == None:
1720 self
._GetHeaderInfo
()
1721 if self
._ModuleUnloadImageList
== None:
1722 self
._ModuleUnloadImageList
= []
1723 return self
._ModuleUnloadImageList
1725 ## Retrieve CONSTRUCTOR
1726 def _GetConstructor(self
):
1727 if self
._ConstructorList
== None:
1728 if self
._Header
_ == None:
1729 self
._GetHeaderInfo
()
1730 if self
._ConstructorList
== None:
1731 self
._ConstructorList
= []
1732 return self
._ConstructorList
1734 ## Retrieve DESTRUCTOR
1735 def _GetDestructor(self
):
1736 if self
._DestructorList
== None:
1737 if self
._Header
_ == None:
1738 self
._GetHeaderInfo
()
1739 if self
._DestructorList
== None:
1740 self
._DestructorList
= []
1741 return self
._DestructorList
1743 ## Retrieve definies other than above ones
1744 def _GetDefines(self
):
1745 if self
._Defs
== None:
1746 if self
._Header
_ == None:
1747 self
._GetHeaderInfo
()
1748 if self
._Defs
== None:
1749 self
._Defs
= sdict()
1752 ## Retrieve binary files
1753 def _GetBinaryFiles(self
):
1754 if self
._Binaries
== None:
1756 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
1757 Macros
= self
._Macros
1758 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1759 Macros
['PROCESSOR'] = self
._Arch
1760 for Record
in RecordList
:
1761 FileType
= Record
[0]
1766 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
1768 Target
= TokenList
[0]
1769 if len(TokenList
) > 1:
1770 FeatureFlag
= Record
[1:]
1772 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
1773 # check the file validation
1774 ErrorCode
, ErrorInfo
= File
.Validate()
1776 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1777 self
._Binaries
.append(File
)
1778 return self
._Binaries
1780 ## Retrieve source files
1781 def _GetSourceFiles(self
):
1782 if self
._Sources
== None:
1784 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
1785 Macros
= self
._Macros
1786 for Record
in RecordList
:
1788 ToolChainFamily
= Record
[1]
1790 ToolCode
= Record
[3]
1791 FeatureFlag
= Record
[4]
1792 if self
.AutoGenVersion
< 0x00010005:
1793 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1794 Macros
['PROCESSOR'] = self
._Arch
1795 # old module source files (Edk)
1796 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
1797 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1798 # check the file validation
1799 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
1801 if File
.Ext
.lower() == '.h':
1802 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
1803 File
=self
.MetaFile
, Line
=LineNo
)
1806 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
1808 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
1809 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1810 # check the file validation
1811 ErrorCode
, ErrorInfo
= File
.Validate()
1813 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1815 self
._Sources
.append(File
)
1816 return self
._Sources
1818 ## Retrieve library classes employed by this module
1819 def _GetLibraryClassUses(self
):
1820 if self
._LibraryClasses
== None:
1821 self
._LibraryClasses
= sdict()
1822 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
1823 for Record
in RecordList
:
1825 Instance
= Record
[1]
1827 Instance
= NormPath(Instance
, self
._Macros
)
1828 self
._LibraryClasses
[Lib
] = Instance
1829 return self
._LibraryClasses
1831 ## Retrieve library names (for Edk.x style of modules)
1832 def _GetLibraryNames(self
):
1833 if self
._Libraries
== None:
1834 self
._Libraries
= []
1835 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
1836 for Record
in RecordList
:
1837 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
1838 # in case of name with '.lib' extension, which is unusual in Edk.x inf
1839 LibraryName
= os
.path
.splitext(LibraryName
)[0]
1840 if LibraryName
not in self
._Libraries
:
1841 self
._Libraries
.append(LibraryName
)
1842 return self
._Libraries
1844 ## Retrieve protocols consumed/produced by this module
1845 def _GetProtocols(self
):
1846 if self
._Protocols
== None:
1847 self
._Protocols
= sdict()
1848 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
1849 for Record
in RecordList
:
1851 Value
= ProtocolValue(CName
, self
.Packages
)
1853 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1854 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1855 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
1856 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1857 self
._Protocols
[CName
] = Value
1858 return self
._Protocols
1860 ## Retrieve PPIs consumed/produced by this module
1862 if self
._Ppis
== None:
1863 self
._Ppis
= sdict()
1864 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
1865 for Record
in RecordList
:
1867 Value
= PpiValue(CName
, self
.Packages
)
1869 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1870 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1871 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
1872 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1873 self
._Ppis
[CName
] = Value
1876 ## Retrieve GUIDs consumed/produced by this module
1877 def _GetGuids(self
):
1878 if self
._Guids
== None:
1879 self
._Guids
= sdict()
1880 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
1881 for Record
in RecordList
:
1883 Value
= GuidValue(CName
, self
.Packages
)
1885 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1886 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1887 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
1888 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1889 self
._Guids
[CName
] = Value
1892 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
1893 def _GetIncludes(self
):
1894 if self
._Includes
== None:
1896 if self
._SourceOverridePath
:
1897 self
._Includes
.append(self
._SourceOverridePath
)
1899 Macros
= self
._Macros
1900 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
1901 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
1903 Macros
['PROCESSOR'] = self
._Arch
1904 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
1905 for Record
in RecordList
:
1906 if Record
[0].find('EDK_SOURCE') > -1:
1907 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
1908 File
= NormPath(Record
[0], self
._Macros
)
1910 File
= os
.path
.join(self
._ModuleDir
, File
)
1912 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1913 File
= RealPath(os
.path
.normpath(File
))
1915 self
._Includes
.append(File
)
1917 #TRICK: let compiler to choose correct header file
1918 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
1919 File
= NormPath(Record
[0], self
._Macros
)
1921 File
= os
.path
.join(self
._ModuleDir
, File
)
1923 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1924 File
= RealPath(os
.path
.normpath(File
))
1926 self
._Includes
.append(File
)
1928 File
= NormPath(Record
[0], Macros
)
1930 File
= os
.path
.join(self
._ModuleDir
, File
)
1932 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1933 File
= RealPath(os
.path
.normpath(File
))
1935 self
._Includes
.append(File
)
1936 return self
._Includes
1938 ## Retrieve packages this module depends on
1939 def _GetPackages(self
):
1940 if self
._Packages
== None:
1942 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
1943 Macros
= self
._Macros
1944 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
1945 for Record
in RecordList
:
1946 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
1948 # check the file validation
1949 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
1951 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1952 # parse this package now. we need it to get protocol/ppi/guid value
1953 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
1954 self
._Packages
.append(Package
)
1955 return self
._Packages
1957 ## Retrieve PCDs used in this module
1959 if self
._Pcds
== None:
1960 self
._Pcds
= sdict()
1961 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1962 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1963 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1964 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1965 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1968 ## Retrieve build options specific to this module
1969 def _GetBuildOptions(self
):
1970 if self
._BuildOptions
== None:
1971 self
._BuildOptions
= sdict()
1972 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
1973 for Record
in RecordList
:
1974 ToolChainFamily
= Record
[0]
1975 ToolChain
= Record
[1]
1977 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1978 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
1980 # concatenate the option string if they're for the same tool
1981 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1982 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
1983 return self
._BuildOptions
1985 ## Retrieve dependency expression
1986 def _GetDepex(self
):
1987 if self
._Depex
== None:
1988 self
._Depex
= tdict(False, 2)
1989 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1991 # If the module has only Binaries and no Sources, then ignore [Depex]
1992 if self
.Sources
== None or self
.Sources
== []:
1993 if self
.Binaries
!= None and self
.Binaries
!= []:
1996 # PEIM and DXE drivers must have a valid [Depex] section
1997 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
1998 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
1999 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2000 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2001 % self
.ModuleType
, File
=self
.MetaFile
)
2004 for Record
in RecordList
:
2005 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2007 ModuleType
= Record
[4]
2008 TokenList
= DepexStr
.split()
2009 if (Arch
, ModuleType
) not in Depex
:
2010 Depex
[Arch
, ModuleType
] = []
2011 DepexList
= Depex
[Arch
, ModuleType
]
2012 for Token
in TokenList
:
2013 if Token
in DEPEX_SUPPORTED_OPCODE
:
2014 DepexList
.append(Token
)
2015 elif Token
.endswith(".inf"): # module file name
2016 ModuleFile
= os
.path
.normpath(Token
)
2017 Module
= self
.BuildDatabase
[ModuleFile
]
2019 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2020 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2021 DepexList
.append(Module
.Guid
)
2023 # get the GUID value now
2024 Value
= ProtocolValue(Token
, self
.Packages
)
2026 Value
= PpiValue(Token
, self
.Packages
)
2028 Value
= GuidValue(Token
, self
.Packages
)
2030 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2031 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2032 "Value of [%s] is not found in" % Token
,
2033 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2034 DepexList
.append(Value
)
2035 for Arch
, ModuleType
in Depex
:
2036 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2039 ## Retrieve depedency expression
2040 def _GetDepexExpression(self
):
2041 if self
._DepexExpression
== None:
2042 self
._DepexExpression
= tdict(False, 2)
2043 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2044 DepexExpression
= sdict()
2045 for Record
in RecordList
:
2046 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2048 ModuleType
= Record
[4]
2049 TokenList
= DepexStr
.split()
2050 if (Arch
, ModuleType
) not in DepexExpression
:
2051 DepexExpression
[Arch
, ModuleType
] = ''
2052 for Token
in TokenList
:
2053 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2054 for Arch
, ModuleType
in DepexExpression
:
2055 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2056 return self
._DepexExpression
2058 ## Retrieve PCD for given type
2059 def _GetPcd(self
, Type
):
2061 PcdDict
= tdict(True, 4)
2063 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2064 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Dummy1
, LineNo
in RecordList
:
2065 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2066 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2067 # get the guid value
2068 if TokenSpaceGuid
not in self
.Guids
:
2069 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2071 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2072 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2073 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2074 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2075 self
.Guids
[TokenSpaceGuid
] = Value
2077 # resolve PCD type, value, datum info, etc. by getting its definition from package
2078 for PcdCName
, TokenSpaceGuid
in PcdList
:
2079 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2082 ValueList
= AnalyzePcdData(Setting
)
2083 DefaultValue
= ValueList
[0]
2084 Pcd
= PcdClassObject(
2094 self
.Guids
[TokenSpaceGuid
]
2097 # get necessary info from package declaring this PCD
2098 for Package
in self
.Packages
:
2100 # 'dynamic' in INF means its type is determined by platform;
2101 # if platform doesn't give its type, use 'lowest' one in the
2102 # following order, if any
2104 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2106 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2107 if Type
== MODEL_PCD_DYNAMIC
:
2109 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2110 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2116 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2117 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2119 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2122 # Check whether the token value exist or not.
2124 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2128 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2129 File
=self
.MetaFile
, Line
=LineNo
,
2133 # Check hexadecimal token value length and format.
2135 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2136 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2137 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2141 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2142 File
=self
.MetaFile
, Line
=LineNo
,
2147 # Check decimal token value length and format.
2151 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2152 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2156 "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
)),
2157 File
=self
.MetaFile
, Line
=LineNo
,
2164 "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
)),
2165 File
=self
.MetaFile
, Line
=LineNo
,
2169 Pcd
.DatumType
= PcdInPackage
.DatumType
2170 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2171 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2172 if Pcd
.DefaultValue
in [None, '']:
2173 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2179 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2180 File
=self
.MetaFile
, Line
=LineNo
,
2181 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2183 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2187 _Macros
= property(_GetMacros
)
2188 Arch
= property(_GetArch
, _SetArch
)
2189 Platform
= property(_GetPlatform
, _SetPlatform
)
2191 AutoGenVersion
= property(_GetInfVersion
)
2192 BaseName
= property(_GetBaseName
)
2193 ModuleType
= property(_GetModuleType
)
2194 ComponentType
= property(_GetComponentType
)
2195 BuildType
= property(_GetBuildType
)
2196 Guid
= property(_GetFileGuid
)
2197 Version
= property(_GetVersion
)
2198 PcdIsDriver
= property(_GetPcdIsDriver
)
2199 Shadow
= property(_GetShadow
)
2200 CustomMakefile
= property(_GetMakefile
)
2201 Specification
= property(_GetSpec
)
2202 LibraryClass
= property(_GetLibraryClass
)
2203 ModuleEntryPointList
= property(_GetEntryPoint
)
2204 ModuleUnloadImageList
= property(_GetUnloadImage
)
2205 ConstructorList
= property(_GetConstructor
)
2206 DestructorList
= property(_GetDestructor
)
2207 Defines
= property(_GetDefines
)
2208 DxsFile
= property(_GetDxsFile
)
2210 Binaries
= property(_GetBinaryFiles
)
2211 Sources
= property(_GetSourceFiles
)
2212 LibraryClasses
= property(_GetLibraryClassUses
)
2213 Libraries
= property(_GetLibraryNames
)
2214 Protocols
= property(_GetProtocols
)
2215 Ppis
= property(_GetPpis
)
2216 Guids
= property(_GetGuids
)
2217 Includes
= property(_GetIncludes
)
2218 Packages
= property(_GetPackages
)
2219 Pcds
= property(_GetPcds
)
2220 BuildOptions
= property(_GetBuildOptions
)
2221 Depex
= property(_GetDepex
)
2222 DepexExpression
= property(_GetDepexExpression
)
2226 # This class defined the build database for all modules, packages and platform.
2227 # It will call corresponding parser for the given file if it cannot find it in
2230 # @param DbPath Path of database file
2231 # @param GlobalMacros Global macros used for replacement during file parsing
2232 # @prarm RenewDb=False Create new database file if it's already there
2234 class WorkspaceDatabase(object):
2236 # default database file path
2237 _DB_PATH_
= "Conf/.cache/build.db"
2240 # internal class used for call corresponding file parser and caching the result
2241 # to avoid unnecessary re-parsing
2243 class BuildObjectFactory(object):
2246 ".inf" : MODEL_FILE_INF
,
2247 ".dec" : MODEL_FILE_DEC
,
2248 ".dsc" : MODEL_FILE_DSC
,
2253 MODEL_FILE_INF
: InfParser
,
2254 MODEL_FILE_DEC
: DecParser
,
2255 MODEL_FILE_DSC
: DscParser
,
2258 # convert to xxxBuildData object
2260 MODEL_FILE_INF
: InfBuildData
,
2261 MODEL_FILE_DEC
: DecBuildData
,
2262 MODEL_FILE_DSC
: DscBuildData
,
2265 _CACHE_
= {} # (FilePath, Arch) : <object>
2268 def __init__(self
, WorkspaceDb
):
2269 self
.WorkspaceDb
= WorkspaceDb
2271 # key = (FilePath, Arch=None)
2272 def __contains__(self
, Key
):
2278 return (FilePath
, Arch
) in self
._CACHE
_
2280 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2281 def __getitem__(self
, Key
):
2283 KeyLength
= len(Key
)
2297 # if it's generated before, just return the cached one
2298 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2299 if Key
in self
._CACHE
_:
2300 return self
._CACHE
_[Key
]
2304 if Ext
not in self
._FILE
_TYPE
_:
2306 FileType
= self
._FILE
_TYPE
_[Ext
]
2307 if FileType
not in self
._GENERATOR
_:
2310 # get the parser ready for this file
2311 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2314 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2316 # alwasy do post-process, in case of macros change
2317 MetaFile
.DoPostProcess()
2318 # object the build is based on
2319 BuildObject
= self
._GENERATOR
_[FileType
](
2327 self
._CACHE
_[Key
] = BuildObject
2330 # placeholder for file format conversion
2331 class TransformObjectFactory
:
2332 def __init__(self
, WorkspaceDb
):
2333 self
.WorkspaceDb
= WorkspaceDb
2335 # key = FilePath, Arch
2336 def __getitem__(self
, Key
):
2339 ## Constructor of WorkspaceDatabase
2341 # @param DbPath Path of database file
2342 # @param GlobalMacros Global macros used for replacement during file parsing
2343 # @prarm RenewDb=False Create new database file if it's already there
2345 def __init__(self
, DbPath
, RenewDb
=False):
2346 self
._DbClosedFlag
= False
2348 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2350 # don't create necessary path for db in memory
2351 if DbPath
!= ':memory:':
2352 DbDir
= os
.path
.split(DbPath
)[0]
2353 if not os
.path
.exists(DbDir
):
2356 # remove db file in case inconsistency between db and file in file system
2357 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2360 # create db with optimized parameters
2361 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2362 self
.Conn
.execute("PRAGMA synchronous=OFF")
2363 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2364 self
.Conn
.execute("PRAGMA count_changes=OFF")
2365 self
.Conn
.execute("PRAGMA cache_size=8192")
2366 #self.Conn.execute("PRAGMA page_size=8192")
2368 # to avoid non-ascii character conversion issue
2369 self
.Conn
.text_factory
= str
2370 self
.Cur
= self
.Conn
.cursor()
2372 # create table for internal uses
2373 self
.TblDataModel
= TableDataModel(self
.Cur
)
2374 self
.TblFile
= TableFile(self
.Cur
)
2375 self
.Platform
= None
2377 # conversion object for build or file format conversion purpose
2378 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2379 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2381 ## Check whether workspace database need to be renew.
2382 # The renew reason maybe:
2383 # 1) If user force to renew;
2384 # 2) If user do not force renew, and
2385 # a) If the time of last modified python source is newer than database file;
2386 # b) If the time of last modified frozen executable file is newer than database file;
2388 # @param force User force renew database
2389 # @param DbPath The absolute path of workspace database file
2391 # @return Bool value for whether need renew workspace databse
2393 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2394 # if database does not exist, we need do nothing
2395 if not os
.path
.exists(DbPath
): return False
2397 # if user force to renew database, then not check whether database is out of date
2398 if force
: return True
2401 # Check the time of last modified source file or build.exe
2402 # if is newer than time of database, then database need to be re-created.
2404 timeOfToolModified
= 0
2405 if hasattr(sys
, "frozen"):
2406 exePath
= os
.path
.abspath(sys
.executable
)
2407 timeOfToolModified
= os
.stat(exePath
).st_mtime
2409 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2410 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2411 if rootPath
== "" or rootPath
== None:
2412 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2413 determine whether database file is out of date!\n")
2415 # walk the root path of source or build's binary to get the time last modified.
2417 for root
, dirs
, files
in os
.walk (rootPath
):
2419 # bypass source control folder
2420 if dir.lower() in [".svn", "_svn", "cvs"]:
2424 ext
= os
.path
.splitext(file)[1]
2425 if ext
.lower() == ".py": # only check .py files
2426 fd
= os
.stat(os
.path
.join(root
, file))
2427 if timeOfToolModified
< fd
.st_mtime
:
2428 timeOfToolModified
= fd
.st_mtime
2429 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2430 EdkLogger
.verbose("\nWorkspace database is out of data!")
2435 ## Initialize build database
2436 def InitDatabase(self
):
2437 EdkLogger
.verbose("\nInitialize build database started ...")
2442 self
.TblDataModel
.Create(False)
2443 self
.TblFile
.Create(False)
2446 # Initialize table DataModel
2448 self
.TblDataModel
.InitTable()
2449 EdkLogger
.verbose("Initialize build database ... DONE!")
2453 # @param Table: The instance of the table to be queried
2455 def QueryTable(self
, Table
):
2461 ## Close entire database
2464 # Close the connection and cursor
2467 if not self
._DbClosedFlag
:
2471 self
._DbClosedFlag
= True
2473 ## Summarize all packages in the database
2474 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2475 self
.Platform
= Platform
2477 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2479 # Get Package related to Modules
2481 for Module
in Pa
.Modules
:
2482 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2483 for Package
in ModuleObj
.Packages
:
2484 if Package
not in PackageList
:
2485 PackageList
.append(Package
)
2487 # Get Packages related to Libraries
2489 for Lib
in Pa
.LibraryInstances
:
2490 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2491 for Package
in LibObj
.Packages
:
2492 if Package
not in PackageList
:
2493 PackageList
.append(Package
)
2497 ## Summarize all platforms in the database
2498 def _GetPlatformList(self
):
2500 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2502 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2505 if Platform
!= None:
2506 PlatformList
.append(Platform
)
2509 PlatformList
= property(_GetPlatformList
)
2513 # This acts like the main() function for the script, unless it is 'import'ed into another
2516 if __name__
== '__main__':