2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2014, 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.
18 import Common
.LongFilePathOs
as os
22 import Common
.EdkLogger
as EdkLogger
23 import Common
.GlobalData
as GlobalData
25 from Common
.String
import *
26 from Common
.DataType
import *
27 from Common
.Misc
import *
30 from CommonDataClass
.CommonClass
import SkuInfoClass
32 from MetaDataTable
import *
33 from MetaFileTable
import *
34 from MetaFileParser
import *
35 from BuildClassObject
import *
36 from WorkspaceCommon
import GetDeclaredPcd
37 from Common
.Misc
import AnalyzeDscPcd
38 from Common
.Misc
import ProcessDuplicatedInf
40 from Common
.Parsing
import IsValidWord
42 import Common
.GlobalData
as GlobalData
44 ## Platform build information from DSC file
46 # This class is used to retrieve information stored in database and convert them
47 # into PlatformBuildClassObject form for easier use for AutoGen.
49 class DscBuildData(PlatformBuildClassObject
):
50 # dict used to convert PCD type in database to string used by build tool
52 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
53 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
54 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
55 MODEL_PCD_DYNAMIC
: "Dynamic",
56 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
57 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
58 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
59 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
60 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
61 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
62 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
65 # dict used to convert part of [Defines] to members of DscBuildData directly
70 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
71 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
72 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
73 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
74 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
75 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
76 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
77 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
78 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
79 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
80 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
81 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
82 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
83 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
84 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
87 # used to compose dummy library class name for those forced library instances
88 _NullLibraryNumber
= 0
90 ## Constructor of DscBuildData
92 # Initialize object of DscBuildData
94 # @param FilePath The path of platform description file
95 # @param RawData The raw data of DSC file
96 # @param BuildDataBase Database used to retrieve module/package information
97 # @param Arch The target architecture
98 # @param Platform (not used for DscBuildData)
99 # @param Macros Macros used for replacement in DSC file
101 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
102 self
.MetaFile
= FilePath
103 self
._RawData
= RawData
104 self
._Bdb
= BuildDataBase
106 self
._Target
= Target
107 self
._Toolchain
= Toolchain
109 self
._HandleOverridePath
()
112 def __setitem__(self
, key
, value
):
113 self
.__dict
__[self
._PROPERTY
_[key
]] = value
116 def __getitem__(self
, key
):
117 return self
.__dict
__[self
._PROPERTY
_[key
]]
120 def __contains__(self
, key
):
121 return key
in self
._PROPERTY
_
123 ## Set all internal used members of DscBuildData to None
126 self
._PlatformName
= None
129 self
._DscSpecification
= None
130 self
._OutputDirectory
= None
131 self
._SupArchList
= None
132 self
._BuildTargets
= None
134 self
._SkuIdentifier
= None
135 self
._PcdInfoFlag
= None
136 self
._FlashDefinition
= None
137 self
._BuildNumber
= None
138 self
._MakefileName
= None
139 self
._BsBaseAddress
= None
140 self
._RtBaseAddress
= None
143 self
._LibraryInstances
= None
144 self
._LibraryClasses
= None
147 self
._BuildOptions
= None
148 self
._LoadFixAddress
= None
149 self
._RFCLanguages
= None
150 self
._ISOLanguages
= None
151 self
._VpdToolGuid
= None
155 ## handle Override Path of Module
156 def _HandleOverridePath(self
):
157 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
158 Macros
= self
._Macros
159 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
160 for Record
in RecordList
:
163 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
164 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
166 SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
168 # Check if the source override path exists
169 if not os
.path
.isdir(SourceOverridePath
):
170 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
172 #Add to GlobalData Variables
173 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
175 ## Get current effective macros
176 def _GetMacros(self
):
177 if self
.__Macros
== None:
179 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
180 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
181 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
190 # Changing the default ARCH to another may affect all other information
191 # because all information in a platform may be ARCH-related. That's
192 # why we need to clear all internal used members, in order to cause all
193 # information to be re-retrieved.
195 # @param Value The value of ARCH
197 def _SetArch(self
, Value
):
198 if self
._Arch
== Value
:
203 ## Retrieve all information in [Defines] section
205 # (Retriving all [Defines] information in one-shot is just to save time.)
207 def _GetHeaderInfo(self
):
208 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
209 for Record
in RecordList
:
211 # items defined _PROPERTY_ don't need additional processing
213 # some special items in [Defines] section need special treatment
214 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
215 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
216 if ' ' in self
._OutputDirectory
:
217 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
218 File
=self
.MetaFile
, Line
=Record
[-1],
219 ExtraData
=self
._OutputDirectory
)
220 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
221 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
222 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
224 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
226 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
227 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
228 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
229 self
._BuildTargets
= GetSplitValueList(Record
[2])
230 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
231 if self
._SkuName
== None:
232 self
._SkuName
= Record
[2]
233 self
._SkuIdentifier
= Record
[2]
234 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
235 self
._PcdInfoFlag
= Record
[2]
236 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
238 self
._LoadFixAddress
= int (Record
[2], 0)
240 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
241 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
242 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
243 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"',
244 File
=self
.MetaFile
, Line
=Record
[-1])
245 LanguageCodes
= Record
[2][1:-1]
246 if not LanguageCodes
:
247 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
248 File
=self
.MetaFile
, Line
=Record
[-1])
249 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
250 # check whether there is empty entries in the list
251 if None in LanguageList
:
252 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
253 File
=self
.MetaFile
, Line
=Record
[-1])
254 self
._RFCLanguages
= LanguageList
255 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
256 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
257 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
258 File
=self
.MetaFile
, Line
=Record
[-1])
259 LanguageCodes
= Record
[2][1:-1]
260 if not LanguageCodes
:
261 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
262 File
=self
.MetaFile
, Line
=Record
[-1])
263 if len(LanguageCodes
)%3:
264 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
265 File
=self
.MetaFile
, Line
=Record
[-1])
267 for i
in range(0, len(LanguageCodes
), 3):
268 LanguageList
.append(LanguageCodes
[i
:i
+3])
269 self
._ISOLanguages
= LanguageList
270 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
272 # try to convert GUID to a real UUID value to see whether the GUID is format
273 # for VPD_TOOL_GUID is correct.
278 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
279 self
._VpdToolGuid
= Record
[2]
281 self
[Name
] = Record
[2]
282 # set _Header to non-None in order to avoid database re-querying
283 self
._Header
= 'DUMMY'
285 ## Retrieve platform name
286 def _GetPlatformName(self
):
287 if self
._PlatformName
== None:
288 if self
._Header
== None:
289 self
._GetHeaderInfo
()
290 if self
._PlatformName
== None:
291 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
292 return self
._PlatformName
294 ## Retrieve file guid
295 def _GetFileGuid(self
):
296 if self
._Guid
== None:
297 if self
._Header
== None:
298 self
._GetHeaderInfo
()
299 if self
._Guid
== None:
300 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
303 ## Retrieve platform version
304 def _GetVersion(self
):
305 if self
._Version
== None:
306 if self
._Header
== None:
307 self
._GetHeaderInfo
()
308 if self
._Version
== None:
309 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
312 ## Retrieve platform description file version
313 def _GetDscSpec(self
):
314 if self
._DscSpecification
== None:
315 if self
._Header
== None:
316 self
._GetHeaderInfo
()
317 if self
._DscSpecification
== None:
318 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
319 return self
._DscSpecification
321 ## Retrieve OUTPUT_DIRECTORY
322 def _GetOutpuDir(self
):
323 if self
._OutputDirectory
== None:
324 if self
._Header
== None:
325 self
._GetHeaderInfo
()
326 if self
._OutputDirectory
== None:
327 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
328 return self
._OutputDirectory
330 ## Retrieve SUPPORTED_ARCHITECTURES
331 def _GetSupArch(self
):
332 if self
._SupArchList
== None:
333 if self
._Header
== None:
334 self
._GetHeaderInfo
()
335 if self
._SupArchList
== None:
336 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
337 return self
._SupArchList
339 ## Retrieve BUILD_TARGETS
340 def _GetBuildTarget(self
):
341 if self
._BuildTargets
== None:
342 if self
._Header
== None:
343 self
._GetHeaderInfo
()
344 if self
._BuildTargets
== None:
345 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
346 return self
._BuildTargets
348 def _GetPcdInfoFlag(self
):
349 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
351 elif self
._PcdInfoFlag
.upper() == 'TRUE':
356 def _GetSkuIdentifier(self
):
359 if self
._SkuIdentifier
== None:
360 if self
._Header
== None:
361 self
._GetHeaderInfo
()
362 return self
._SkuIdentifier
363 ## Retrieve SKUID_IDENTIFIER
364 def _GetSkuName(self
):
365 if self
._SkuName
== None:
366 if self
._Header
== None:
367 self
._GetHeaderInfo
()
368 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
369 self
._SkuName
= 'DEFAULT'
372 ## Override SKUID_IDENTIFIER
373 def _SetSkuName(self
, Value
):
374 self
._SkuName
= Value
377 def _GetFdfFile(self
):
378 if self
._FlashDefinition
== None:
379 if self
._Header
== None:
380 self
._GetHeaderInfo
()
381 if self
._FlashDefinition
== None:
382 self
._FlashDefinition
= ''
383 return self
._FlashDefinition
385 ## Retrieve FLASH_DEFINITION
386 def _GetBuildNumber(self
):
387 if self
._BuildNumber
== None:
388 if self
._Header
== None:
389 self
._GetHeaderInfo
()
390 if self
._BuildNumber
== None:
391 self
._BuildNumber
= ''
392 return self
._BuildNumber
394 ## Retrieve MAKEFILE_NAME
395 def _GetMakefileName(self
):
396 if self
._MakefileName
== None:
397 if self
._Header
== None:
398 self
._GetHeaderInfo
()
399 if self
._MakefileName
== None:
400 self
._MakefileName
= ''
401 return self
._MakefileName
403 ## Retrieve BsBaseAddress
404 def _GetBsBaseAddress(self
):
405 if self
._BsBaseAddress
== None:
406 if self
._Header
== None:
407 self
._GetHeaderInfo
()
408 if self
._BsBaseAddress
== None:
409 self
._BsBaseAddress
= ''
410 return self
._BsBaseAddress
412 ## Retrieve RtBaseAddress
413 def _GetRtBaseAddress(self
):
414 if self
._RtBaseAddress
== None:
415 if self
._Header
== None:
416 self
._GetHeaderInfo
()
417 if self
._RtBaseAddress
== None:
418 self
._RtBaseAddress
= ''
419 return self
._RtBaseAddress
421 ## Retrieve the top address for the load fix address
422 def _GetLoadFixAddress(self
):
423 if self
._LoadFixAddress
== None:
424 if self
._Header
== None:
425 self
._GetHeaderInfo
()
427 if self
._LoadFixAddress
== None:
428 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
431 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
433 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
436 # If command line defined, should override the value in DSC file.
438 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
440 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
442 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']))
444 if self
._LoadFixAddress
< 0:
445 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
446 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
447 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
449 return self
._LoadFixAddress
451 ## Retrieve RFCLanguage filter
452 def _GetRFCLanguages(self
):
453 if self
._RFCLanguages
== None:
454 if self
._Header
== None:
455 self
._GetHeaderInfo
()
456 if self
._RFCLanguages
== None:
457 self
._RFCLanguages
= []
458 return self
._RFCLanguages
460 ## Retrieve ISOLanguage filter
461 def _GetISOLanguages(self
):
462 if self
._ISOLanguages
== None:
463 if self
._Header
== None:
464 self
._GetHeaderInfo
()
465 if self
._ISOLanguages
== None:
466 self
._ISOLanguages
= []
467 return self
._ISOLanguages
468 ## Retrieve the GUID string for VPD tool
469 def _GetVpdToolGuid(self
):
470 if self
._VpdToolGuid
== None:
471 if self
._Header
== None:
472 self
._GetHeaderInfo
()
473 if self
._VpdToolGuid
== None:
474 self
._VpdToolGuid
= ''
475 return self
._VpdToolGuid
477 ## Retrieve [SkuIds] section information
478 def _GetSkuIds(self
):
479 if self
._SkuIds
== None:
480 self
._SkuIds
= sdict()
481 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
482 for Record
in RecordList
:
483 if Record
[0] in [None, '']:
484 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
485 File
=self
.MetaFile
, Line
=Record
[-1])
486 if Record
[1] in [None, '']:
487 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
488 File
=self
.MetaFile
, Line
=Record
[-1])
489 self
._SkuIds
[Record
[1]] = Record
[0]
490 if 'DEFAULT' not in self
._SkuIds
:
491 self
._SkuIds
['DEFAULT'] = '0'
492 if 'COMMON' not in self
._SkuIds
:
493 self
._SkuIds
['COMMON'] = '0'
496 ## Retrieve [Components] section information
497 def _GetModules(self
):
498 if self
._Modules
!= None:
501 self
._Modules
= sdict()
502 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
503 Macros
= self
._Macros
504 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
505 for Record
in RecordList
:
506 DuplicatedFile
= False
507 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
511 # check the file validation
512 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
514 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
517 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
518 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
519 DuplicatedFile
= True
521 Module
= ModuleBuildClassObject()
522 Module
.MetaFile
= ModuleFile
524 # get module private library instance
525 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
526 for Record
in RecordList
:
527 LibraryClass
= Record
[0]
528 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
531 # check the file validation
532 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
534 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
537 if LibraryClass
== '' or LibraryClass
== 'NULL':
538 self
._NullLibraryNumber
+= 1
539 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
540 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
541 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
542 if LibraryPath
not in self
.LibraryInstances
:
543 self
.LibraryInstances
.append(LibraryPath
)
545 # get module private PCD setting
546 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
547 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
548 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
549 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
550 TokenList
= GetSplitValueList(Setting
)
551 DefaultValue
= TokenList
[0]
552 if len(TokenList
) > 1:
553 MaxDatumSize
= TokenList
[1]
556 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
557 Pcd
= PcdClassObject(
569 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
571 # get module private build options
572 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
573 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
574 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
575 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
577 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
578 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
580 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
581 if DuplicatedFile
and not RecordList
:
582 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
584 if len(RecordList
) != 1:
585 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
586 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
587 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
588 ModuleFile
.Arch
= self
._Arch
590 self
._Modules
[ModuleFile
] = Module
593 ## Retrieve all possible library instances used in this platform
594 def _GetLibraryInstances(self
):
595 if self
._LibraryInstances
== None:
596 self
._GetLibraryClasses
()
597 return self
._LibraryInstances
599 ## Retrieve [LibraryClasses] information
600 def _GetLibraryClasses(self
):
601 if self
._LibraryClasses
== None:
602 self
._LibraryInstances
= []
604 # tdict is a special dict kind of type, used for selecting correct
605 # library instance for given library class and module type
607 LibraryClassDict
= tdict(True, 3)
608 # track all library class names
609 LibraryClassSet
= set()
610 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
611 Macros
= self
._Macros
612 for Record
in RecordList
:
613 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
614 if LibraryClass
== '' or LibraryClass
== 'NULL':
615 self
._NullLibraryNumber
+= 1
616 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
617 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
618 LibraryClassSet
.add(LibraryClass
)
619 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
620 # check the file validation
621 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
623 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
626 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
627 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
628 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
629 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
630 if LibraryInstance
not in self
._LibraryInstances
:
631 self
._LibraryInstances
.append(LibraryInstance
)
633 # resolve the specific library instance for each class and each module type
634 self
._LibraryClasses
= tdict(True)
635 for LibraryClass
in LibraryClassSet
:
636 # try all possible module types
637 for ModuleType
in SUP_MODULE_LIST
:
638 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
639 if LibraryInstance
== None:
641 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
643 # for Edk style library instances, which are listed in different section
644 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
645 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
646 for Record
in RecordList
:
647 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
649 # check the file validation
650 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
652 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
654 if File
not in self
._LibraryInstances
:
655 self
._LibraryInstances
.append(File
)
657 # we need the module name as the library class name, so we have
658 # to parse it here. (self._Bdb[] will trigger a file parse if it
659 # hasn't been parsed)
661 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
662 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
663 return self
._LibraryClasses
665 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
666 if self
._DecPcds
== None:
667 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
669 if GlobalData
.gFdfParser
:
670 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
673 for Inf
in FdfInfList
:
674 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
675 if ModuleFile
in self
._Modules
:
677 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
678 PkgSet
.update(ModuleData
.Packages
)
682 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
683 self
._DecPcds
.update(DecPcds
)
685 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
686 EdkLogger
.error('build', PARSER_ERROR
,
687 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
688 File
=self
.MetaFile
, Line
=LineNo
)
689 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
690 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
691 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
692 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
693 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
695 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
696 except WrnExpression
, Value
:
697 ValueList
[Index
] = Value
.result
698 except EvaluationException
, Excpt
:
699 if hasattr(Excpt
, 'Pcd'):
700 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
701 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
702 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
703 " of the DSC file" % Excpt
.Pcd
,
704 File
=self
.MetaFile
, Line
=LineNo
)
706 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
707 File
=self
.MetaFile
, Line
=LineNo
)
709 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
710 File
=self
.MetaFile
, Line
=LineNo
)
711 if ValueList
[Index
] == 'True':
712 ValueList
[Index
] = '1'
713 elif ValueList
[Index
] == 'False':
714 ValueList
[Index
] = '0'
716 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
718 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
719 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
722 ## Retrieve all PCD settings in platform
724 if self
._Pcds
== None:
726 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
727 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
728 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
729 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
730 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
731 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
732 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
733 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
734 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
737 ## Retrieve [BuildOptions]
738 def _GetBuildOptions(self
):
739 if self
._BuildOptions
== None:
740 self
._BuildOptions
= sdict()
742 # Retrieve build option for EDKII style module
744 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
745 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
746 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
748 # Retrieve build option for EDK style module
750 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
751 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
752 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
753 return self
._BuildOptions
755 ## Retrieve non-dynamic PCD settings
757 # @param Type PCD type
759 # @retval a dict object contains settings of given PCD type
761 def _GetPcd(self
, Type
):
764 # tdict is a special dict kind of type, used for selecting correct
765 # PCD settings for certain ARCH
768 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
770 PcdDict
= tdict(True, 3)
772 # Find out all possible PCD candidates for self._Arch
773 RecordList
= self
._RawData
[Type
, self
._Arch
]
774 PcdValueDict
= sdict()
775 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
776 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
777 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
778 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
780 #handle pcd value override
781 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
782 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
785 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
786 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
787 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
789 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
791 PcdsKeys
= PcdValueDict
.keys()
792 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
794 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
798 if 'COMMON' in PcdSetting
:
799 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
800 if 'DEFAULT' in PcdSetting
:
801 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
802 if SkuObj
.SystemSkuId
in PcdSetting
:
803 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
805 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
808 self
._PCD
_TYPE
_STRING
_[Type
],
819 ## Retrieve dynamic PCD settings
821 # @param Type PCD type
823 # @retval a dict object contains settings of given PCD type
825 def _GetDynamicPcd(self
, Type
):
827 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
831 # tdict is a special dict kind of type, used for selecting correct
832 # PCD settings for certain ARCH and SKU
834 PcdDict
= tdict(True, 4)
836 # Find out all possible PCD candidates for self._Arch
837 RecordList
= self
._RawData
[Type
, self
._Arch
]
838 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
840 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
841 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
842 if SkuName
not in AvailableSkuIdSet
:
845 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
846 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
847 # Remove redundant PCD candidates, per the ARCH and SKU
848 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
850 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
854 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
855 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
856 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
857 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
858 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
859 if MaxDatumSize
.strip():
860 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
863 if pcdObject
.MaxDatumSize
:
864 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
867 if CurrentMaxSize
> PcdMaxSize
:
868 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
870 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
873 self
._PCD
_TYPE
_STRING
_[Type
],
883 for pcd
in Pcds
.values():
884 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
885 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
886 valuefromDec
= pcdDecObject
.DefaultValue
887 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
888 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
889 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
890 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
891 del(pcd
.SkuInfoList
['COMMON'])
892 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
893 del(pcd
.SkuInfoList
['COMMON'])
894 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
895 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
896 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
897 del(pcd
.SkuInfoList
['DEFAULT'])
901 ## Retrieve dynamic HII PCD settings
903 # @param Type PCD type
905 # @retval a dict object contains settings of given PCD type
907 def _GetDynamicHiiPcd(self
, Type
):
909 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
913 # tdict is a special dict kind of type, used for selecting correct
914 # PCD settings for certain ARCH and SKU
916 PcdDict
= tdict(True, 4)
918 RecordList
= self
._RawData
[Type
, self
._Arch
]
919 # Find out all possible PCD candidates for self._Arch
920 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
922 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
923 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
924 if SkuName
not in AvailableSkuIdSet
:
926 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
927 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
928 # Remove redundant PCD candidates, per the ARCH and SKU
929 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
931 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
934 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
938 if VariableOffset
.isdigit():
939 if int(VariableOffset
,10) > 0xFFFF:
941 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
942 if int(VariableOffset
,16) > 0xFFFF:
944 # For Offset written in "A.B"
945 elif VariableOffset
.find('.') > -1:
946 VariableOffsetList
= VariableOffset
.split(".")
947 if not (len(VariableOffsetList
) == 2
948 and IsValidWord(VariableOffsetList
[0])
949 and IsValidWord(VariableOffsetList
[1])):
950 FormatCorrect
= False
952 FormatCorrect
= False
953 if not FormatCorrect
:
954 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
957 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
959 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
960 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
961 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
962 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
964 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
967 self
._PCD
_TYPE
_STRING
_[Type
],
978 for pcd
in Pcds
.values():
979 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
980 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
981 # Only fix the value while no value provided in DSC file.
982 for sku
in pcd
.SkuInfoList
.values():
983 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
984 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
985 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
986 valuefromDec
= pcdDecObject
.DefaultValue
987 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
988 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
989 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
990 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
991 del(pcd
.SkuInfoList
['COMMON'])
992 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
993 del(pcd
.SkuInfoList
['COMMON'])
995 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
996 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
997 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
998 del(pcd
.SkuInfoList
['DEFAULT'])
1001 if pcd
.MaxDatumSize
.strip():
1002 MaxSize
= int(pcd
.MaxDatumSize
,0)
1005 if pcdDecObject
.DatumType
== 'VOID*':
1006 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1008 if skuobj
.HiiDefaultValue
.startswith("L"):
1009 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
1010 elif skuobj
.HiiDefaultValue
.startswith("{"):
1011 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1013 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
1016 pcd
.MaxDatumSize
= str(MaxSize
)
1019 ## Retrieve dynamic VPD PCD settings
1021 # @param Type PCD type
1023 # @retval a dict object contains settings of given PCD type
1025 def _GetDynamicVpdPcd(self
, Type
):
1027 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
1031 # tdict is a special dict kind of type, used for selecting correct
1032 # PCD settings for certain ARCH and SKU
1034 PcdDict
= tdict(True, 4)
1036 # Find out all possible PCD candidates for self._Arch
1037 RecordList
= self
._RawData
[Type
, self
._Arch
]
1038 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1040 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1041 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1042 if SkuName
not in AvailableSkuIdSet
:
1045 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1046 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1047 # Remove redundant PCD candidates, per the ARCH and SKU
1048 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1049 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1053 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1054 # For the Integer & Boolean type, the optional data can only be InitialValue.
1055 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1056 # until the DEC parser has been called.
1058 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1059 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1060 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1061 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1062 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1063 if MaxDatumSize
.strip():
1064 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1067 if pcdObject
.MaxDatumSize
:
1068 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1071 if CurrentMaxSize
> PcdMaxSize
:
1072 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1074 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1077 self
._PCD
_TYPE
_STRING
_[Type
],
1082 {SkuName
: SkuInfo
},
1086 for pcd
in Pcds
.values():
1087 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1088 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1089 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1090 valuefromDec
= pcdDecObject
.DefaultValue
1091 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1092 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1093 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1094 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1095 del(pcd
.SkuInfoList
['COMMON'])
1096 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1097 del(pcd
.SkuInfoList
['COMMON'])
1098 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1099 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1100 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1101 del(pcd
.SkuInfoList
['DEFAULT'])
1105 ## Add external modules
1107 # The external modules are mostly those listed in FDF file, which don't
1110 # @param FilePath The path of module description file
1112 def AddModule(self
, FilePath
):
1113 FilePath
= NormPath(FilePath
)
1114 if FilePath
not in self
.Modules
:
1115 Module
= ModuleBuildClassObject()
1116 Module
.MetaFile
= FilePath
1117 self
.Modules
.append(Module
)
1119 ## Add external PCDs
1121 # The external PCDs are mostly those listed in FDF file to specify address
1122 # or offset information.
1124 # @param Name Name of the PCD
1125 # @param Guid Token space guid of the PCD
1126 # @param Value Value of the PCD
1128 def AddPcd(self
, Name
, Guid
, Value
):
1129 if (Name
, Guid
) not in self
.Pcds
:
1130 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1131 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1133 _Macros
= property(_GetMacros
)
1134 Arch
= property(_GetArch
, _SetArch
)
1135 Platform
= property(_GetPlatformName
)
1136 PlatformName
= property(_GetPlatformName
)
1137 Guid
= property(_GetFileGuid
)
1138 Version
= property(_GetVersion
)
1139 DscSpecification
= property(_GetDscSpec
)
1140 OutputDirectory
= property(_GetOutpuDir
)
1141 SupArchList
= property(_GetSupArch
)
1142 BuildTargets
= property(_GetBuildTarget
)
1143 SkuName
= property(_GetSkuName
, _SetSkuName
)
1144 SkuIdentifier
= property(_GetSkuIdentifier
)
1145 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1146 FlashDefinition
= property(_GetFdfFile
)
1147 BuildNumber
= property(_GetBuildNumber
)
1148 MakefileName
= property(_GetMakefileName
)
1149 BsBaseAddress
= property(_GetBsBaseAddress
)
1150 RtBaseAddress
= property(_GetRtBaseAddress
)
1151 LoadFixAddress
= property(_GetLoadFixAddress
)
1152 RFCLanguages
= property(_GetRFCLanguages
)
1153 ISOLanguages
= property(_GetISOLanguages
)
1154 VpdToolGuid
= property(_GetVpdToolGuid
)
1155 SkuIds
= property(_GetSkuIds
)
1156 Modules
= property(_GetModules
)
1157 LibraryInstances
= property(_GetLibraryInstances
)
1158 LibraryClasses
= property(_GetLibraryClasses
)
1159 Pcds
= property(_GetPcds
)
1160 BuildOptions
= property(_GetBuildOptions
)
1162 ## Platform build information from DEC file
1164 # This class is used to retrieve information stored in database and convert them
1165 # into PackageBuildClassObject form for easier use for AutoGen.
1167 class DecBuildData(PackageBuildClassObject
):
1168 # dict used to convert PCD type in database to string used by build tool
1169 _PCD_TYPE_STRING_
= {
1170 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1171 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1172 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1173 MODEL_PCD_DYNAMIC
: "Dynamic",
1174 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1175 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1176 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1177 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1178 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1179 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1180 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1183 # dict used to convert part of [Defines] to members of DecBuildData directly
1188 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1189 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1190 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1191 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1195 ## Constructor of DecBuildData
1197 # Initialize object of DecBuildData
1199 # @param FilePath The path of package description file
1200 # @param RawData The raw data of DEC file
1201 # @param BuildDataBase Database used to retrieve module information
1202 # @param Arch The target architecture
1203 # @param Platform (not used for DecBuildData)
1204 # @param Macros Macros used for replacement in DSC file
1206 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1207 self
.MetaFile
= File
1208 self
._PackageDir
= File
.Dir
1209 self
._RawData
= RawData
1210 self
._Bdb
= BuildDataBase
1212 self
._Target
= Target
1213 self
._Toolchain
= Toolchain
1217 def __setitem__(self
, key
, value
):
1218 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1221 def __getitem__(self
, key
):
1222 return self
.__dict
__[self
._PROPERTY
_[key
]]
1224 ## "in" test support
1225 def __contains__(self
, key
):
1226 return key
in self
._PROPERTY
_
1228 ## Set all internal used members of DecBuildData to None
1231 self
._PackageName
= None
1233 self
._Version
= None
1234 self
._PkgUniFile
= None
1235 self
._Protocols
= None
1238 self
._Includes
= None
1239 self
._LibraryClasses
= None
1241 self
.__Macros
= None
1243 ## Get current effective macros
1244 def _GetMacros(self
):
1245 if self
.__Macros
== None:
1247 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1248 return self
.__Macros
1256 # Changing the default ARCH to another may affect all other information
1257 # because all information in a platform may be ARCH-related. That's
1258 # why we need to clear all internal used members, in order to cause all
1259 # information to be re-retrieved.
1261 # @param Value The value of ARCH
1263 def _SetArch(self
, Value
):
1264 if self
._Arch
== Value
:
1269 ## Retrieve all information in [Defines] section
1271 # (Retriving all [Defines] information in one-shot is just to save time.)
1273 def _GetHeaderInfo(self
):
1274 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1275 for Record
in RecordList
:
1278 self
[Name
] = Record
[2]
1279 self
._Header
= 'DUMMY'
1281 ## Retrieve package name
1282 def _GetPackageName(self
):
1283 if self
._PackageName
== None:
1284 if self
._Header
== None:
1285 self
._GetHeaderInfo
()
1286 if self
._PackageName
== None:
1287 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1288 return self
._PackageName
1290 ## Retrieve file guid
1291 def _GetFileGuid(self
):
1292 if self
._Guid
== None:
1293 if self
._Header
== None:
1294 self
._GetHeaderInfo
()
1295 if self
._Guid
== None:
1296 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1299 ## Retrieve package version
1300 def _GetVersion(self
):
1301 if self
._Version
== None:
1302 if self
._Header
== None:
1303 self
._GetHeaderInfo
()
1304 if self
._Version
== None:
1306 return self
._Version
1308 ## Retrieve protocol definitions (name/value pairs)
1309 def _GetProtocol(self
):
1310 if self
._Protocols
== None:
1312 # tdict is a special kind of dict, used for selecting correct
1313 # protocol defition for given ARCH
1315 ProtocolDict
= tdict(True)
1317 # find out all protocol definitions for specific and 'common' arch
1318 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1319 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1320 if Name
not in NameList
:
1321 NameList
.append(Name
)
1322 ProtocolDict
[Arch
, Name
] = Guid
1323 # use sdict to keep the order
1324 self
._Protocols
= sdict()
1325 for Name
in NameList
:
1327 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1328 # will automatically turn to 'common' ARCH for trying
1330 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1331 return self
._Protocols
1333 ## Retrieve PPI definitions (name/value pairs)
1335 if self
._Ppis
== None:
1337 # tdict is a special kind of dict, used for selecting correct
1338 # PPI defition for given ARCH
1340 PpiDict
= tdict(True)
1342 # find out all PPI definitions for specific arch and 'common' arch
1343 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1344 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1345 if Name
not in NameList
:
1346 NameList
.append(Name
)
1347 PpiDict
[Arch
, Name
] = Guid
1348 # use sdict to keep the order
1349 self
._Ppis
= sdict()
1350 for Name
in NameList
:
1352 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1353 # will automatically turn to 'common' ARCH for trying
1355 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1358 ## Retrieve GUID definitions (name/value pairs)
1360 if self
._Guids
== None:
1362 # tdict is a special kind of dict, used for selecting correct
1363 # GUID defition for given ARCH
1365 GuidDict
= tdict(True)
1367 # find out all protocol definitions for specific and 'common' arch
1368 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1369 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1370 if Name
not in NameList
:
1371 NameList
.append(Name
)
1372 GuidDict
[Arch
, Name
] = Guid
1373 # use sdict to keep the order
1374 self
._Guids
= sdict()
1375 for Name
in NameList
:
1377 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1378 # will automatically turn to 'common' ARCH for trying
1380 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1383 ## Retrieve public include paths declared in this package
1384 def _GetInclude(self
):
1385 if self
._Includes
== None:
1387 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1388 Macros
= self
._Macros
1389 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1390 for Record
in RecordList
:
1391 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1394 ErrorCode
, ErrorInfo
= File
.Validate()
1396 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1398 # avoid duplicate include path
1399 if File
not in self
._Includes
:
1400 self
._Includes
.append(File
)
1401 return self
._Includes
1403 ## Retrieve library class declarations (not used in build at present)
1404 def _GetLibraryClass(self
):
1405 if self
._LibraryClasses
== None:
1407 # tdict is a special kind of dict, used for selecting correct
1408 # library class declaration for given ARCH
1410 LibraryClassDict
= tdict(True)
1411 LibraryClassSet
= set()
1412 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1413 Macros
= self
._Macros
1414 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1415 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1416 # check the file validation
1417 ErrorCode
, ErrorInfo
= File
.Validate()
1419 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1420 LibraryClassSet
.add(LibraryClass
)
1421 LibraryClassDict
[Arch
, LibraryClass
] = File
1422 self
._LibraryClasses
= sdict()
1423 for LibraryClass
in LibraryClassSet
:
1424 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1425 return self
._LibraryClasses
1427 ## Retrieve PCD declarations
1429 if self
._Pcds
== None:
1430 self
._Pcds
= sdict()
1431 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1432 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1433 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1434 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1435 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1438 ## Retrieve PCD declarations for given type
1439 def _GetPcd(self
, Type
):
1442 # tdict is a special kind of dict, used for selecting correct
1443 # PCD declaration for given ARCH
1445 PcdDict
= tdict(True, 3)
1446 # for summarizing PCD
1448 # find out all PCDs of the 'type'
1449 RecordList
= self
._RawData
[Type
, self
._Arch
]
1450 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1451 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1452 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1454 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1456 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1457 # will automatically turn to 'common' ARCH and try again
1459 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1463 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1465 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1468 self
._PCD
_TYPE
_STRING
_[Type
],
1480 _Macros
= property(_GetMacros
)
1481 Arch
= property(_GetArch
, _SetArch
)
1482 PackageName
= property(_GetPackageName
)
1483 Guid
= property(_GetFileGuid
)
1484 Version
= property(_GetVersion
)
1486 Protocols
= property(_GetProtocol
)
1487 Ppis
= property(_GetPpi
)
1488 Guids
= property(_GetGuid
)
1489 Includes
= property(_GetInclude
)
1490 LibraryClasses
= property(_GetLibraryClass
)
1491 Pcds
= property(_GetPcds
)
1493 ## Module build information from INF file
1495 # This class is used to retrieve information stored in database and convert them
1496 # into ModuleBuildClassObject form for easier use for AutoGen.
1498 class InfBuildData(ModuleBuildClassObject
):
1499 # dict used to convert PCD type in database to string used by build tool
1500 _PCD_TYPE_STRING_
= {
1501 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1502 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1503 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1504 MODEL_PCD_DYNAMIC
: "Dynamic",
1505 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1506 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1507 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1508 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1509 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1510 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1511 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1514 # dict used to convert part of [Defines] to members of InfBuildData directly
1519 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1520 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1521 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1525 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1526 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1527 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1528 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1529 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1530 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1531 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1532 TAB_INF_DEFINES_VERSION
: "_Version",
1533 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1534 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1536 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1539 # dict used to convert Component type to Module type
1542 "SECURITY_CORE" : "SEC",
1543 "PEI_CORE" : "PEI_CORE",
1544 "COMBINED_PEIM_DRIVER" : "PEIM",
1545 "PIC_PEIM" : "PEIM",
1546 "RELOCATABLE_PEIM" : "PEIM",
1547 "PE32_PEIM" : "PEIM",
1548 "BS_DRIVER" : "DXE_DRIVER",
1549 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1550 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1551 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1552 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1553 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1554 # "BS_DRIVER" : "UEFI_DRIVER",
1555 "APPLICATION" : "UEFI_APPLICATION",
1559 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1560 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1561 # dict used to convert old tool name used in [nmake] section to new ones
1569 ## Constructor of DscBuildData
1571 # Initialize object of DscBuildData
1573 # @param FilePath The path of platform description file
1574 # @param RawData The raw data of DSC file
1575 # @param BuildDataBase Database used to retrieve module/package information
1576 # @param Arch The target architecture
1577 # @param Platform The name of platform employing this module
1578 # @param Macros Macros used for replacement in DSC file
1580 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1581 self
.MetaFile
= FilePath
1582 self
._ModuleDir
= FilePath
.Dir
1583 self
._RawData
= RawData
1584 self
._Bdb
= BuildDatabase
1586 self
._Target
= Target
1587 self
._Toolchain
= Toolchain
1588 self
._Platform
= 'COMMON'
1589 self
._SourceOverridePath
= None
1590 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1591 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1595 def __setitem__(self
, key
, value
):
1596 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1599 def __getitem__(self
, key
):
1600 return self
.__dict
__[self
._PROPERTY
_[key
]]
1602 ## "in" test support
1603 def __contains__(self
, key
):
1604 return key
in self
._PROPERTY
_
1606 ## Set all internal used members of InfBuildData to None
1608 self
._HeaderComments
= None
1609 self
._TailComments
= None
1610 self
._Header
_ = None
1611 self
._AutoGenVersion
= None
1612 self
._BaseName
= None
1613 self
._DxsFile
= None
1614 self
._ModuleType
= None
1615 self
._ComponentType
= None
1616 self
._BuildType
= None
1618 self
._Version
= None
1619 self
._PcdIsDriver
= None
1620 self
._BinaryModule
= None
1622 self
._MakefileName
= None
1623 self
._CustomMakefile
= None
1624 self
._Specification
= None
1625 self
._LibraryClass
= None
1626 self
._ModuleEntryPointList
= None
1627 self
._ModuleUnloadImageList
= None
1628 self
._ConstructorList
= None
1629 self
._DestructorList
= None
1631 self
._Binaries
= None
1632 self
._Sources
= None
1633 self
._LibraryClasses
= None
1634 self
._Libraries
= None
1635 self
._Protocols
= None
1636 self
._ProtocolComments
= None
1638 self
._PpiComments
= None
1640 self
._GuidsUsedByPcd
= sdict()
1641 self
._GuidComments
= None
1642 self
._Includes
= None
1643 self
._Packages
= None
1645 self
._PcdComments
= None
1646 self
._BuildOptions
= None
1648 self
._DepexExpression
= None
1649 self
.__Macros
= None
1651 ## Get current effective macros
1652 def _GetMacros(self
):
1653 if self
.__Macros
== None:
1655 # EDK_GLOBAL defined macros can be applied to EDK module
1656 if self
.AutoGenVersion
< 0x00010005:
1657 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1658 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1659 return self
.__Macros
1667 # Changing the default ARCH to another may affect all other information
1668 # because all information in a platform may be ARCH-related. That's
1669 # why we need to clear all internal used members, in order to cause all
1670 # information to be re-retrieved.
1672 # @param Value The value of ARCH
1674 def _SetArch(self
, Value
):
1675 if self
._Arch
== Value
:
1680 ## Return the name of platform employing this module
1681 def _GetPlatform(self
):
1682 return self
._Platform
1684 ## Change the name of platform employing this module
1686 # Changing the default name of platform to another may affect some information
1687 # because they may be PLATFORM-related. That's why we need to clear all internal
1688 # used members, in order to cause all information to be re-retrieved.
1690 def _SetPlatform(self
, Value
):
1691 if self
._Platform
== Value
:
1693 self
._Platform
= Value
1695 def _GetHeaderComments(self
):
1696 if not self
._HeaderComments
:
1697 self
._HeaderComments
= []
1698 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1699 for Record
in RecordList
:
1700 self
._HeaderComments
.append(Record
[0])
1701 return self
._HeaderComments
1702 def _GetTailComments(self
):
1703 if not self
._TailComments
:
1704 self
._TailComments
= []
1705 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1706 for Record
in RecordList
:
1707 self
._TailComments
.append(Record
[0])
1708 return self
._TailComments
1709 ## Retrieve all information in [Defines] section
1711 # (Retriving all [Defines] information in one-shot is just to save time.)
1713 def _GetHeaderInfo(self
):
1714 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1715 for Record
in RecordList
:
1716 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1717 # items defined _PROPERTY_ don't need additional processing
1720 if self
._Defs
== None:
1721 self
._Defs
= sdict()
1722 self
._Defs
[Name
] = Value
1723 # some special items in [Defines] section need special treatment
1724 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1725 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1726 Name
= 'UEFI_SPECIFICATION_VERSION'
1727 if self
._Specification
== None:
1728 self
._Specification
= sdict()
1729 self
._Specification
[Name
] = GetHexVerValue(Value
)
1730 if self
._Specification
[Name
] == None:
1731 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1732 "'%s' format is not supported for %s" % (Value
, Name
),
1733 File
=self
.MetaFile
, Line
=Record
[-1])
1734 elif Name
== 'LIBRARY_CLASS':
1735 if self
._LibraryClass
== None:
1736 self
._LibraryClass
= []
1737 ValueList
= GetSplitValueList(Value
)
1738 LibraryClass
= ValueList
[0]
1739 if len(ValueList
) > 1:
1740 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1742 SupModuleList
= SUP_MODULE_LIST
1743 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1744 elif Name
== 'ENTRY_POINT':
1745 if self
._ModuleEntryPointList
== None:
1746 self
._ModuleEntryPointList
= []
1747 self
._ModuleEntryPointList
.append(Value
)
1748 elif Name
== 'UNLOAD_IMAGE':
1749 if self
._ModuleUnloadImageList
== None:
1750 self
._ModuleUnloadImageList
= []
1753 self
._ModuleUnloadImageList
.append(Value
)
1754 elif Name
== 'CONSTRUCTOR':
1755 if self
._ConstructorList
== None:
1756 self
._ConstructorList
= []
1759 self
._ConstructorList
.append(Value
)
1760 elif Name
== 'DESTRUCTOR':
1761 if self
._DestructorList
== None:
1762 self
._DestructorList
= []
1765 self
._DestructorList
.append(Value
)
1766 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1767 TokenList
= GetSplitValueList(Value
)
1768 if self
._CustomMakefile
== None:
1769 self
._CustomMakefile
= {}
1770 if len(TokenList
) < 2:
1771 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1772 self
._CustomMakefile
['GCC'] = TokenList
[0]
1774 if TokenList
[0] not in ['MSFT', 'GCC']:
1775 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1776 "No supported family [%s]" % TokenList
[0],
1777 File
=self
.MetaFile
, Line
=Record
[-1])
1778 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1780 if self
._Defs
== None:
1781 self
._Defs
= sdict()
1782 self
._Defs
[Name
] = Value
1785 # Retrieve information in sections specific to Edk.x modules
1787 if self
.AutoGenVersion
>= 0x00010005:
1788 if not self
._ModuleType
:
1789 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1790 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1791 if self
._ModuleType
not in SUP_MODULE_LIST
:
1792 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1793 for Record
in RecordList
:
1795 if Name
== "MODULE_TYPE":
1798 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1799 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1800 File
=self
.MetaFile
, Line
=LineNo
)
1801 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1802 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1803 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
)
1804 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1805 and 'PCI_CLASS_CODE' in self
._Defs
:
1806 self
._BuildType
= 'UEFI_OPTIONROM'
1807 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1808 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1809 self
._BuildType
= 'UEFI_HII'
1811 self
._BuildType
= self
._ModuleType
.upper()
1814 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1815 # check the file validation
1816 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1818 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1819 File
=self
.MetaFile
, Line
=LineNo
)
1820 if self
.Sources
== None:
1822 self
._Sources
.append(File
)
1824 if not self
._ComponentType
:
1825 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1826 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1827 self
._BuildType
= self
._ComponentType
.upper()
1828 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1829 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1830 if self
._ComponentType
== 'LIBRARY':
1831 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1832 # make use some [nmake] section macros
1833 Macros
= self
._Macros
1834 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1835 Macros
['PROCESSOR'] = self
._Arch
1836 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1837 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1838 Value
= ReplaceMacro(Value
, Macros
, True)
1839 if Name
== "IMAGE_ENTRY_POINT":
1840 if self
._ModuleEntryPointList
== None:
1841 self
._ModuleEntryPointList
= []
1842 self
._ModuleEntryPointList
.append(Value
)
1843 elif Name
== "DPX_SOURCE":
1844 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1845 # check the file validation
1846 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1848 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1849 File
=self
.MetaFile
, Line
=LineNo
)
1850 if self
.Sources
== None:
1852 self
._Sources
.append(File
)
1854 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1855 if len(ToolList
) == 0 or len(ToolList
) != 1:
1857 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1858 # File=self.MetaFile, Line=LineNo)
1860 if self
._BuildOptions
== None:
1861 self
._BuildOptions
= sdict()
1863 if ToolList
[0] in self
._TOOL
_CODE
_:
1864 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1867 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1868 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1869 #ignore not replaced macros in value
1870 ValueList
= GetSplitList(' ' + Value
, '/D')
1871 Dummy
= ValueList
[0]
1872 for Index
in range(1, len(ValueList
)):
1873 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1875 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1876 Value
= Dummy
.strip()
1877 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1878 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1880 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1881 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1882 # set _Header to non-None in order to avoid database re-querying
1883 self
._Header
_ = 'DUMMY'
1885 ## Retrieve file version
1886 def _GetInfVersion(self
):
1887 if self
._AutoGenVersion
== None:
1888 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1889 for Record
in RecordList
:
1890 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1891 self
._AutoGenVersion
= int(Record
[2], 0)
1893 if self
._AutoGenVersion
== None:
1894 self
._AutoGenVersion
= 0x00010000
1895 return self
._AutoGenVersion
1897 ## Retrieve BASE_NAME
1898 def _GetBaseName(self
):
1899 if self
._BaseName
== None:
1900 if self
._Header
_ == None:
1901 self
._GetHeaderInfo
()
1902 if self
._BaseName
== None:
1903 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1904 return self
._BaseName
1907 def _GetDxsFile(self
):
1908 if self
._DxsFile
== None:
1909 if self
._Header
_ == None:
1910 self
._GetHeaderInfo
()
1911 if self
._DxsFile
== None:
1913 return self
._DxsFile
1915 ## Retrieve MODULE_TYPE
1916 def _GetModuleType(self
):
1917 if self
._ModuleType
== None:
1918 if self
._Header
_ == None:
1919 self
._GetHeaderInfo
()
1920 if self
._ModuleType
== None:
1921 self
._ModuleType
= 'BASE'
1922 if self
._ModuleType
not in SUP_MODULE_LIST
:
1923 self
._ModuleType
= "USER_DEFINED"
1924 return self
._ModuleType
1926 ## Retrieve COMPONENT_TYPE
1927 def _GetComponentType(self
):
1928 if self
._ComponentType
== None:
1929 if self
._Header
_ == None:
1930 self
._GetHeaderInfo
()
1931 if self
._ComponentType
== None:
1932 self
._ComponentType
= 'USER_DEFINED'
1933 return self
._ComponentType
1935 ## Retrieve "BUILD_TYPE"
1936 def _GetBuildType(self
):
1937 if self
._BuildType
== None:
1938 if self
._Header
_ == None:
1939 self
._GetHeaderInfo
()
1940 if not self
._BuildType
:
1941 self
._BuildType
= "BASE"
1942 return self
._BuildType
1944 ## Retrieve file guid
1945 def _GetFileGuid(self
):
1946 if self
._Guid
== None:
1947 if self
._Header
_ == None:
1948 self
._GetHeaderInfo
()
1949 if self
._Guid
== None:
1950 self
._Guid
= '00000000-0000-0000-000000000000'
1953 ## Retrieve module version
1954 def _GetVersion(self
):
1955 if self
._Version
== None:
1956 if self
._Header
_ == None:
1957 self
._GetHeaderInfo
()
1958 if self
._Version
== None:
1959 self
._Version
= '0.0'
1960 return self
._Version
1962 ## Retrieve PCD_IS_DRIVER
1963 def _GetPcdIsDriver(self
):
1964 if self
._PcdIsDriver
== None:
1965 if self
._Header
_ == None:
1966 self
._GetHeaderInfo
()
1967 if self
._PcdIsDriver
== None:
1968 self
._PcdIsDriver
= ''
1969 return self
._PcdIsDriver
1972 def _GetShadow(self
):
1973 if self
._Shadow
== None:
1974 if self
._Header
_ == None:
1975 self
._GetHeaderInfo
()
1976 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1979 self
._Shadow
= False
1982 ## Retrieve CUSTOM_MAKEFILE
1983 def _GetMakefile(self
):
1984 if self
._CustomMakefile
== None:
1985 if self
._Header
_ == None:
1986 self
._GetHeaderInfo
()
1987 if self
._CustomMakefile
== None:
1988 self
._CustomMakefile
= {}
1989 return self
._CustomMakefile
1991 ## Retrieve EFI_SPECIFICATION_VERSION
1993 if self
._Specification
== None:
1994 if self
._Header
_ == None:
1995 self
._GetHeaderInfo
()
1996 if self
._Specification
== None:
1997 self
._Specification
= {}
1998 return self
._Specification
2000 ## Retrieve LIBRARY_CLASS
2001 def _GetLibraryClass(self
):
2002 if self
._LibraryClass
== None:
2003 if self
._Header
_ == None:
2004 self
._GetHeaderInfo
()
2005 if self
._LibraryClass
== None:
2006 self
._LibraryClass
= []
2007 return self
._LibraryClass
2009 ## Retrieve ENTRY_POINT
2010 def _GetEntryPoint(self
):
2011 if self
._ModuleEntryPointList
== None:
2012 if self
._Header
_ == None:
2013 self
._GetHeaderInfo
()
2014 if self
._ModuleEntryPointList
== None:
2015 self
._ModuleEntryPointList
= []
2016 return self
._ModuleEntryPointList
2018 ## Retrieve UNLOAD_IMAGE
2019 def _GetUnloadImage(self
):
2020 if self
._ModuleUnloadImageList
== None:
2021 if self
._Header
_ == None:
2022 self
._GetHeaderInfo
()
2023 if self
._ModuleUnloadImageList
== None:
2024 self
._ModuleUnloadImageList
= []
2025 return self
._ModuleUnloadImageList
2027 ## Retrieve CONSTRUCTOR
2028 def _GetConstructor(self
):
2029 if self
._ConstructorList
== None:
2030 if self
._Header
_ == None:
2031 self
._GetHeaderInfo
()
2032 if self
._ConstructorList
== None:
2033 self
._ConstructorList
= []
2034 return self
._ConstructorList
2036 ## Retrieve DESTRUCTOR
2037 def _GetDestructor(self
):
2038 if self
._DestructorList
== None:
2039 if self
._Header
_ == None:
2040 self
._GetHeaderInfo
()
2041 if self
._DestructorList
== None:
2042 self
._DestructorList
= []
2043 return self
._DestructorList
2045 ## Retrieve definies other than above ones
2046 def _GetDefines(self
):
2047 if self
._Defs
== None:
2048 if self
._Header
_ == None:
2049 self
._GetHeaderInfo
()
2050 if self
._Defs
== None:
2051 self
._Defs
= sdict()
2054 ## Retrieve binary files
2055 def _GetBinaries(self
):
2056 if self
._Binaries
== None:
2058 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2059 Macros
= self
._Macros
2060 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2061 Macros
['PROCESSOR'] = self
._Arch
2062 for Record
in RecordList
:
2063 FileType
= Record
[0]
2068 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2070 Target
= TokenList
[0]
2071 if len(TokenList
) > 1:
2072 FeatureFlag
= Record
[1:]
2074 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2075 # check the file validation
2076 ErrorCode
, ErrorInfo
= File
.Validate()
2078 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2079 self
._Binaries
.append(File
)
2080 return self
._Binaries
2082 ## Retrieve binary files with error check.
2083 def _GetBinaryFiles(self
):
2084 Binaries
= self
._GetBinaries
()
2085 if GlobalData
.gIgnoreSource
and Binaries
== []:
2086 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2087 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2090 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2091 def _IsSupportedArch(self
):
2092 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2096 ## Retrieve source files
2097 def _GetSourceFiles(self
):
2098 #Ignore all source files in a binary build mode
2099 if GlobalData
.gIgnoreSource
:
2101 return self
._Sources
2103 if self
._Sources
== None:
2105 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2106 Macros
= self
._Macros
2107 for Record
in RecordList
:
2109 ToolChainFamily
= Record
[1]
2111 ToolCode
= Record
[3]
2112 FeatureFlag
= Record
[4]
2113 if self
.AutoGenVersion
< 0x00010005:
2114 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2115 Macros
['PROCESSOR'] = self
._Arch
2116 # old module source files (Edk)
2117 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
2118 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2119 # check the file validation
2120 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2122 if File
.Ext
.lower() == '.h':
2123 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2124 File
=self
.MetaFile
, Line
=LineNo
)
2127 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2129 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2130 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2131 # check the file validation
2132 ErrorCode
, ErrorInfo
= File
.Validate()
2134 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2136 self
._Sources
.append(File
)
2137 return self
._Sources
2139 ## Retrieve library classes employed by this module
2140 def _GetLibraryClassUses(self
):
2141 if self
._LibraryClasses
== None:
2142 self
._LibraryClasses
= sdict()
2143 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2144 for Record
in RecordList
:
2146 Instance
= Record
[1]
2148 Instance
= NormPath(Instance
, self
._Macros
)
2149 self
._LibraryClasses
[Lib
] = Instance
2150 return self
._LibraryClasses
2152 ## Retrieve library names (for Edk.x style of modules)
2153 def _GetLibraryNames(self
):
2154 if self
._Libraries
== None:
2155 self
._Libraries
= []
2156 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2157 for Record
in RecordList
:
2158 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2159 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2160 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2161 if LibraryName
not in self
._Libraries
:
2162 self
._Libraries
.append(LibraryName
)
2163 return self
._Libraries
2165 def _GetProtocolComments(self
):
2166 self
._GetProtocols
()
2167 return self
._ProtocolComments
2168 ## Retrieve protocols consumed/produced by this module
2169 def _GetProtocols(self
):
2170 if self
._Protocols
== None:
2171 self
._Protocols
= sdict()
2172 self
._ProtocolComments
= sdict()
2173 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2174 for Record
in RecordList
:
2176 Value
= ProtocolValue(CName
, self
.Packages
)
2178 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2179 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2180 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2181 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2182 self
._Protocols
[CName
] = Value
2183 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2185 for CmtRec
in CommentRecords
:
2186 Comments
.append(CmtRec
[0])
2187 self
._ProtocolComments
[CName
] = Comments
2188 return self
._Protocols
2190 def _GetPpiComments(self
):
2192 return self
._PpiComments
2193 ## Retrieve PPIs consumed/produced by this module
2195 if self
._Ppis
== None:
2196 self
._Ppis
= sdict()
2197 self
._PpiComments
= sdict()
2198 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2199 for Record
in RecordList
:
2201 Value
= PpiValue(CName
, self
.Packages
)
2203 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2204 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2205 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2206 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2207 self
._Ppis
[CName
] = Value
2208 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2210 for CmtRec
in CommentRecords
:
2211 Comments
.append(CmtRec
[0])
2212 self
._PpiComments
[CName
] = Comments
2215 def _GetGuidComments(self
):
2217 return self
._GuidComments
2218 ## Retrieve GUIDs consumed/produced by this module
2219 def _GetGuids(self
):
2220 if self
._Guids
== None:
2221 self
._Guids
= sdict()
2222 self
._GuidComments
= sdict()
2223 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2224 for Record
in RecordList
:
2226 Value
= GuidValue(CName
, self
.Packages
)
2228 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2229 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2230 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2231 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2232 self
._Guids
[CName
] = Value
2233 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2235 for CmtRec
in CommentRecords
:
2236 Comments
.append(CmtRec
[0])
2237 self
._GuidComments
[CName
] = Comments
2240 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2241 def _GetIncludes(self
):
2242 if self
._Includes
== None:
2244 if self
._SourceOverridePath
:
2245 self
._Includes
.append(self
._SourceOverridePath
)
2247 Macros
= self
._Macros
2248 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2249 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2251 Macros
['PROCESSOR'] = self
._Arch
2252 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2253 for Record
in RecordList
:
2254 if Record
[0].find('EDK_SOURCE') > -1:
2255 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2256 File
= NormPath(Record
[0], self
._Macros
)
2258 File
= os
.path
.join(self
._ModuleDir
, File
)
2260 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2261 File
= RealPath(os
.path
.normpath(File
))
2263 self
._Includes
.append(File
)
2265 #TRICK: let compiler to choose correct header file
2266 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2267 File
= NormPath(Record
[0], self
._Macros
)
2269 File
= os
.path
.join(self
._ModuleDir
, File
)
2271 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2272 File
= RealPath(os
.path
.normpath(File
))
2274 self
._Includes
.append(File
)
2276 File
= NormPath(Record
[0], Macros
)
2278 File
= os
.path
.join(self
._ModuleDir
, File
)
2280 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2281 File
= RealPath(os
.path
.normpath(File
))
2283 self
._Includes
.append(File
)
2284 return self
._Includes
2286 ## Retrieve packages this module depends on
2287 def _GetPackages(self
):
2288 if self
._Packages
== None:
2290 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2291 Macros
= self
._Macros
2292 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2293 for Record
in RecordList
:
2294 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2296 # check the file validation
2297 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2299 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2300 # parse this package now. we need it to get protocol/ppi/guid value
2301 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2302 self
._Packages
.append(Package
)
2303 return self
._Packages
2305 ## Retrieve PCD comments
2306 def _GetPcdComments(self
):
2308 return self
._PcdComments
2309 ## Retrieve PCDs used in this module
2311 if self
._Pcds
== None:
2312 self
._Pcds
= sdict()
2313 self
._PcdComments
= sdict()
2314 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2315 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2316 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2317 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2318 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2321 ## Retrieve build options specific to this module
2322 def _GetBuildOptions(self
):
2323 if self
._BuildOptions
== None:
2324 self
._BuildOptions
= sdict()
2325 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2326 for Record
in RecordList
:
2327 ToolChainFamily
= Record
[0]
2328 ToolChain
= Record
[1]
2330 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2331 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2333 # concatenate the option string if they're for the same tool
2334 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2335 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2336 return self
._BuildOptions
2338 ## Retrieve dependency expression
2339 def _GetDepex(self
):
2340 if self
._Depex
== None:
2341 self
._Depex
= tdict(False, 2)
2342 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2344 # If the module has only Binaries and no Sources, then ignore [Depex]
2345 if self
.Sources
== None or self
.Sources
== []:
2346 if self
.Binaries
!= None and self
.Binaries
!= []:
2349 # PEIM and DXE drivers must have a valid [Depex] section
2350 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2351 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2352 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2353 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2354 % self
.ModuleType
, File
=self
.MetaFile
)
2356 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2357 for Record
in RecordList
:
2358 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2359 EdkLogger
.error('build', FORMAT_INVALID
,
2360 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2364 for Record
in RecordList
:
2365 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2367 ModuleType
= Record
[4]
2368 TokenList
= DepexStr
.split()
2369 if (Arch
, ModuleType
) not in Depex
:
2370 Depex
[Arch
, ModuleType
] = []
2371 DepexList
= Depex
[Arch
, ModuleType
]
2372 for Token
in TokenList
:
2373 if Token
in DEPEX_SUPPORTED_OPCODE
:
2374 DepexList
.append(Token
)
2375 elif Token
.endswith(".inf"): # module file name
2376 ModuleFile
= os
.path
.normpath(Token
)
2377 Module
= self
.BuildDatabase
[ModuleFile
]
2379 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2380 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2381 DepexList
.append(Module
.Guid
)
2383 # get the GUID value now
2384 Value
= ProtocolValue(Token
, self
.Packages
)
2386 Value
= PpiValue(Token
, self
.Packages
)
2388 Value
= GuidValue(Token
, self
.Packages
)
2390 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2391 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2392 "Value of [%s] is not found in" % Token
,
2393 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2394 DepexList
.append(Value
)
2395 for Arch
, ModuleType
in Depex
:
2396 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2399 ## Retrieve depedency expression
2400 def _GetDepexExpression(self
):
2401 if self
._DepexExpression
== None:
2402 self
._DepexExpression
= tdict(False, 2)
2403 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2404 DepexExpression
= sdict()
2405 for Record
in RecordList
:
2406 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2408 ModuleType
= Record
[4]
2409 TokenList
= DepexStr
.split()
2410 if (Arch
, ModuleType
) not in DepexExpression
:
2411 DepexExpression
[Arch
, ModuleType
] = ''
2412 for Token
in TokenList
:
2413 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2414 for Arch
, ModuleType
in DepexExpression
:
2415 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2416 return self
._DepexExpression
2418 def GetGuidsUsedByPcd(self
):
2419 return self
._GuidsUsedByPcd
2420 ## Retrieve PCD for given type
2421 def _GetPcd(self
, Type
):
2423 PcdDict
= tdict(True, 4)
2425 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2426 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2427 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2428 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2429 # get the guid value
2430 if TokenSpaceGuid
not in self
.Guids
:
2431 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2433 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2434 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2435 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2436 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2437 self
.Guids
[TokenSpaceGuid
] = Value
2438 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2439 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2441 for CmtRec
in CommentRecords
:
2442 Comments
.append(CmtRec
[0])
2443 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2445 # resolve PCD type, value, datum info, etc. by getting its definition from package
2446 for PcdCName
, TokenSpaceGuid
in PcdList
:
2447 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2450 ValueList
= AnalyzePcdData(Setting
)
2451 DefaultValue
= ValueList
[0]
2452 Pcd
= PcdClassObject(
2462 self
.Guids
[TokenSpaceGuid
]
2464 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2465 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2466 Pcd
.Offset
= ValueList
[1]
2468 # get necessary info from package declaring this PCD
2469 for Package
in self
.Packages
:
2471 # 'dynamic' in INF means its type is determined by platform;
2472 # if platform doesn't give its type, use 'lowest' one in the
2473 # following order, if any
2475 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2477 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2478 if Type
== MODEL_PCD_DYNAMIC
:
2480 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2481 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2487 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2488 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2490 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2493 # Check whether the token value exist or not.
2495 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2499 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2500 File
=self
.MetaFile
, Line
=LineNo
,
2504 # Check hexadecimal token value length and format.
2506 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2507 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2508 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2512 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2513 File
=self
.MetaFile
, Line
=LineNo
,
2518 # Check decimal token value length and format.
2522 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2523 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2527 "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
)),
2528 File
=self
.MetaFile
, Line
=LineNo
,
2535 "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
)),
2536 File
=self
.MetaFile
, Line
=LineNo
,
2540 Pcd
.DatumType
= PcdInPackage
.DatumType
2541 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2542 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2543 if Pcd
.DefaultValue
in [None, '']:
2544 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2550 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2551 File
=self
.MetaFile
, Line
=LineNo
,
2552 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2554 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2558 ## check whether current module is binary module
2559 def _IsBinaryModule(self
):
2560 if self
.Binaries
and not self
.Sources
:
2562 elif GlobalData
.gIgnoreSource
:
2567 _Macros
= property(_GetMacros
)
2568 Arch
= property(_GetArch
, _SetArch
)
2569 Platform
= property(_GetPlatform
, _SetPlatform
)
2571 HeaderComments
= property(_GetHeaderComments
)
2572 TailComments
= property(_GetTailComments
)
2573 AutoGenVersion
= property(_GetInfVersion
)
2574 BaseName
= property(_GetBaseName
)
2575 ModuleType
= property(_GetModuleType
)
2576 ComponentType
= property(_GetComponentType
)
2577 BuildType
= property(_GetBuildType
)
2578 Guid
= property(_GetFileGuid
)
2579 Version
= property(_GetVersion
)
2580 PcdIsDriver
= property(_GetPcdIsDriver
)
2581 Shadow
= property(_GetShadow
)
2582 CustomMakefile
= property(_GetMakefile
)
2583 Specification
= property(_GetSpec
)
2584 LibraryClass
= property(_GetLibraryClass
)
2585 ModuleEntryPointList
= property(_GetEntryPoint
)
2586 ModuleUnloadImageList
= property(_GetUnloadImage
)
2587 ConstructorList
= property(_GetConstructor
)
2588 DestructorList
= property(_GetDestructor
)
2589 Defines
= property(_GetDefines
)
2590 DxsFile
= property(_GetDxsFile
)
2592 Binaries
= property(_GetBinaryFiles
)
2593 Sources
= property(_GetSourceFiles
)
2594 LibraryClasses
= property(_GetLibraryClassUses
)
2595 Libraries
= property(_GetLibraryNames
)
2596 Protocols
= property(_GetProtocols
)
2597 ProtocolComments
= property(_GetProtocolComments
)
2598 Ppis
= property(_GetPpis
)
2599 PpiComments
= property(_GetPpiComments
)
2600 Guids
= property(_GetGuids
)
2601 GuidComments
= property(_GetGuidComments
)
2602 Includes
= property(_GetIncludes
)
2603 Packages
= property(_GetPackages
)
2604 Pcds
= property(_GetPcds
)
2605 PcdComments
= property(_GetPcdComments
)
2606 BuildOptions
= property(_GetBuildOptions
)
2607 Depex
= property(_GetDepex
)
2608 DepexExpression
= property(_GetDepexExpression
)
2609 IsBinaryModule
= property(_IsBinaryModule
)
2610 IsSupportedArch
= property(_IsSupportedArch
)
2614 # This class defined the build database for all modules, packages and platform.
2615 # It will call corresponding parser for the given file if it cannot find it in
2618 # @param DbPath Path of database file
2619 # @param GlobalMacros Global macros used for replacement during file parsing
2620 # @prarm RenewDb=False Create new database file if it's already there
2622 class WorkspaceDatabase(object):
2626 # internal class used for call corresponding file parser and caching the result
2627 # to avoid unnecessary re-parsing
2629 class BuildObjectFactory(object):
2632 ".inf" : MODEL_FILE_INF
,
2633 ".dec" : MODEL_FILE_DEC
,
2634 ".dsc" : MODEL_FILE_DSC
,
2639 MODEL_FILE_INF
: InfParser
,
2640 MODEL_FILE_DEC
: DecParser
,
2641 MODEL_FILE_DSC
: DscParser
,
2644 # convert to xxxBuildData object
2646 MODEL_FILE_INF
: InfBuildData
,
2647 MODEL_FILE_DEC
: DecBuildData
,
2648 MODEL_FILE_DSC
: DscBuildData
,
2651 _CACHE_
= {} # (FilePath, Arch) : <object>
2654 def __init__(self
, WorkspaceDb
):
2655 self
.WorkspaceDb
= WorkspaceDb
2657 # key = (FilePath, Arch=None)
2658 def __contains__(self
, Key
):
2664 return (FilePath
, Arch
) in self
._CACHE
_
2666 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2667 def __getitem__(self
, Key
):
2669 KeyLength
= len(Key
)
2683 # if it's generated before, just return the cached one
2684 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2685 if Key
in self
._CACHE
_:
2686 return self
._CACHE
_[Key
]
2690 if Ext
not in self
._FILE
_TYPE
_:
2692 FileType
= self
._FILE
_TYPE
_[Ext
]
2693 if FileType
not in self
._GENERATOR
_:
2696 # get the parser ready for this file
2697 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2700 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2702 # alwasy do post-process, in case of macros change
2703 MetaFile
.DoPostProcess()
2704 # object the build is based on
2705 BuildObject
= self
._GENERATOR
_[FileType
](
2713 self
._CACHE
_[Key
] = BuildObject
2716 # placeholder for file format conversion
2717 class TransformObjectFactory
:
2718 def __init__(self
, WorkspaceDb
):
2719 self
.WorkspaceDb
= WorkspaceDb
2721 # key = FilePath, Arch
2722 def __getitem__(self
, Key
):
2725 ## Constructor of WorkspaceDatabase
2727 # @param DbPath Path of database file
2728 # @param GlobalMacros Global macros used for replacement during file parsing
2729 # @prarm RenewDb=False Create new database file if it's already there
2731 def __init__(self
, DbPath
, RenewDb
=False):
2732 self
._DbClosedFlag
= False
2734 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2736 # don't create necessary path for db in memory
2737 if DbPath
!= ':memory:':
2738 DbDir
= os
.path
.split(DbPath
)[0]
2739 if not os
.path
.exists(DbDir
):
2742 # remove db file in case inconsistency between db and file in file system
2743 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2746 # create db with optimized parameters
2747 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2748 self
.Conn
.execute("PRAGMA synchronous=OFF")
2749 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2750 self
.Conn
.execute("PRAGMA count_changes=OFF")
2751 self
.Conn
.execute("PRAGMA cache_size=8192")
2752 #self.Conn.execute("PRAGMA page_size=8192")
2754 # to avoid non-ascii character conversion issue
2755 self
.Conn
.text_factory
= str
2756 self
.Cur
= self
.Conn
.cursor()
2758 # create table for internal uses
2759 self
.TblDataModel
= TableDataModel(self
.Cur
)
2760 self
.TblFile
= TableFile(self
.Cur
)
2761 self
.Platform
= None
2763 # conversion object for build or file format conversion purpose
2764 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2765 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2767 ## Check whether workspace database need to be renew.
2768 # The renew reason maybe:
2769 # 1) If user force to renew;
2770 # 2) If user do not force renew, and
2771 # a) If the time of last modified python source is newer than database file;
2772 # b) If the time of last modified frozen executable file is newer than database file;
2774 # @param force User force renew database
2775 # @param DbPath The absolute path of workspace database file
2777 # @return Bool value for whether need renew workspace databse
2779 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2780 # if database does not exist, we need do nothing
2781 if not os
.path
.exists(DbPath
): return False
2783 # if user force to renew database, then not check whether database is out of date
2784 if force
: return True
2787 # Check the time of last modified source file or build.exe
2788 # if is newer than time of database, then database need to be re-created.
2790 timeOfToolModified
= 0
2791 if hasattr(sys
, "frozen"):
2792 exePath
= os
.path
.abspath(sys
.executable
)
2793 timeOfToolModified
= os
.stat(exePath
).st_mtime
2795 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2796 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2797 if rootPath
== "" or rootPath
== None:
2798 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2799 determine whether database file is out of date!\n")
2801 # walk the root path of source or build's binary to get the time last modified.
2803 for root
, dirs
, files
in os
.walk (rootPath
):
2805 # bypass source control folder
2806 if dir.lower() in [".svn", "_svn", "cvs"]:
2810 ext
= os
.path
.splitext(file)[1]
2811 if ext
.lower() == ".py": # only check .py files
2812 fd
= os
.stat(os
.path
.join(root
, file))
2813 if timeOfToolModified
< fd
.st_mtime
:
2814 timeOfToolModified
= fd
.st_mtime
2815 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2816 EdkLogger
.verbose("\nWorkspace database is out of data!")
2821 ## Initialize build database
2822 def InitDatabase(self
):
2823 EdkLogger
.verbose("\nInitialize build database started ...")
2828 self
.TblDataModel
.Create(False)
2829 self
.TblFile
.Create(False)
2832 # Initialize table DataModel
2834 self
.TblDataModel
.InitTable()
2835 EdkLogger
.verbose("Initialize build database ... DONE!")
2839 # @param Table: The instance of the table to be queried
2841 def QueryTable(self
, Table
):
2847 ## Close entire database
2850 # Close the connection and cursor
2853 if not self
._DbClosedFlag
:
2857 self
._DbClosedFlag
= True
2859 ## Summarize all packages in the database
2860 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2861 self
.Platform
= Platform
2863 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2865 # Get Package related to Modules
2867 for Module
in Pa
.Modules
:
2868 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2869 for Package
in ModuleObj
.Packages
:
2870 if Package
not in PackageList
:
2871 PackageList
.append(Package
)
2873 # Get Packages related to Libraries
2875 for Lib
in Pa
.LibraryInstances
:
2876 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2877 for Package
in LibObj
.Packages
:
2878 if Package
not in PackageList
:
2879 PackageList
.append(Package
)
2883 ## Summarize all platforms in the database
2884 def _GetPlatformList(self
):
2886 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2888 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2891 if Platform
!= None:
2892 PlatformList
.append(Platform
)
2895 PlatformList
= property(_GetPlatformList
)
2899 # This acts like the main() function for the script, unless it is 'import'ed into another
2902 if __name__
== '__main__':