2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 import Common
.EdkLogger
as EdkLogger
24 import Common
.GlobalData
as GlobalData
26 from Common
.String
import *
27 from Common
.DataType
import *
28 from Common
.Misc
import *
31 from CommonDataClass
.CommonClass
import SkuInfoClass
33 from MetaDataTable
import *
34 from MetaFileTable
import *
35 from MetaFileParser
import *
36 from BuildClassObject
import *
38 ## Platform build information from DSC file
40 # This class is used to retrieve information stored in database and convert them
41 # into PlatformBuildClassObject form for easier use for AutoGen.
43 class DscBuildData(PlatformBuildClassObject
):
44 # dict used to convert PCD type in database to string used by build tool
46 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
47 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
48 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
49 MODEL_PCD_DYNAMIC
: "Dynamic",
50 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
51 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
52 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
53 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
54 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
55 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
56 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
59 # dict used to convert part of [Defines] to members of DscBuildData directly
64 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
65 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
66 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
67 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
68 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
69 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
70 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
71 #TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
72 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
73 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
74 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
75 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
76 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
77 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
78 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
81 # used to compose dummy library class name for those forced library instances
82 _NullLibraryNumber
= 0
84 ## Constructor of DscBuildData
86 # Initialize object of DscBuildData
88 # @param FilePath The path of platform description file
89 # @param RawData The raw data of DSC file
90 # @param BuildDataBase Database used to retrieve module/package information
91 # @param Arch The target architecture
92 # @param Platform (not used for DscBuildData)
93 # @param Macros Macros used for replacement in DSC file
95 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
96 self
.MetaFile
= FilePath
97 self
._RawData
= RawData
98 self
._Bdb
= BuildDataBase
100 self
._Target
= Target
101 self
._Toolchain
= Toolchain
105 def __setitem__(self
, key
, value
):
106 self
.__dict
__[self
._PROPERTY
_[key
]] = value
109 def __getitem__(self
, key
):
110 return self
.__dict
__[self
._PROPERTY
_[key
]]
113 def __contains__(self
, key
):
114 return key
in self
._PROPERTY
_
116 ## Set all internal used members of DscBuildData to None
119 self
._PlatformName
= None
122 self
._DscSpecification
= None
123 self
._OutputDirectory
= None
124 self
._SupArchList
= None
125 self
._BuildTargets
= None
127 self
._FlashDefinition
= None
128 self
._BuildNumber
= None
129 self
._MakefileName
= None
130 self
._BsBaseAddress
= None
131 self
._RtBaseAddress
= None
134 self
._LibraryInstances
= None
135 self
._LibraryClasses
= None
137 self
._BuildOptions
= None
138 self
._LoadFixAddress
= None
139 self
._RFCLanguages
= None
140 self
._ISOLanguages
= None
141 self
._VpdToolGuid
= None
144 ## Get current effective macros
145 def _GetMacros(self
):
146 if self
.__Macros
== None:
148 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
149 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
150 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
159 # Changing the default ARCH to another may affect all other information
160 # because all information in a platform may be ARCH-related. That's
161 # why we need to clear all internal used members, in order to cause all
162 # information to be re-retrieved.
164 # @param Value The value of ARCH
166 def _SetArch(self
, Value
):
167 if self
._Arch
== Value
:
172 ## Retrieve all information in [Defines] section
174 # (Retriving all [Defines] information in one-shot is just to save time.)
176 def _GetHeaderInfo(self
):
177 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
178 for Record
in RecordList
:
180 # items defined _PROPERTY_ don't need additional processing
182 self
[Name
] = Record
[2]
183 # some special items in [Defines] section need special treatment
184 elif Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
185 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
186 if ' ' in self
._OutputDirectory
:
187 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
188 File
=self
.MetaFile
, Line
=Record
[-1],
189 ExtraData
=self
._OutputDirectory
)
190 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
191 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
192 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
194 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
196 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
197 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
198 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
199 self
._BuildTargets
= GetSplitValueList(Record
[2])
200 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
201 if self
._SkuName
== None:
202 self
._SkuName
= Record
[2]
203 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
205 self
._LoadFixAddress
= int (Record
[2], 0)
207 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
208 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
209 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
210 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
211 File
=self
.MetaFile
, Line
=Record
[-1])
212 LanguageCodes
= Record
[2][1:-1]
213 if not LanguageCodes
:
214 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
215 File
=self
.MetaFile
, Line
=Record
[-1])
216 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
217 # check whether there is empty entries in the list
218 if None in LanguageList
:
219 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
220 File
=self
.MetaFile
, Line
=Record
[-1])
221 self
._RFCLanguages
= LanguageList
222 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
223 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
224 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
225 File
=self
.MetaFile
, Line
=Record
[-1])
226 LanguageCodes
= Record
[2][1:-1]
227 if not LanguageCodes
:
228 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
229 File
=self
.MetaFile
, Line
=Record
[-1])
230 if len(LanguageCodes
)%3:
231 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
232 File
=self
.MetaFile
, Line
=Record
[-1])
234 for i
in range(0, len(LanguageCodes
), 3):
235 LanguageList
.append(LanguageCodes
[i
:i
+3])
236 self
._ISOLanguages
= LanguageList
237 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
239 # try to convert GUID to a real UUID value to see whether the GUID is format
240 # for VPD_TOOL_GUID is correct.
245 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
246 self
._VpdToolGuid
= Record
[2]
247 # set _Header to non-None in order to avoid database re-querying
248 self
._Header
= 'DUMMY'
250 ## Retrieve platform name
251 def _GetPlatformName(self
):
252 if self
._PlatformName
== None:
253 if self
._Header
== None:
254 self
._GetHeaderInfo
()
255 if self
._PlatformName
== None:
256 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
257 return self
._PlatformName
259 ## Retrieve file guid
260 def _GetFileGuid(self
):
261 if self
._Guid
== None:
262 if self
._Header
== None:
263 self
._GetHeaderInfo
()
264 if self
._Guid
== None:
265 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No FILE_GUID", File
=self
.MetaFile
)
268 ## Retrieve platform version
269 def _GetVersion(self
):
270 if self
._Version
== None:
271 if self
._Header
== None:
272 self
._GetHeaderInfo
()
273 if self
._Version
== None:
277 ## Retrieve platform description file version
278 def _GetDscSpec(self
):
279 if self
._DscSpecification
== None:
280 if self
._Header
== None:
281 self
._GetHeaderInfo
()
282 if self
._DscSpecification
== None:
283 self
._DscSpecification
= ''
284 return self
._DscSpecification
286 ## Retrieve OUTPUT_DIRECTORY
287 def _GetOutpuDir(self
):
288 if self
._OutputDirectory
== None:
289 if self
._Header
== None:
290 self
._GetHeaderInfo
()
291 if self
._OutputDirectory
== None:
292 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
293 return self
._OutputDirectory
295 ## Retrieve SUPPORTED_ARCHITECTURES
296 def _GetSupArch(self
):
297 if self
._SupArchList
== None:
298 if self
._Header
== None:
299 self
._GetHeaderInfo
()
300 if self
._SupArchList
== None:
301 self
._SupArchList
= ARCH_LIST
302 return self
._SupArchList
304 ## Retrieve BUILD_TARGETS
305 def _GetBuildTarget(self
):
306 if self
._BuildTargets
== None:
307 if self
._Header
== None:
308 self
._GetHeaderInfo
()
309 if self
._BuildTargets
== None:
310 self
._BuildTargets
= ['DEBUG', 'RELEASE', 'NOOPT']
311 return self
._BuildTargets
313 ## Retrieve SKUID_IDENTIFIER
314 def _GetSkuName(self
):
315 if self
._SkuName
== None:
316 if self
._Header
== None:
317 self
._GetHeaderInfo
()
318 if self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
:
319 self
._SkuName
= 'DEFAULT'
322 ## Override SKUID_IDENTIFIER
323 def _SetSkuName(self
, Value
):
324 if Value
in self
.SkuIds
:
325 self
._SkuName
= Value
326 # Needs to re-retrieve the PCD information
329 def _GetFdfFile(self
):
330 if self
._FlashDefinition
== None:
331 if self
._Header
== None:
332 self
._GetHeaderInfo
()
333 if self
._FlashDefinition
== None:
334 self
._FlashDefinition
= ''
335 return self
._FlashDefinition
337 ## Retrieve FLASH_DEFINITION
338 def _GetBuildNumber(self
):
339 if self
._BuildNumber
== None:
340 if self
._Header
== None:
341 self
._GetHeaderInfo
()
342 if self
._BuildNumber
== None:
343 self
._BuildNumber
= ''
344 return self
._BuildNumber
346 ## Retrieve MAKEFILE_NAME
347 def _GetMakefileName(self
):
348 if self
._MakefileName
== None:
349 if self
._Header
== None:
350 self
._GetHeaderInfo
()
351 if self
._MakefileName
== None:
352 self
._MakefileName
= ''
353 return self
._MakefileName
355 ## Retrieve BsBaseAddress
356 def _GetBsBaseAddress(self
):
357 if self
._BsBaseAddress
== None:
358 if self
._Header
== None:
359 self
._GetHeaderInfo
()
360 if self
._BsBaseAddress
== None:
361 self
._BsBaseAddress
= ''
362 return self
._BsBaseAddress
364 ## Retrieve RtBaseAddress
365 def _GetRtBaseAddress(self
):
366 if self
._RtBaseAddress
== None:
367 if self
._Header
== None:
368 self
._GetHeaderInfo
()
369 if self
._RtBaseAddress
== None:
370 self
._RtBaseAddress
= ''
371 return self
._RtBaseAddress
373 ## Retrieve the top address for the load fix address
374 def _GetLoadFixAddress(self
):
375 if self
._LoadFixAddress
== None:
376 if self
._Header
== None:
377 self
._GetHeaderInfo
()
379 if self
._LoadFixAddress
== None:
380 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
383 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
385 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
386 if self
._LoadFixAddress
< 0:
387 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value %s" % (self
._LoadFixAddress
))
388 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
389 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value %s" % (self
._LoadFixAddress
))
390 return self
._LoadFixAddress
392 ## Retrieve RFCLanguage filter
393 def _GetRFCLanguages(self
):
394 if self
._RFCLanguages
== None:
395 if self
._Header
== None:
396 self
._GetHeaderInfo
()
397 if self
._RFCLanguages
== None:
398 self
._RFCLanguages
= []
399 return self
._RFCLanguages
401 ## Retrieve ISOLanguage filter
402 def _GetISOLanguages(self
):
403 if self
._ISOLanguages
== None:
404 if self
._Header
== None:
405 self
._GetHeaderInfo
()
406 if self
._ISOLanguages
== None:
407 self
._ISOLanguages
= []
408 return self
._ISOLanguages
409 ## Retrieve the GUID string for VPD tool
410 def _GetVpdToolGuid(self
):
411 if self
._VpdToolGuid
== None:
412 if self
._Header
== None:
413 self
._GetHeaderInfo
()
414 if self
._VpdToolGuid
== None:
415 self
._VpdToolGuid
= ''
416 return self
._VpdToolGuid
418 ## Retrieve [SkuIds] section information
419 def _GetSkuIds(self
):
420 if self
._SkuIds
== None:
421 self
._SkuIds
= sdict()
422 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
423 for Record
in RecordList
:
424 if Record
[0] in [None, '']:
425 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
426 File
=self
.MetaFile
, Line
=Record
[-1])
427 if Record
[1] in [None, '']:
428 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
429 File
=self
.MetaFile
, Line
=Record
[-1])
430 self
._SkuIds
[Record
[1]] = Record
[0]
431 if 'DEFAULT' not in self
._SkuIds
:
432 self
._SkuIds
['DEFAULT'] = '0'
435 ## Retrieve [Components] section information
436 def _GetModules(self
):
437 if self
._Modules
!= None:
440 self
._Modules
= sdict()
441 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
442 Macros
= self
._Macros
443 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
444 for Record
in RecordList
:
445 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
449 # check the file validation
450 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
452 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
455 if ModuleFile
in self
._Modules
:
456 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
458 Module
= ModuleBuildClassObject()
459 Module
.MetaFile
= ModuleFile
461 # get module override path
462 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
464 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
466 # Check if the source override path exists
467 if not os
.path
.isdir(Module
.SourceOverridePath
):
468 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
470 #Add to GlobalData Variables
471 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
473 # get module private library instance
474 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
475 for Record
in RecordList
:
476 LibraryClass
= Record
[0]
477 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
480 # check the file validation
481 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
483 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
486 if LibraryClass
== '' or LibraryClass
== 'NULL':
487 self
._NullLibraryNumber
+= 1
488 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
489 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
490 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
491 if LibraryPath
not in self
.LibraryInstances
:
492 self
.LibraryInstances
.append(LibraryPath
)
494 # get module private PCD setting
495 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
496 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
497 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
498 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
499 TokenList
= GetSplitValueList(Setting
)
500 DefaultValue
= TokenList
[0]
501 if len(TokenList
) > 1:
502 MaxDatumSize
= TokenList
[1]
505 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
506 Pcd
= PcdClassObject(
518 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
520 # get module private build options
521 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
522 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
523 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
524 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
526 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
527 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
529 self
._Modules
[ModuleFile
] = Module
532 ## Retrieve all possible library instances used in this platform
533 def _GetLibraryInstances(self
):
534 if self
._LibraryInstances
== None:
535 self
._GetLibraryClasses
()
536 return self
._LibraryInstances
538 ## Retrieve [LibraryClasses] information
539 def _GetLibraryClasses(self
):
540 if self
._LibraryClasses
== None:
541 self
._LibraryInstances
= []
543 # tdict is a special dict kind of type, used for selecting correct
544 # library instance for given library class and module type
546 LibraryClassDict
= tdict(True, 3)
547 # track all library class names
548 LibraryClassSet
= set()
549 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
550 Macros
= self
._Macros
551 for Record
in RecordList
:
552 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
553 if LibraryClass
== '' or LibraryClass
== 'NULL':
554 self
._NullLibraryNumber
+= 1
555 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
556 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
557 LibraryClassSet
.add(LibraryClass
)
558 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
559 # check the file validation
560 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
562 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
565 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
566 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
567 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
568 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
569 if LibraryInstance
not in self
._LibraryInstances
:
570 self
._LibraryInstances
.append(LibraryInstance
)
572 # resolve the specific library instance for each class and each module type
573 self
._LibraryClasses
= tdict(True)
574 for LibraryClass
in LibraryClassSet
:
575 # try all possible module types
576 for ModuleType
in SUP_MODULE_LIST
:
577 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
578 if LibraryInstance
== None:
580 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
582 # for Edk style library instances, which are listed in different section
583 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
584 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
585 for Record
in RecordList
:
586 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
588 # check the file validation
589 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
591 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
593 if File
not in self
._LibraryInstances
:
594 self
._LibraryInstances
.append(File
)
596 # we need the module name as the library class name, so we have
597 # to parse it here. (self._Bdb[] will trigger a file parse if it
598 # hasn't been parsed)
600 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
601 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
602 return self
._LibraryClasses
604 ## Retrieve all PCD settings in platform
606 if self
._Pcds
== None:
608 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
609 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
610 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
611 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
612 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
613 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
614 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
615 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
616 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
619 ## Retrieve [BuildOptions]
620 def _GetBuildOptions(self
):
621 if self
._BuildOptions
== None:
622 self
._BuildOptions
= sdict()
624 # Retrieve build option for EDKII style module
626 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
627 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
628 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
630 # Retrieve build option for EDK style module
632 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
633 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
634 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
635 return self
._BuildOptions
637 ## Retrieve non-dynamic PCD settings
639 # @param Type PCD type
641 # @retval a dict object contains settings of given PCD type
643 def _GetPcd(self
, Type
):
646 # tdict is a special dict kind of type, used for selecting correct
647 # PCD settings for certain ARCH
649 PcdDict
= tdict(True, 3)
651 # Find out all possible PCD candidates for self._Arch
652 RecordList
= self
._RawData
[Type
, self
._Arch
]
653 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
654 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
655 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
656 # Remove redundant PCD candidates
657 for PcdCName
, TokenSpaceGuid
in PcdSet
:
658 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
661 PcdValue
, DatumType
, MaxDatumSize
= AnalyzePcdData(Setting
)
662 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
665 self
._PCD
_TYPE
_STRING
_[Type
],
676 ## Retrieve dynamic PCD settings
678 # @param Type PCD type
680 # @retval a dict object contains settings of given PCD type
682 def _GetDynamicPcd(self
, Type
):
685 # tdict is a special dict kind of type, used for selecting correct
686 # PCD settings for certain ARCH and SKU
688 PcdDict
= tdict(True, 4)
690 # Find out all possible PCD candidates for self._Arch
691 RecordList
= self
._RawData
[Type
, self
._Arch
]
692 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
693 PcdList
.append((PcdCName
, TokenSpaceGuid
))
694 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
695 # Remove redundant PCD candidates, per the ARCH and SKU
696 for PcdCName
, TokenSpaceGuid
in PcdList
:
697 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
701 PcdValue
, DatumType
, MaxDatumSize
= AnalyzePcdData(Setting
)
703 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', '', PcdValue
)
704 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
707 self
._PCD
_TYPE
_STRING
_[Type
],
712 {self
.SkuName
: SkuInfo
},
718 ## Retrieve dynamic HII PCD settings
720 # @param Type PCD type
722 # @retval a dict object contains settings of given PCD type
724 def _GetDynamicHiiPcd(self
, Type
):
727 # tdict is a special dict kind of type, used for selecting correct
728 # PCD settings for certain ARCH and SKU
730 PcdDict
= tdict(True, 4)
732 RecordList
= self
._RawData
[Type
, self
._Arch
]
733 # Find out all possible PCD candidates for self._Arch
734 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
735 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
736 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
737 # Remove redundant PCD candidates, per the ARCH and SKU
738 for PcdCName
, TokenSpaceGuid
in PcdSet
:
739 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
742 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= AnalyzeHiiPcdData(Setting
)
743 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
744 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
747 self
._PCD
_TYPE
_STRING
_[Type
],
752 {self
.SkuName
: SkuInfo
},
758 ## Retrieve dynamic VPD PCD settings
760 # @param Type PCD type
762 # @retval a dict object contains settings of given PCD type
764 def _GetDynamicVpdPcd(self
, Type
):
767 # tdict is a special dict kind of type, used for selecting correct
768 # PCD settings for certain ARCH and SKU
770 PcdDict
= tdict(True, 4)
772 # Find out all possible PCD candidates for self._Arch
773 RecordList
= self
._RawData
[Type
, self
._Arch
]
774 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
775 PcdList
.append((PcdCName
, TokenSpaceGuid
))
776 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
777 # Remove redundant PCD candidates, per the ARCH and SKU
778 for PcdCName
, TokenSpaceGuid
in PcdList
:
779 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
783 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
784 # For the Integer & Boolean type, the optional data can only be InitialValue.
785 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
786 # until the DEC parser has been called.
788 VpdOffset
, MaxDatumSize
, InitialValue
= AnalyzeVpdPcdData(Setting
)
790 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
791 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
794 self
._PCD
_TYPE
_STRING
_[Type
],
799 {self
.SkuName
: SkuInfo
},
805 ## Add external modules
807 # The external modules are mostly those listed in FDF file, which don't
810 # @param FilePath The path of module description file
812 def AddModule(self
, FilePath
):
813 FilePath
= NormPath(FilePath
)
814 if FilePath
not in self
.Modules
:
815 Module
= ModuleBuildClassObject()
816 Module
.MetaFile
= FilePath
817 self
.Modules
.append(Module
)
821 # The external PCDs are mostly those listed in FDF file to specify address
822 # or offset information.
824 # @param Name Name of the PCD
825 # @param Guid Token space guid of the PCD
826 # @param Value Value of the PCD
828 def AddPcd(self
, Name
, Guid
, Value
):
829 if (Name
, Guid
) not in self
.Pcds
:
830 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
831 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
833 _Macros
= property(_GetMacros
)
834 Arch
= property(_GetArch
, _SetArch
)
835 Platform
= property(_GetPlatformName
)
836 PlatformName
= property(_GetPlatformName
)
837 Guid
= property(_GetFileGuid
)
838 Version
= property(_GetVersion
)
839 DscSpecification
= property(_GetDscSpec
)
840 OutputDirectory
= property(_GetOutpuDir
)
841 SupArchList
= property(_GetSupArch
)
842 BuildTargets
= property(_GetBuildTarget
)
843 SkuName
= property(_GetSkuName
, _SetSkuName
)
844 FlashDefinition
= property(_GetFdfFile
)
845 BuildNumber
= property(_GetBuildNumber
)
846 MakefileName
= property(_GetMakefileName
)
847 BsBaseAddress
= property(_GetBsBaseAddress
)
848 RtBaseAddress
= property(_GetRtBaseAddress
)
849 LoadFixAddress
= property(_GetLoadFixAddress
)
850 RFCLanguages
= property(_GetRFCLanguages
)
851 ISOLanguages
= property(_GetISOLanguages
)
852 VpdToolGuid
= property(_GetVpdToolGuid
)
853 SkuIds
= property(_GetSkuIds
)
854 Modules
= property(_GetModules
)
855 LibraryInstances
= property(_GetLibraryInstances
)
856 LibraryClasses
= property(_GetLibraryClasses
)
857 Pcds
= property(_GetPcds
)
858 BuildOptions
= property(_GetBuildOptions
)
860 ## Platform build information from DEC file
862 # This class is used to retrieve information stored in database and convert them
863 # into PackageBuildClassObject form for easier use for AutoGen.
865 class DecBuildData(PackageBuildClassObject
):
866 # dict used to convert PCD type in database to string used by build tool
867 _PCD_TYPE_STRING_
= {
868 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
869 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
870 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
871 MODEL_PCD_DYNAMIC
: "Dynamic",
872 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
873 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
874 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
875 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
876 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
877 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
878 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
881 # dict used to convert part of [Defines] to members of DecBuildData directly
886 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
887 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
888 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
889 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
893 ## Constructor of DecBuildData
895 # Initialize object of DecBuildData
897 # @param FilePath The path of package description file
898 # @param RawData The raw data of DEC file
899 # @param BuildDataBase Database used to retrieve module information
900 # @param Arch The target architecture
901 # @param Platform (not used for DecBuildData)
902 # @param Macros Macros used for replacement in DSC file
904 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
906 self
._PackageDir
= File
.Dir
907 self
._RawData
= RawData
908 self
._Bdb
= BuildDataBase
910 self
._Target
= Target
911 self
._Toolchain
= Toolchain
915 def __setitem__(self
, key
, value
):
916 self
.__dict
__[self
._PROPERTY
_[key
]] = value
919 def __getitem__(self
, key
):
920 return self
.__dict
__[self
._PROPERTY
_[key
]]
923 def __contains__(self
, key
):
924 return key
in self
._PROPERTY
_
926 ## Set all internal used members of DecBuildData to None
929 self
._PackageName
= None
932 self
._PkgUniFile
= None
933 self
._Protocols
= None
936 self
._Includes
= None
937 self
._LibraryClasses
= None
941 ## Get current effective macros
942 def _GetMacros(self
):
943 if self
.__Macros
== None:
945 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
954 # Changing the default ARCH to another may affect all other information
955 # because all information in a platform may be ARCH-related. That's
956 # why we need to clear all internal used members, in order to cause all
957 # information to be re-retrieved.
959 # @param Value The value of ARCH
961 def _SetArch(self
, Value
):
962 if self
._Arch
== Value
:
967 ## Retrieve all information in [Defines] section
969 # (Retriving all [Defines] information in one-shot is just to save time.)
971 def _GetHeaderInfo(self
):
972 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
973 for Record
in RecordList
:
976 self
[Name
] = Record
[2]
977 self
._Header
= 'DUMMY'
979 ## Retrieve package name
980 def _GetPackageName(self
):
981 if self
._PackageName
== None:
982 if self
._Header
== None:
983 self
._GetHeaderInfo
()
984 if self
._PackageName
== None:
985 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
986 return self
._PackageName
988 ## Retrieve file guid
989 def _GetFileGuid(self
):
990 if self
._Guid
== None:
991 if self
._Header
== None:
992 self
._GetHeaderInfo
()
993 if self
._Guid
== None:
994 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
997 ## Retrieve package version
998 def _GetVersion(self
):
999 if self
._Version
== None:
1000 if self
._Header
== None:
1001 self
._GetHeaderInfo
()
1002 if self
._Version
== None:
1004 return self
._Version
1006 ## Retrieve protocol definitions (name/value pairs)
1007 def _GetProtocol(self
):
1008 if self
._Protocols
== None:
1010 # tdict is a special kind of dict, used for selecting correct
1011 # protocol defition for given ARCH
1013 ProtocolDict
= tdict(True)
1015 # find out all protocol definitions for specific and 'common' arch
1016 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1017 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1018 if Name
not in NameList
:
1019 NameList
.append(Name
)
1020 ProtocolDict
[Arch
, Name
] = Guid
1021 # use sdict to keep the order
1022 self
._Protocols
= sdict()
1023 for Name
in NameList
:
1025 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1026 # will automatically turn to 'common' ARCH for trying
1028 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1029 return self
._Protocols
1031 ## Retrieve PPI definitions (name/value pairs)
1033 if self
._Ppis
== None:
1035 # tdict is a special kind of dict, used for selecting correct
1036 # PPI defition for given ARCH
1038 PpiDict
= tdict(True)
1040 # find out all PPI definitions for specific arch and 'common' arch
1041 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1042 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1043 if Name
not in NameList
:
1044 NameList
.append(Name
)
1045 PpiDict
[Arch
, Name
] = Guid
1046 # use sdict to keep the order
1047 self
._Ppis
= sdict()
1048 for Name
in NameList
:
1050 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1051 # will automatically turn to 'common' ARCH for trying
1053 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1056 ## Retrieve GUID definitions (name/value pairs)
1058 if self
._Guids
== None:
1060 # tdict is a special kind of dict, used for selecting correct
1061 # GUID defition for given ARCH
1063 GuidDict
= tdict(True)
1065 # find out all protocol definitions for specific and 'common' arch
1066 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1067 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1068 if Name
not in NameList
:
1069 NameList
.append(Name
)
1070 GuidDict
[Arch
, Name
] = Guid
1071 # use sdict to keep the order
1072 self
._Guids
= sdict()
1073 for Name
in NameList
:
1075 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1076 # will automatically turn to 'common' ARCH for trying
1078 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1081 ## Retrieve public include paths declared in this package
1082 def _GetInclude(self
):
1083 if self
._Includes
== None:
1085 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1086 Macros
= self
._Macros
1087 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1088 for Record
in RecordList
:
1089 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1092 ErrorCode
, ErrorInfo
= File
.Validate()
1094 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1096 # avoid duplicate include path
1097 if File
not in self
._Includes
:
1098 self
._Includes
.append(File
)
1099 return self
._Includes
1101 ## Retrieve library class declarations (not used in build at present)
1102 def _GetLibraryClass(self
):
1103 if self
._LibraryClasses
== None:
1105 # tdict is a special kind of dict, used for selecting correct
1106 # library class declaration for given ARCH
1108 LibraryClassDict
= tdict(True)
1109 LibraryClassSet
= set()
1110 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1111 Macros
= self
._Macros
1112 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1113 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1114 # check the file validation
1115 ErrorCode
, ErrorInfo
= File
.Validate()
1117 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1118 LibraryClassSet
.add(LibraryClass
)
1119 LibraryClassDict
[Arch
, LibraryClass
] = File
1120 self
._LibraryClasses
= sdict()
1121 for LibraryClass
in LibraryClassSet
:
1122 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1123 return self
._LibraryClasses
1125 ## Retrieve PCD declarations
1127 if self
._Pcds
== None:
1128 self
._Pcds
= sdict()
1129 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1130 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1131 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1132 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1133 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1136 ## Retrieve PCD declarations for given type
1137 def _GetPcd(self
, Type
):
1140 # tdict is a special kind of dict, used for selecting correct
1141 # PCD declaration for given ARCH
1143 PcdDict
= tdict(True, 3)
1144 # for summarizing PCD
1146 # find out all PCDs of the 'type'
1147 RecordList
= self
._RawData
[Type
, self
._Arch
]
1148 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1149 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1150 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1152 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1154 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1155 # will automatically turn to 'common' ARCH and try again
1157 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1161 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1163 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1166 self
._PCD
_TYPE
_STRING
_[Type
],
1178 _Macros
= property(_GetMacros
)
1179 Arch
= property(_GetArch
, _SetArch
)
1180 PackageName
= property(_GetPackageName
)
1181 Guid
= property(_GetFileGuid
)
1182 Version
= property(_GetVersion
)
1184 Protocols
= property(_GetProtocol
)
1185 Ppis
= property(_GetPpi
)
1186 Guids
= property(_GetGuid
)
1187 Includes
= property(_GetInclude
)
1188 LibraryClasses
= property(_GetLibraryClass
)
1189 Pcds
= property(_GetPcds
)
1191 ## Module build information from INF file
1193 # This class is used to retrieve information stored in database and convert them
1194 # into ModuleBuildClassObject form for easier use for AutoGen.
1196 class InfBuildData(ModuleBuildClassObject
):
1197 # dict used to convert PCD type in database to string used by build tool
1198 _PCD_TYPE_STRING_
= {
1199 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1200 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1201 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1202 MODEL_PCD_DYNAMIC
: "Dynamic",
1203 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1204 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1205 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1206 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1207 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1208 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1209 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1212 # dict used to convert part of [Defines] to members of InfBuildData directly
1217 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1218 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1219 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1223 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1224 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1225 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1226 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1227 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1228 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1229 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1230 TAB_INF_DEFINES_VERSION
: "_Version",
1231 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1232 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1234 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1237 # dict used to convert Component type to Module type
1240 "SECURITY_CORE" : "SEC",
1241 "PEI_CORE" : "PEI_CORE",
1242 "COMBINED_PEIM_DRIVER" : "PEIM",
1243 "PIC_PEIM" : "PEIM",
1244 "RELOCATABLE_PEIM" : "PEIM",
1245 "PE32_PEIM" : "PEIM",
1246 "BS_DRIVER" : "DXE_DRIVER",
1247 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1248 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1249 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1250 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1251 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1252 # "BS_DRIVER" : "UEFI_DRIVER",
1253 "APPLICATION" : "UEFI_APPLICATION",
1257 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1258 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1259 # dict used to convert old tool name used in [nmake] section to new ones
1267 ## Constructor of DscBuildData
1269 # Initialize object of DscBuildData
1271 # @param FilePath The path of platform description file
1272 # @param RawData The raw data of DSC file
1273 # @param BuildDataBase Database used to retrieve module/package information
1274 # @param Arch The target architecture
1275 # @param Platform The name of platform employing this module
1276 # @param Macros Macros used for replacement in DSC file
1278 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1279 self
.MetaFile
= FilePath
1280 self
._ModuleDir
= FilePath
.Dir
1281 self
._RawData
= RawData
1282 self
._Bdb
= BuildDatabase
1284 self
._Target
= Target
1285 self
._Toolchain
= Toolchain
1286 self
._Platform
= 'COMMON'
1287 self
._SourceOverridePath
= None
1288 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1289 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1293 def __setitem__(self
, key
, value
):
1294 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1297 def __getitem__(self
, key
):
1298 return self
.__dict
__[self
._PROPERTY
_[key
]]
1300 ## "in" test support
1301 def __contains__(self
, key
):
1302 return key
in self
._PROPERTY
_
1304 ## Set all internal used members of InfBuildData to None
1306 self
._Header
_ = None
1307 self
._AutoGenVersion
= None
1308 self
._BaseName
= None
1309 self
._DxsFile
= None
1310 self
._ModuleType
= None
1311 self
._ComponentType
= None
1312 self
._BuildType
= None
1314 self
._Version
= None
1315 self
._PcdIsDriver
= None
1316 self
._BinaryModule
= None
1318 self
._MakefileName
= None
1319 self
._CustomMakefile
= None
1320 self
._Specification
= None
1321 self
._LibraryClass
= None
1322 self
._ModuleEntryPointList
= None
1323 self
._ModuleUnloadImageList
= None
1324 self
._ConstructorList
= None
1325 self
._DestructorList
= None
1327 self
._Binaries
= None
1328 self
._Sources
= None
1329 self
._LibraryClasses
= None
1330 self
._Libraries
= None
1331 self
._Protocols
= None
1334 self
._Includes
= None
1335 self
._Packages
= None
1337 self
._BuildOptions
= None
1339 self
._DepexExpression
= None
1340 self
.__Macros
= None
1342 ## Get current effective macros
1343 def _GetMacros(self
):
1344 if self
.__Macros
== None:
1346 # EDK_GLOBAL defined macros can be applied to EDK module
1347 if self
.AutoGenVersion
< 0x00010005:
1348 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1349 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1350 return self
.__Macros
1358 # Changing the default ARCH to another may affect all other information
1359 # because all information in a platform may be ARCH-related. That's
1360 # why we need to clear all internal used members, in order to cause all
1361 # information to be re-retrieved.
1363 # @param Value The value of ARCH
1365 def _SetArch(self
, Value
):
1366 if self
._Arch
== Value
:
1371 ## Return the name of platform employing this module
1372 def _GetPlatform(self
):
1373 return self
._Platform
1375 ## Change the name of platform employing this module
1377 # Changing the default name of platform to another may affect some information
1378 # because they may be PLATFORM-related. That's why we need to clear all internal
1379 # used members, in order to cause all information to be re-retrieved.
1381 def _SetPlatform(self
, Value
):
1382 if self
._Platform
== Value
:
1384 self
._Platform
= Value
1387 ## Retrieve all information in [Defines] section
1389 # (Retriving all [Defines] information in one-shot is just to save time.)
1391 def _GetHeaderInfo(self
):
1392 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1393 for Record
in RecordList
:
1394 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1395 # items defined _PROPERTY_ don't need additional processing
1398 # some special items in [Defines] section need special treatment
1399 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1400 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1401 Name
= 'UEFI_SPECIFICATION_VERSION'
1402 if self
._Specification
== None:
1403 self
._Specification
= sdict()
1404 self
._Specification
[Name
] = GetHexVerValue(Value
)
1405 if self
._Specification
[Name
] == None:
1406 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1407 "'%s' format is not supported for %s" % (Value
, Name
),
1408 File
=self
.MetaFile
, Line
=Record
[-1])
1409 elif Name
== 'LIBRARY_CLASS':
1410 if self
._LibraryClass
== None:
1411 self
._LibraryClass
= []
1412 ValueList
= GetSplitValueList(Value
)
1413 LibraryClass
= ValueList
[0]
1414 if len(ValueList
) > 1:
1415 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1417 SupModuleList
= SUP_MODULE_LIST
1418 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1419 elif Name
== 'ENTRY_POINT':
1420 if self
._ModuleEntryPointList
== None:
1421 self
._ModuleEntryPointList
= []
1422 self
._ModuleEntryPointList
.append(Value
)
1423 elif Name
== 'UNLOAD_IMAGE':
1424 if self
._ModuleUnloadImageList
== None:
1425 self
._ModuleUnloadImageList
= []
1428 self
._ModuleUnloadImageList
.append(Value
)
1429 elif Name
== 'CONSTRUCTOR':
1430 if self
._ConstructorList
== None:
1431 self
._ConstructorList
= []
1434 self
._ConstructorList
.append(Value
)
1435 elif Name
== 'DESTRUCTOR':
1436 if self
._DestructorList
== None:
1437 self
._DestructorList
= []
1440 self
._DestructorList
.append(Value
)
1441 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1442 TokenList
= GetSplitValueList(Value
)
1443 if self
._CustomMakefile
== None:
1444 self
._CustomMakefile
= {}
1445 if len(TokenList
) < 2:
1446 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1447 self
._CustomMakefile
['GCC'] = TokenList
[0]
1449 if TokenList
[0] not in ['MSFT', 'GCC']:
1450 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1451 "No supported family [%s]" % TokenList
[0],
1452 File
=self
.MetaFile
, Line
=Record
[-1])
1453 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1455 if self
._Defs
== None:
1456 self
._Defs
= sdict()
1457 self
._Defs
[Name
] = Value
1460 # Retrieve information in sections specific to Edk.x modules
1462 if self
.AutoGenVersion
>= 0x00010005:
1463 if not self
._ModuleType
:
1464 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1465 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1466 if self
._ModuleType
not in SUP_MODULE_LIST
:
1467 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1468 for Record
in RecordList
:
1470 if Name
== "MODULE_TYPE":
1473 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1474 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1475 File
=self
.MetaFile
, Line
=LineNo
)
1476 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1477 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1478 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
)
1479 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1480 and 'PCI_CLASS_CODE' in self
._Defs
:
1481 self
._BuildType
= 'UEFI_OPTIONROM'
1482 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1483 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1484 self
._BuildType
= 'UEFI_HII'
1486 self
._BuildType
= self
._ModuleType
.upper()
1489 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1490 # check the file validation
1491 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1493 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1494 File
=self
.MetaFile
, Line
=LineNo
)
1495 if self
.Sources
== None:
1497 self
._Sources
.append(File
)
1499 if not self
._ComponentType
:
1500 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1501 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1502 self
._BuildType
= self
._ComponentType
.upper()
1503 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1504 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1505 if self
._ComponentType
== 'LIBRARY':
1506 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1507 # make use some [nmake] section macros
1508 Macros
= self
._Macros
1509 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1510 Macros
['PROCESSOR'] = self
._Arch
1511 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1512 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1513 Value
= ReplaceMacro(Value
, Macros
, True)
1514 if Name
== "IMAGE_ENTRY_POINT":
1515 if self
._ModuleEntryPointList
== None:
1516 self
._ModuleEntryPointList
= []
1517 self
._ModuleEntryPointList
.append(Value
)
1518 elif Name
== "DPX_SOURCE":
1519 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1520 # check the file validation
1521 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1523 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1524 File
=self
.MetaFile
, Line
=LineNo
)
1525 if self
.Sources
== None:
1527 self
._Sources
.append(File
)
1529 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1530 if len(ToolList
) == 0 or len(ToolList
) != 1:
1532 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1533 # File=self.MetaFile, Line=LineNo)
1535 if self
._BuildOptions
== None:
1536 self
._BuildOptions
= sdict()
1538 if ToolList
[0] in self
._TOOL
_CODE
_:
1539 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1542 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1543 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1544 #ignore not replaced macros in value
1545 ValueList
= GetSplitList(' ' + Value
, '/D')
1546 Dummy
= ValueList
[0]
1547 for Index
in range(1, len(ValueList
)):
1548 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1550 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1551 Value
= Dummy
.strip()
1552 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1553 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1555 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1556 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1557 # set _Header to non-None in order to avoid database re-querying
1558 self
._Header
_ = 'DUMMY'
1560 ## Retrieve file version
1561 def _GetInfVersion(self
):
1562 if self
._AutoGenVersion
== None:
1563 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1564 for Record
in RecordList
:
1565 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1566 self
._AutoGenVersion
= int(Record
[2], 0)
1568 if self
._AutoGenVersion
== None:
1569 self
._AutoGenVersion
= 0x00010000
1570 return self
._AutoGenVersion
1572 ## Retrieve BASE_NAME
1573 def _GetBaseName(self
):
1574 if self
._BaseName
== None:
1575 if self
._Header
_ == None:
1576 self
._GetHeaderInfo
()
1577 if self
._BaseName
== None:
1578 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1579 return self
._BaseName
1582 def _GetDxsFile(self
):
1583 if self
._DxsFile
== None:
1584 if self
._Header
_ == None:
1585 self
._GetHeaderInfo
()
1586 if self
._DxsFile
== None:
1588 return self
._DxsFile
1590 ## Retrieve MODULE_TYPE
1591 def _GetModuleType(self
):
1592 if self
._ModuleType
== None:
1593 if self
._Header
_ == None:
1594 self
._GetHeaderInfo
()
1595 if self
._ModuleType
== None:
1596 self
._ModuleType
= 'BASE'
1597 if self
._ModuleType
not in SUP_MODULE_LIST
:
1598 self
._ModuleType
= "USER_DEFINED"
1599 return self
._ModuleType
1601 ## Retrieve COMPONENT_TYPE
1602 def _GetComponentType(self
):
1603 if self
._ComponentType
== None:
1604 if self
._Header
_ == None:
1605 self
._GetHeaderInfo
()
1606 if self
._ComponentType
== None:
1607 self
._ComponentType
= 'USER_DEFINED'
1608 return self
._ComponentType
1610 ## Retrieve "BUILD_TYPE"
1611 def _GetBuildType(self
):
1612 if self
._BuildType
== None:
1613 if self
._Header
_ == None:
1614 self
._GetHeaderInfo
()
1615 if not self
._BuildType
:
1616 self
._BuildType
= "BASE"
1617 return self
._BuildType
1619 ## Retrieve file guid
1620 def _GetFileGuid(self
):
1621 if self
._Guid
== None:
1622 if self
._Header
_ == None:
1623 self
._GetHeaderInfo
()
1624 if self
._Guid
== None:
1625 self
._Guid
= '00000000-0000-0000-000000000000'
1628 ## Retrieve module version
1629 def _GetVersion(self
):
1630 if self
._Version
== None:
1631 if self
._Header
_ == None:
1632 self
._GetHeaderInfo
()
1633 if self
._Version
== None:
1634 self
._Version
= '0.0'
1635 return self
._Version
1637 ## Retrieve PCD_IS_DRIVER
1638 def _GetPcdIsDriver(self
):
1639 if self
._PcdIsDriver
== None:
1640 if self
._Header
_ == None:
1641 self
._GetHeaderInfo
()
1642 if self
._PcdIsDriver
== None:
1643 self
._PcdIsDriver
= ''
1644 return self
._PcdIsDriver
1647 def _GetShadow(self
):
1648 if self
._Shadow
== None:
1649 if self
._Header
_ == None:
1650 self
._GetHeaderInfo
()
1651 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1654 self
._Shadow
= False
1657 ## Retrieve CUSTOM_MAKEFILE
1658 def _GetMakefile(self
):
1659 if self
._CustomMakefile
== None:
1660 if self
._Header
_ == None:
1661 self
._GetHeaderInfo
()
1662 if self
._CustomMakefile
== None:
1663 self
._CustomMakefile
= {}
1664 return self
._CustomMakefile
1666 ## Retrieve EFI_SPECIFICATION_VERSION
1668 if self
._Specification
== None:
1669 if self
._Header
_ == None:
1670 self
._GetHeaderInfo
()
1671 if self
._Specification
== None:
1672 self
._Specification
= {}
1673 return self
._Specification
1675 ## Retrieve LIBRARY_CLASS
1676 def _GetLibraryClass(self
):
1677 if self
._LibraryClass
== None:
1678 if self
._Header
_ == None:
1679 self
._GetHeaderInfo
()
1680 if self
._LibraryClass
== None:
1681 self
._LibraryClass
= []
1682 return self
._LibraryClass
1684 ## Retrieve ENTRY_POINT
1685 def _GetEntryPoint(self
):
1686 if self
._ModuleEntryPointList
== None:
1687 if self
._Header
_ == None:
1688 self
._GetHeaderInfo
()
1689 if self
._ModuleEntryPointList
== None:
1690 self
._ModuleEntryPointList
= []
1691 return self
._ModuleEntryPointList
1693 ## Retrieve UNLOAD_IMAGE
1694 def _GetUnloadImage(self
):
1695 if self
._ModuleUnloadImageList
== None:
1696 if self
._Header
_ == None:
1697 self
._GetHeaderInfo
()
1698 if self
._ModuleUnloadImageList
== None:
1699 self
._ModuleUnloadImageList
= []
1700 return self
._ModuleUnloadImageList
1702 ## Retrieve CONSTRUCTOR
1703 def _GetConstructor(self
):
1704 if self
._ConstructorList
== None:
1705 if self
._Header
_ == None:
1706 self
._GetHeaderInfo
()
1707 if self
._ConstructorList
== None:
1708 self
._ConstructorList
= []
1709 return self
._ConstructorList
1711 ## Retrieve DESTRUCTOR
1712 def _GetDestructor(self
):
1713 if self
._DestructorList
== None:
1714 if self
._Header
_ == None:
1715 self
._GetHeaderInfo
()
1716 if self
._DestructorList
== None:
1717 self
._DestructorList
= []
1718 return self
._DestructorList
1720 ## Retrieve definies other than above ones
1721 def _GetDefines(self
):
1722 if self
._Defs
== None:
1723 if self
._Header
_ == None:
1724 self
._GetHeaderInfo
()
1725 if self
._Defs
== None:
1726 self
._Defs
= sdict()
1729 ## Retrieve binary files
1730 def _GetBinaryFiles(self
):
1731 if self
._Binaries
== None:
1733 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
1734 Macros
= self
._Macros
1735 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1736 Macros
['PROCESSOR'] = self
._Arch
1737 for Record
in RecordList
:
1738 FileType
= Record
[0]
1743 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
1745 Target
= TokenList
[0]
1746 if len(TokenList
) > 1:
1747 FeatureFlag
= Record
[1:]
1749 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
1750 # check the file validation
1751 ErrorCode
, ErrorInfo
= File
.Validate()
1753 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1754 self
._Binaries
.append(File
)
1755 return self
._Binaries
1757 ## Retrieve source files
1758 def _GetSourceFiles(self
):
1759 if self
._Sources
== None:
1761 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
1762 Macros
= self
._Macros
1763 for Record
in RecordList
:
1765 ToolChainFamily
= Record
[1]
1767 ToolCode
= Record
[3]
1768 FeatureFlag
= Record
[4]
1769 if self
.AutoGenVersion
< 0x00010005:
1770 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1771 Macros
['PROCESSOR'] = self
._Arch
1772 # old module source files (Edk)
1773 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
1774 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1775 # check the file validation
1776 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
1778 if File
.Ext
.lower() == '.h':
1779 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
1780 File
=self
.MetaFile
, Line
=LineNo
)
1783 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
1785 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
1786 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1787 # check the file validation
1788 ErrorCode
, ErrorInfo
= File
.Validate()
1790 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1792 self
._Sources
.append(File
)
1793 return self
._Sources
1795 ## Retrieve library classes employed by this module
1796 def _GetLibraryClassUses(self
):
1797 if self
._LibraryClasses
== None:
1798 self
._LibraryClasses
= sdict()
1799 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
1800 for Record
in RecordList
:
1802 Instance
= Record
[1]
1804 Instance
= NormPath(Instance
, self
._Macros
)
1805 self
._LibraryClasses
[Lib
] = Instance
1806 return self
._LibraryClasses
1808 ## Retrieve library names (for Edk.x style of modules)
1809 def _GetLibraryNames(self
):
1810 if self
._Libraries
== None:
1811 self
._Libraries
= []
1812 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
1813 for Record
in RecordList
:
1814 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
1815 # in case of name with '.lib' extension, which is unusual in Edk.x inf
1816 LibraryName
= os
.path
.splitext(LibraryName
)[0]
1817 if LibraryName
not in self
._Libraries
:
1818 self
._Libraries
.append(LibraryName
)
1819 return self
._Libraries
1821 ## Retrieve protocols consumed/produced by this module
1822 def _GetProtocols(self
):
1823 if self
._Protocols
== None:
1824 self
._Protocols
= sdict()
1825 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
1826 for Record
in RecordList
:
1828 Value
= ProtocolValue(CName
, self
.Packages
)
1830 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1831 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1832 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
1833 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1834 self
._Protocols
[CName
] = Value
1835 return self
._Protocols
1837 ## Retrieve PPIs consumed/produced by this module
1839 if self
._Ppis
== None:
1840 self
._Ppis
= sdict()
1841 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
1842 for Record
in RecordList
:
1844 Value
= PpiValue(CName
, self
.Packages
)
1846 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1847 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1848 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
1849 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1850 self
._Ppis
[CName
] = Value
1853 ## Retrieve GUIDs consumed/produced by this module
1854 def _GetGuids(self
):
1855 if self
._Guids
== None:
1856 self
._Guids
= sdict()
1857 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
1858 for Record
in RecordList
:
1860 Value
= GuidValue(CName
, self
.Packages
)
1862 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1863 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1864 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
1865 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1866 self
._Guids
[CName
] = Value
1869 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
1870 def _GetIncludes(self
):
1871 if self
._Includes
== None:
1873 if self
._SourceOverridePath
:
1874 self
._Includes
.append(self
._SourceOverridePath
)
1876 Macros
= self
._Macros
1877 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
1878 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
1880 Macros
['PROCESSOR'] = self
._Arch
1881 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
1882 for Record
in RecordList
:
1883 if Record
[0].find('EDK_SOURCE') > -1:
1884 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
1885 File
= NormPath(Record
[0], self
._Macros
)
1887 File
= os
.path
.join(self
._ModuleDir
, File
)
1889 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1890 File
= RealPath(os
.path
.normpath(File
))
1892 self
._Includes
.append(File
)
1894 #TRICK: let compiler to choose correct header file
1895 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
1896 File
= NormPath(Record
[0], self
._Macros
)
1898 File
= os
.path
.join(self
._ModuleDir
, File
)
1900 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1901 File
= RealPath(os
.path
.normpath(File
))
1903 self
._Includes
.append(File
)
1905 File
= NormPath(Record
[0], Macros
)
1907 File
= os
.path
.join(self
._ModuleDir
, File
)
1909 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1910 File
= RealPath(os
.path
.normpath(File
))
1912 self
._Includes
.append(File
)
1913 return self
._Includes
1915 ## Retrieve packages this module depends on
1916 def _GetPackages(self
):
1917 if self
._Packages
== None:
1919 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
1920 Macros
= self
._Macros
1921 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
1922 for Record
in RecordList
:
1923 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
1925 # check the file validation
1926 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
1928 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1929 # parse this package now. we need it to get protocol/ppi/guid value
1930 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
1931 self
._Packages
.append(Package
)
1932 return self
._Packages
1934 ## Retrieve PCDs used in this module
1936 if self
._Pcds
== None:
1937 self
._Pcds
= sdict()
1938 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1939 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1940 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1941 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1942 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1945 ## Retrieve build options specific to this module
1946 def _GetBuildOptions(self
):
1947 if self
._BuildOptions
== None:
1948 self
._BuildOptions
= sdict()
1949 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
1950 for Record
in RecordList
:
1951 ToolChainFamily
= Record
[0]
1952 ToolChain
= Record
[1]
1954 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1955 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
1957 # concatenate the option string if they're for the same tool
1958 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1959 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
1960 return self
._BuildOptions
1962 ## Retrieve dependency expression
1963 def _GetDepex(self
):
1964 if self
._Depex
== None:
1965 self
._Depex
= tdict(False, 2)
1966 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1968 # If the module has only Binaries and no Sources, then ignore [Depex]
1969 if self
.Sources
== None or self
.Sources
== []:
1970 if self
.Binaries
!= None and self
.Binaries
!= []:
1973 # PEIM and DXE drivers must have a valid [Depex] section
1974 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
1975 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
1976 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
1977 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
1978 % self
.ModuleType
, File
=self
.MetaFile
)
1981 for Record
in RecordList
:
1982 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
1984 ModuleType
= Record
[4]
1985 TokenList
= DepexStr
.split()
1986 if (Arch
, ModuleType
) not in Depex
:
1987 Depex
[Arch
, ModuleType
] = []
1988 DepexList
= Depex
[Arch
, ModuleType
]
1989 for Token
in TokenList
:
1990 if Token
in DEPEX_SUPPORTED_OPCODE
:
1991 DepexList
.append(Token
)
1992 elif Token
.endswith(".inf"): # module file name
1993 ModuleFile
= os
.path
.normpath(Token
)
1994 Module
= self
.BuildDatabase
[ModuleFile
]
1996 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
1997 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
1998 DepexList
.append(Module
.Guid
)
2000 # get the GUID value now
2001 Value
= ProtocolValue(Token
, self
.Packages
)
2003 Value
= PpiValue(Token
, self
.Packages
)
2005 Value
= GuidValue(Token
, self
.Packages
)
2007 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2008 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2009 "Value of [%s] is not found in" % Token
,
2010 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2011 DepexList
.append(Value
)
2012 for Arch
, ModuleType
in Depex
:
2013 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2016 ## Retrieve depedency expression
2017 def _GetDepexExpression(self
):
2018 if self
._DepexExpression
== None:
2019 self
._DepexExpression
= tdict(False, 2)
2020 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2021 DepexExpression
= sdict()
2022 for Record
in RecordList
:
2023 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2025 ModuleType
= Record
[4]
2026 TokenList
= DepexStr
.split()
2027 if (Arch
, ModuleType
) not in DepexExpression
:
2028 DepexExpression
[Arch
, ModuleType
] = ''
2029 for Token
in TokenList
:
2030 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2031 for Arch
, ModuleType
in DepexExpression
:
2032 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2033 return self
._DepexExpression
2035 ## Retrieve PCD for given type
2036 def _GetPcd(self
, Type
):
2038 PcdDict
= tdict(True, 4)
2040 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2041 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Dummy1
, LineNo
in RecordList
:
2042 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2043 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2044 # get the guid value
2045 if TokenSpaceGuid
not in self
.Guids
:
2046 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2048 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2049 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2050 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2051 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2052 self
.Guids
[TokenSpaceGuid
] = Value
2054 # resolve PCD type, value, datum info, etc. by getting its definition from package
2055 for PcdCName
, TokenSpaceGuid
in PcdList
:
2056 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2059 ValueList
= AnalyzePcdData(Setting
)
2060 DefaultValue
= ValueList
[0]
2061 Pcd
= PcdClassObject(
2071 self
.Guids
[TokenSpaceGuid
]
2074 # get necessary info from package declaring this PCD
2075 for Package
in self
.Packages
:
2077 # 'dynamic' in INF means its type is determined by platform;
2078 # if platform doesn't give its type, use 'lowest' one in the
2079 # following order, if any
2081 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2083 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2084 if Type
== MODEL_PCD_DYNAMIC
:
2086 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2087 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2093 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2094 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2096 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2099 # Check whether the token value exist or not.
2101 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2105 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2106 File
=self
.MetaFile
, Line
=LineNo
,
2110 # Check hexadecimal token value length and format.
2112 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2113 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2114 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2118 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2119 File
=self
.MetaFile
, Line
=LineNo
,
2124 # Check decimal token value length and format.
2128 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2129 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2133 "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
)),
2134 File
=self
.MetaFile
, Line
=LineNo
,
2141 "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
)),
2142 File
=self
.MetaFile
, Line
=LineNo
,
2146 Pcd
.DatumType
= PcdInPackage
.DatumType
2147 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2148 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2149 if Pcd
.DefaultValue
in [None, '']:
2150 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2156 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2157 File
=self
.MetaFile
, Line
=LineNo
,
2158 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2160 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2164 _Macros
= property(_GetMacros
)
2165 Arch
= property(_GetArch
, _SetArch
)
2166 Platform
= property(_GetPlatform
, _SetPlatform
)
2168 AutoGenVersion
= property(_GetInfVersion
)
2169 BaseName
= property(_GetBaseName
)
2170 ModuleType
= property(_GetModuleType
)
2171 ComponentType
= property(_GetComponentType
)
2172 BuildType
= property(_GetBuildType
)
2173 Guid
= property(_GetFileGuid
)
2174 Version
= property(_GetVersion
)
2175 PcdIsDriver
= property(_GetPcdIsDriver
)
2176 Shadow
= property(_GetShadow
)
2177 CustomMakefile
= property(_GetMakefile
)
2178 Specification
= property(_GetSpec
)
2179 LibraryClass
= property(_GetLibraryClass
)
2180 ModuleEntryPointList
= property(_GetEntryPoint
)
2181 ModuleUnloadImageList
= property(_GetUnloadImage
)
2182 ConstructorList
= property(_GetConstructor
)
2183 DestructorList
= property(_GetDestructor
)
2184 Defines
= property(_GetDefines
)
2185 DxsFile
= property(_GetDxsFile
)
2187 Binaries
= property(_GetBinaryFiles
)
2188 Sources
= property(_GetSourceFiles
)
2189 LibraryClasses
= property(_GetLibraryClassUses
)
2190 Libraries
= property(_GetLibraryNames
)
2191 Protocols
= property(_GetProtocols
)
2192 Ppis
= property(_GetPpis
)
2193 Guids
= property(_GetGuids
)
2194 Includes
= property(_GetIncludes
)
2195 Packages
= property(_GetPackages
)
2196 Pcds
= property(_GetPcds
)
2197 BuildOptions
= property(_GetBuildOptions
)
2198 Depex
= property(_GetDepex
)
2199 DepexExpression
= property(_GetDepexExpression
)
2203 # This class defined the build database for all modules, packages and platform.
2204 # It will call corresponding parser for the given file if it cannot find it in
2207 # @param DbPath Path of database file
2208 # @param GlobalMacros Global macros used for replacement during file parsing
2209 # @prarm RenewDb=False Create new database file if it's already there
2211 class WorkspaceDatabase(object):
2213 # default database file path
2214 _DB_PATH_
= "Conf/.cache/build.db"
2217 # internal class used for call corresponding file parser and caching the result
2218 # to avoid unnecessary re-parsing
2220 class BuildObjectFactory(object):
2223 ".inf" : MODEL_FILE_INF
,
2224 ".dec" : MODEL_FILE_DEC
,
2225 ".dsc" : MODEL_FILE_DSC
,
2230 MODEL_FILE_INF
: InfParser
,
2231 MODEL_FILE_DEC
: DecParser
,
2232 MODEL_FILE_DSC
: DscParser
,
2235 # convert to xxxBuildData object
2237 MODEL_FILE_INF
: InfBuildData
,
2238 MODEL_FILE_DEC
: DecBuildData
,
2239 MODEL_FILE_DSC
: DscBuildData
,
2242 _CACHE_
= {} # (FilePath, Arch) : <object>
2245 def __init__(self
, WorkspaceDb
):
2246 self
.WorkspaceDb
= WorkspaceDb
2248 # key = (FilePath, Arch=None)
2249 def __contains__(self
, Key
):
2255 return (FilePath
, Arch
) in self
._CACHE
_
2257 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2258 def __getitem__(self
, Key
):
2260 KeyLength
= len(Key
)
2274 # if it's generated before, just return the cached one
2275 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2276 if Key
in self
._CACHE
_:
2277 return self
._CACHE
_[Key
]
2281 if Ext
not in self
._FILE
_TYPE
_:
2283 FileType
= self
._FILE
_TYPE
_[Ext
]
2284 if FileType
not in self
._GENERATOR
_:
2287 # get the parser ready for this file
2288 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2291 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2293 # alwasy do post-process, in case of macros change
2294 MetaFile
.DoPostProcess()
2295 # object the build is based on
2296 BuildObject
= self
._GENERATOR
_[FileType
](
2304 self
._CACHE
_[Key
] = BuildObject
2307 # placeholder for file format conversion
2308 class TransformObjectFactory
:
2309 def __init__(self
, WorkspaceDb
):
2310 self
.WorkspaceDb
= WorkspaceDb
2312 # key = FilePath, Arch
2313 def __getitem__(self
, Key
):
2316 ## Constructor of WorkspaceDatabase
2318 # @param DbPath Path of database file
2319 # @param GlobalMacros Global macros used for replacement during file parsing
2320 # @prarm RenewDb=False Create new database file if it's already there
2322 def __init__(self
, DbPath
, RenewDb
=False):
2323 self
._DbClosedFlag
= False
2325 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2327 # don't create necessary path for db in memory
2328 if DbPath
!= ':memory:':
2329 DbDir
= os
.path
.split(DbPath
)[0]
2330 if not os
.path
.exists(DbDir
):
2333 # remove db file in case inconsistency between db and file in file system
2334 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2337 # create db with optimized parameters
2338 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2339 self
.Conn
.execute("PRAGMA synchronous=OFF")
2340 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2341 self
.Conn
.execute("PRAGMA count_changes=OFF")
2342 self
.Conn
.execute("PRAGMA cache_size=8192")
2343 #self.Conn.execute("PRAGMA page_size=8192")
2345 # to avoid non-ascii character conversion issue
2346 self
.Conn
.text_factory
= str
2347 self
.Cur
= self
.Conn
.cursor()
2349 # create table for internal uses
2350 self
.TblDataModel
= TableDataModel(self
.Cur
)
2351 self
.TblFile
= TableFile(self
.Cur
)
2352 self
.Platform
= None
2354 # conversion object for build or file format conversion purpose
2355 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2356 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2358 ## Check whether workspace database need to be renew.
2359 # The renew reason maybe:
2360 # 1) If user force to renew;
2361 # 2) If user do not force renew, and
2362 # a) If the time of last modified python source is newer than database file;
2363 # b) If the time of last modified frozen executable file is newer than database file;
2365 # @param force User force renew database
2366 # @param DbPath The absolute path of workspace database file
2368 # @return Bool value for whether need renew workspace databse
2370 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2371 # if database does not exist, we need do nothing
2372 if not os
.path
.exists(DbPath
): return False
2374 # if user force to renew database, then not check whether database is out of date
2375 if force
: return True
2378 # Check the time of last modified source file or build.exe
2379 # if is newer than time of database, then database need to be re-created.
2381 timeOfToolModified
= 0
2382 if hasattr(sys
, "frozen"):
2383 exePath
= os
.path
.abspath(sys
.executable
)
2384 timeOfToolModified
= os
.stat(exePath
).st_mtime
2386 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2387 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2388 if rootPath
== "" or rootPath
== None:
2389 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2390 determine whether database file is out of date!\n")
2392 # walk the root path of source or build's binary to get the time last modified.
2394 for root
, dirs
, files
in os
.walk (rootPath
):
2396 # bypass source control folder
2397 if dir.lower() in [".svn", "_svn", "cvs"]:
2401 ext
= os
.path
.splitext(file)[1]
2402 if ext
.lower() == ".py": # only check .py files
2403 fd
= os
.stat(os
.path
.join(root
, file))
2404 if timeOfToolModified
< fd
.st_mtime
:
2405 timeOfToolModified
= fd
.st_mtime
2406 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2407 EdkLogger
.verbose("\nWorkspace database is out of data!")
2412 ## Initialize build database
2413 def InitDatabase(self
):
2414 EdkLogger
.verbose("\nInitialize build database started ...")
2419 self
.TblDataModel
.Create(False)
2420 self
.TblFile
.Create(False)
2423 # Initialize table DataModel
2425 self
.TblDataModel
.InitTable()
2426 EdkLogger
.verbose("Initialize build database ... DONE!")
2430 # @param Table: The instance of the table to be queried
2432 def QueryTable(self
, Table
):
2438 ## Close entire database
2441 # Close the connection and cursor
2444 if not self
._DbClosedFlag
:
2448 self
._DbClosedFlag
= True
2450 ## Summarize all packages in the database
2451 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2452 self
.Platform
= Platform
2454 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2456 # Get Package related to Modules
2458 for Module
in Pa
.Modules
:
2459 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2460 for Package
in ModuleObj
.Packages
:
2461 if Package
not in PackageList
:
2462 PackageList
.append(Package
)
2464 # Get Packages related to Libraries
2466 for Lib
in Pa
.LibraryInstances
:
2467 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2468 for Package
in LibObj
.Packages
:
2469 if Package
not in PackageList
:
2470 PackageList
.append(Package
)
2474 ## Summarize all platforms in the database
2475 def _GetPlatformList(self
):
2477 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2479 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2482 if Platform
!= None:
2483 PlatformList
.append(Platform
)
2486 PlatformList
= property(_GetPlatformList
)
2490 # This acts like the main() function for the script, unless it is 'import'ed into another
2493 if __name__
== '__main__':