2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2015, 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
41 from Common
.VariableAttributes
import VariableAttributes
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
._VarCheckFlag
= None
137 self
._FlashDefinition
= None
138 self
._BuildNumber
= None
139 self
._MakefileName
= None
140 self
._BsBaseAddress
= None
141 self
._RtBaseAddress
= None
144 self
._LibraryInstances
= None
145 self
._LibraryClasses
= None
148 self
._BuildOptions
= None
149 self
._LoadFixAddress
= None
150 self
._RFCLanguages
= None
151 self
._ISOLanguages
= None
152 self
._VpdToolGuid
= None
156 ## handle Override Path of Module
157 def _HandleOverridePath(self
):
158 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
159 Macros
= self
._Macros
160 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
161 for Record
in RecordList
:
164 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
165 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
167 SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
169 # Check if the source override path exists
170 if not os
.path
.isdir(SourceOverridePath
):
171 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
173 #Add to GlobalData Variables
174 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
176 ## Get current effective macros
177 def _GetMacros(self
):
178 if self
.__Macros
== None:
180 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
181 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
182 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
191 # Changing the default ARCH to another may affect all other information
192 # because all information in a platform may be ARCH-related. That's
193 # why we need to clear all internal used members, in order to cause all
194 # information to be re-retrieved.
196 # @param Value The value of ARCH
198 def _SetArch(self
, Value
):
199 if self
._Arch
== Value
:
204 ## Retrieve all information in [Defines] section
206 # (Retriving all [Defines] information in one-shot is just to save time.)
208 def _GetHeaderInfo(self
):
209 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
210 for Record
in RecordList
:
212 # items defined _PROPERTY_ don't need additional processing
214 # some special items in [Defines] section need special treatment
215 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
216 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
217 if ' ' in self
._OutputDirectory
:
218 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
219 File
=self
.MetaFile
, Line
=Record
[-1],
220 ExtraData
=self
._OutputDirectory
)
221 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
222 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
223 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
225 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
227 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
228 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
229 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
230 self
._BuildTargets
= GetSplitValueList(Record
[2])
231 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
232 if self
._SkuName
== None:
233 self
._SkuName
= Record
[2]
234 self
._SkuIdentifier
= Record
[2]
235 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
236 self
._PcdInfoFlag
= Record
[2]
237 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
238 self
._VarCheckFlag
= Record
[2]
239 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
241 self
._LoadFixAddress
= int (Record
[2], 0)
243 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
244 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
245 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
246 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"',
247 File
=self
.MetaFile
, Line
=Record
[-1])
248 LanguageCodes
= Record
[2][1:-1]
249 if not LanguageCodes
:
250 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
251 File
=self
.MetaFile
, Line
=Record
[-1])
252 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
253 # check whether there is empty entries in the list
254 if None in LanguageList
:
255 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
256 File
=self
.MetaFile
, Line
=Record
[-1])
257 self
._RFCLanguages
= LanguageList
258 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
259 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
260 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
261 File
=self
.MetaFile
, Line
=Record
[-1])
262 LanguageCodes
= Record
[2][1:-1]
263 if not LanguageCodes
:
264 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
265 File
=self
.MetaFile
, Line
=Record
[-1])
266 if len(LanguageCodes
)%3:
267 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
268 File
=self
.MetaFile
, Line
=Record
[-1])
270 for i
in range(0, len(LanguageCodes
), 3):
271 LanguageList
.append(LanguageCodes
[i
:i
+3])
272 self
._ISOLanguages
= LanguageList
273 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
275 # try to convert GUID to a real UUID value to see whether the GUID is format
276 # for VPD_TOOL_GUID is correct.
281 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
282 self
._VpdToolGuid
= Record
[2]
284 self
[Name
] = Record
[2]
285 # set _Header to non-None in order to avoid database re-querying
286 self
._Header
= 'DUMMY'
288 ## Retrieve platform name
289 def _GetPlatformName(self
):
290 if self
._PlatformName
== None:
291 if self
._Header
== None:
292 self
._GetHeaderInfo
()
293 if self
._PlatformName
== None:
294 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
295 return self
._PlatformName
297 ## Retrieve file guid
298 def _GetFileGuid(self
):
299 if self
._Guid
== None:
300 if self
._Header
== None:
301 self
._GetHeaderInfo
()
302 if self
._Guid
== None:
303 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
306 ## Retrieve platform version
307 def _GetVersion(self
):
308 if self
._Version
== None:
309 if self
._Header
== None:
310 self
._GetHeaderInfo
()
311 if self
._Version
== None:
312 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
315 ## Retrieve platform description file version
316 def _GetDscSpec(self
):
317 if self
._DscSpecification
== None:
318 if self
._Header
== None:
319 self
._GetHeaderInfo
()
320 if self
._DscSpecification
== None:
321 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
322 return self
._DscSpecification
324 ## Retrieve OUTPUT_DIRECTORY
325 def _GetOutpuDir(self
):
326 if self
._OutputDirectory
== None:
327 if self
._Header
== None:
328 self
._GetHeaderInfo
()
329 if self
._OutputDirectory
== None:
330 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
331 return self
._OutputDirectory
333 ## Retrieve SUPPORTED_ARCHITECTURES
334 def _GetSupArch(self
):
335 if self
._SupArchList
== None:
336 if self
._Header
== None:
337 self
._GetHeaderInfo
()
338 if self
._SupArchList
== None:
339 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
340 return self
._SupArchList
342 ## Retrieve BUILD_TARGETS
343 def _GetBuildTarget(self
):
344 if self
._BuildTargets
== None:
345 if self
._Header
== None:
346 self
._GetHeaderInfo
()
347 if self
._BuildTargets
== None:
348 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
349 return self
._BuildTargets
351 def _GetPcdInfoFlag(self
):
352 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
354 elif self
._PcdInfoFlag
.upper() == 'TRUE':
358 def _GetVarCheckFlag(self
):
359 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
361 elif self
._VarCheckFlag
.upper() == 'TRUE':
366 def _GetSkuIdentifier(self
):
369 if self
._SkuIdentifier
== None:
370 if self
._Header
== None:
371 self
._GetHeaderInfo
()
372 return self
._SkuIdentifier
373 ## Retrieve SKUID_IDENTIFIER
374 def _GetSkuName(self
):
375 if self
._SkuName
== None:
376 if self
._Header
== None:
377 self
._GetHeaderInfo
()
378 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
379 self
._SkuName
= 'DEFAULT'
382 ## Override SKUID_IDENTIFIER
383 def _SetSkuName(self
, Value
):
384 self
._SkuName
= Value
387 def _GetFdfFile(self
):
388 if self
._FlashDefinition
== None:
389 if self
._Header
== None:
390 self
._GetHeaderInfo
()
391 if self
._FlashDefinition
== None:
392 self
._FlashDefinition
= ''
393 return self
._FlashDefinition
395 ## Retrieve FLASH_DEFINITION
396 def _GetBuildNumber(self
):
397 if self
._BuildNumber
== None:
398 if self
._Header
== None:
399 self
._GetHeaderInfo
()
400 if self
._BuildNumber
== None:
401 self
._BuildNumber
= ''
402 return self
._BuildNumber
404 ## Retrieve MAKEFILE_NAME
405 def _GetMakefileName(self
):
406 if self
._MakefileName
== None:
407 if self
._Header
== None:
408 self
._GetHeaderInfo
()
409 if self
._MakefileName
== None:
410 self
._MakefileName
= ''
411 return self
._MakefileName
413 ## Retrieve BsBaseAddress
414 def _GetBsBaseAddress(self
):
415 if self
._BsBaseAddress
== None:
416 if self
._Header
== None:
417 self
._GetHeaderInfo
()
418 if self
._BsBaseAddress
== None:
419 self
._BsBaseAddress
= ''
420 return self
._BsBaseAddress
422 ## Retrieve RtBaseAddress
423 def _GetRtBaseAddress(self
):
424 if self
._RtBaseAddress
== None:
425 if self
._Header
== None:
426 self
._GetHeaderInfo
()
427 if self
._RtBaseAddress
== None:
428 self
._RtBaseAddress
= ''
429 return self
._RtBaseAddress
431 ## Retrieve the top address for the load fix address
432 def _GetLoadFixAddress(self
):
433 if self
._LoadFixAddress
== None:
434 if self
._Header
== None:
435 self
._GetHeaderInfo
()
437 if self
._LoadFixAddress
== None:
438 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
441 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
443 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
446 # If command line defined, should override the value in DSC file.
448 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
450 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
452 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']))
454 if self
._LoadFixAddress
< 0:
455 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
456 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
457 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
459 return self
._LoadFixAddress
461 ## Retrieve RFCLanguage filter
462 def _GetRFCLanguages(self
):
463 if self
._RFCLanguages
== None:
464 if self
._Header
== None:
465 self
._GetHeaderInfo
()
466 if self
._RFCLanguages
== None:
467 self
._RFCLanguages
= []
468 return self
._RFCLanguages
470 ## Retrieve ISOLanguage filter
471 def _GetISOLanguages(self
):
472 if self
._ISOLanguages
== None:
473 if self
._Header
== None:
474 self
._GetHeaderInfo
()
475 if self
._ISOLanguages
== None:
476 self
._ISOLanguages
= []
477 return self
._ISOLanguages
478 ## Retrieve the GUID string for VPD tool
479 def _GetVpdToolGuid(self
):
480 if self
._VpdToolGuid
== None:
481 if self
._Header
== None:
482 self
._GetHeaderInfo
()
483 if self
._VpdToolGuid
== None:
484 self
._VpdToolGuid
= ''
485 return self
._VpdToolGuid
487 ## Retrieve [SkuIds] section information
488 def _GetSkuIds(self
):
489 if self
._SkuIds
== None:
490 self
._SkuIds
= sdict()
491 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
492 for Record
in RecordList
:
493 if Record
[0] in [None, '']:
494 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
495 File
=self
.MetaFile
, Line
=Record
[-1])
496 if Record
[1] in [None, '']:
497 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
498 File
=self
.MetaFile
, Line
=Record
[-1])
499 self
._SkuIds
[Record
[1]] = Record
[0]
500 if 'DEFAULT' not in self
._SkuIds
:
501 self
._SkuIds
['DEFAULT'] = '0'
502 if 'COMMON' not in self
._SkuIds
:
503 self
._SkuIds
['COMMON'] = '0'
506 ## Retrieve [Components] section information
507 def _GetModules(self
):
508 if self
._Modules
!= None:
511 self
._Modules
= sdict()
512 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
513 Macros
= self
._Macros
514 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
515 for Record
in RecordList
:
516 DuplicatedFile
= False
517 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
521 # check the file validation
522 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
524 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
527 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
528 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
529 DuplicatedFile
= True
531 Module
= ModuleBuildClassObject()
532 Module
.MetaFile
= ModuleFile
534 # get module private library instance
535 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
536 for Record
in RecordList
:
537 LibraryClass
= Record
[0]
538 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
541 # check the file validation
542 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
544 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
547 if LibraryClass
== '' or LibraryClass
== 'NULL':
548 self
._NullLibraryNumber
+= 1
549 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
550 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
551 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
552 if LibraryPath
not in self
.LibraryInstances
:
553 self
.LibraryInstances
.append(LibraryPath
)
555 # get module private PCD setting
556 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
557 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
558 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
559 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
560 TokenList
= GetSplitValueList(Setting
)
561 DefaultValue
= TokenList
[0]
562 if len(TokenList
) > 1:
563 MaxDatumSize
= TokenList
[1]
566 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
567 Pcd
= PcdClassObject(
579 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
581 # get module private build options
582 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
583 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
584 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
585 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
587 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
588 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
590 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
591 if DuplicatedFile
and not RecordList
:
592 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
594 if len(RecordList
) != 1:
595 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
596 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
597 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
598 ModuleFile
.Arch
= self
._Arch
600 self
._Modules
[ModuleFile
] = Module
603 ## Retrieve all possible library instances used in this platform
604 def _GetLibraryInstances(self
):
605 if self
._LibraryInstances
== None:
606 self
._GetLibraryClasses
()
607 return self
._LibraryInstances
609 ## Retrieve [LibraryClasses] information
610 def _GetLibraryClasses(self
):
611 if self
._LibraryClasses
== None:
612 self
._LibraryInstances
= []
614 # tdict is a special dict kind of type, used for selecting correct
615 # library instance for given library class and module type
617 LibraryClassDict
= tdict(True, 3)
618 # track all library class names
619 LibraryClassSet
= set()
620 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
621 Macros
= self
._Macros
622 for Record
in RecordList
:
623 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
624 if LibraryClass
== '' or LibraryClass
== 'NULL':
625 self
._NullLibraryNumber
+= 1
626 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
627 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
628 LibraryClassSet
.add(LibraryClass
)
629 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
630 # check the file validation
631 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
633 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
636 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
637 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
638 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
639 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
640 if LibraryInstance
not in self
._LibraryInstances
:
641 self
._LibraryInstances
.append(LibraryInstance
)
643 # resolve the specific library instance for each class and each module type
644 self
._LibraryClasses
= tdict(True)
645 for LibraryClass
in LibraryClassSet
:
646 # try all possible module types
647 for ModuleType
in SUP_MODULE_LIST
:
648 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
649 if LibraryInstance
== None:
651 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
653 # for Edk style library instances, which are listed in different section
654 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
655 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
656 for Record
in RecordList
:
657 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
659 # check the file validation
660 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
662 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
664 if File
not in self
._LibraryInstances
:
665 self
._LibraryInstances
.append(File
)
667 # we need the module name as the library class name, so we have
668 # to parse it here. (self._Bdb[] will trigger a file parse if it
669 # hasn't been parsed)
671 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
672 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
673 return self
._LibraryClasses
675 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
676 if self
._DecPcds
== None:
677 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
679 if GlobalData
.gFdfParser
:
680 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
683 for Inf
in FdfInfList
:
684 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
685 if ModuleFile
in self
._Modules
:
687 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
688 PkgSet
.update(ModuleData
.Packages
)
692 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
693 self
._DecPcds
.update(DecPcds
)
695 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
696 EdkLogger
.error('build', PARSER_ERROR
,
697 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
698 File
=self
.MetaFile
, Line
=LineNo
)
699 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
700 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
701 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
702 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
703 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
705 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
706 except WrnExpression
, Value
:
707 ValueList
[Index
] = Value
.result
708 except EvaluationException
, Excpt
:
709 if hasattr(Excpt
, 'Pcd'):
710 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
711 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
712 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
713 " of the DSC file" % Excpt
.Pcd
,
714 File
=self
.MetaFile
, Line
=LineNo
)
716 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
717 File
=self
.MetaFile
, Line
=LineNo
)
719 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
720 File
=self
.MetaFile
, Line
=LineNo
)
721 if ValueList
[Index
] == 'True':
722 ValueList
[Index
] = '1'
723 elif ValueList
[Index
] == 'False':
724 ValueList
[Index
] = '0'
726 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
728 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
729 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
732 ## Retrieve all PCD settings in platform
734 if self
._Pcds
== None:
736 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
737 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
738 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
739 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
740 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
741 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
742 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
743 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
744 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
747 ## Retrieve [BuildOptions]
748 def _GetBuildOptions(self
):
749 if self
._BuildOptions
== None:
750 self
._BuildOptions
= sdict()
752 # Retrieve build option for EDKII style module
754 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
755 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
756 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
758 # Retrieve build option for EDK style module
760 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
761 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
762 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
763 return self
._BuildOptions
765 ## Retrieve non-dynamic PCD settings
767 # @param Type PCD type
769 # @retval a dict object contains settings of given PCD type
771 def _GetPcd(self
, Type
):
774 # tdict is a special dict kind of type, used for selecting correct
775 # PCD settings for certain ARCH
778 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
780 PcdDict
= tdict(True, 3)
782 # Find out all possible PCD candidates for self._Arch
783 RecordList
= self
._RawData
[Type
, self
._Arch
]
784 PcdValueDict
= sdict()
785 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
786 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
787 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
788 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
790 #handle pcd value override
791 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
792 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
795 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
796 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
797 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
799 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
801 PcdsKeys
= PcdValueDict
.keys()
802 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
804 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
808 if 'COMMON' in PcdSetting
:
809 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
810 if 'DEFAULT' in PcdSetting
:
811 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
812 if SkuObj
.SystemSkuId
in PcdSetting
:
813 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
815 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
818 self
._PCD
_TYPE
_STRING
_[Type
],
829 ## Retrieve dynamic PCD settings
831 # @param Type PCD type
833 # @retval a dict object contains settings of given PCD type
835 def _GetDynamicPcd(self
, Type
):
837 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
841 # tdict is a special dict kind of type, used for selecting correct
842 # PCD settings for certain ARCH and SKU
844 PcdDict
= tdict(True, 4)
846 # Find out all possible PCD candidates for self._Arch
847 RecordList
= self
._RawData
[Type
, self
._Arch
]
848 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
850 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
851 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
852 if SkuName
not in AvailableSkuIdSet
:
855 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
856 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
857 # Remove redundant PCD candidates, per the ARCH and SKU
858 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
860 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
864 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
865 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
866 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
867 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
868 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
869 if MaxDatumSize
.strip():
870 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
873 if pcdObject
.MaxDatumSize
:
874 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
877 if CurrentMaxSize
> PcdMaxSize
:
878 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
880 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
883 self
._PCD
_TYPE
_STRING
_[Type
],
893 for pcd
in Pcds
.values():
894 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
895 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
896 valuefromDec
= pcdDecObject
.DefaultValue
897 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
898 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
899 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
900 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
901 del(pcd
.SkuInfoList
['COMMON'])
902 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
903 del(pcd
.SkuInfoList
['COMMON'])
904 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
905 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
906 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
907 del(pcd
.SkuInfoList
['DEFAULT'])
911 def CompareVarAttr(self
, Attr1
, Attr2
):
912 if not Attr1
or not Attr2
: # for empty string
914 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
915 Attr1Set
= set(Attr1s
)
916 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
917 Attr2Set
= set(Attr2s
)
918 if Attr2Set
== Attr1Set
:
922 ## Retrieve dynamic HII PCD settings
924 # @param Type PCD type
926 # @retval a dict object contains settings of given PCD type
928 def _GetDynamicHiiPcd(self
, Type
):
930 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
935 # tdict is a special dict kind of type, used for selecting correct
936 # PCD settings for certain ARCH and SKU
938 PcdDict
= tdict(True, 4)
940 RecordList
= self
._RawData
[Type
, self
._Arch
]
941 # Find out all possible PCD candidates for self._Arch
942 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
944 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
945 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
946 if SkuName
not in AvailableSkuIdSet
:
948 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
949 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
950 # Remove redundant PCD candidates, per the ARCH and SKU
951 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
953 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
956 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
958 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
960 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
961 ExtraData
= "[%s]" % VarAttribute
)
964 if VariableOffset
.isdigit():
965 if int(VariableOffset
,10) > 0xFFFF:
967 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
968 if int(VariableOffset
,16) > 0xFFFF:
970 # For Offset written in "A.B"
971 elif VariableOffset
.find('.') > -1:
972 VariableOffsetList
= VariableOffset
.split(".")
973 if not (len(VariableOffsetList
) == 2
974 and IsValidWord(VariableOffsetList
[0])
975 and IsValidWord(VariableOffsetList
[1])):
976 FormatCorrect
= False
978 FormatCorrect
= False
979 if not FormatCorrect
:
980 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
983 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
984 if (VariableName
, VariableGuid
) not in VariableAttrs
:
985 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
987 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
988 EdkLogger
.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR
, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid
, VariableName
, VarAttribute
, VariableAttrs
[(VariableName
, VariableGuid
)]))
990 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
= VarAttribute
)
991 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
992 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
993 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
994 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
996 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
999 self
._PCD
_TYPE
_STRING
_[Type
],
1004 {SkuName
: SkuInfo
},
1007 pcdDecObject
.validateranges
,
1008 pcdDecObject
.validlists
,
1009 pcdDecObject
.expressions
1013 for pcd
in Pcds
.values():
1014 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1015 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1016 # Only fix the value while no value provided in DSC file.
1017 for sku
in pcd
.SkuInfoList
.values():
1018 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
1019 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1020 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1021 valuefromDec
= pcdDecObject
.DefaultValue
1022 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
1023 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1024 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1025 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1026 del(pcd
.SkuInfoList
['COMMON'])
1027 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1028 del(pcd
.SkuInfoList
['COMMON'])
1030 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1031 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1032 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1033 del(pcd
.SkuInfoList
['DEFAULT'])
1036 if pcd
.MaxDatumSize
.strip():
1037 MaxSize
= int(pcd
.MaxDatumSize
,0)
1040 if pcdDecObject
.DatumType
== 'VOID*':
1041 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1043 if skuobj
.HiiDefaultValue
.startswith("L"):
1044 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
1045 elif skuobj
.HiiDefaultValue
.startswith("{"):
1046 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1048 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
1051 pcd
.MaxDatumSize
= str(MaxSize
)
1054 ## Retrieve dynamic VPD PCD settings
1056 # @param Type PCD type
1058 # @retval a dict object contains settings of given PCD type
1060 def _GetDynamicVpdPcd(self
, Type
):
1062 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
1066 # tdict is a special dict kind of type, used for selecting correct
1067 # PCD settings for certain ARCH and SKU
1069 PcdDict
= tdict(True, 4)
1071 # Find out all possible PCD candidates for self._Arch
1072 RecordList
= self
._RawData
[Type
, self
._Arch
]
1073 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1075 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1076 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1077 if SkuName
not in AvailableSkuIdSet
:
1080 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1081 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1082 # Remove redundant PCD candidates, per the ARCH and SKU
1083 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1084 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1088 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1089 # For the Integer & Boolean type, the optional data can only be InitialValue.
1090 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1091 # until the DEC parser has been called.
1093 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1094 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1095 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1096 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1097 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1098 if MaxDatumSize
.strip():
1099 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1102 if pcdObject
.MaxDatumSize
:
1103 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1106 if CurrentMaxSize
> PcdMaxSize
:
1107 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1109 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1112 self
._PCD
_TYPE
_STRING
_[Type
],
1117 {SkuName
: SkuInfo
},
1121 for pcd
in Pcds
.values():
1122 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1123 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1124 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1125 valuefromDec
= pcdDecObject
.DefaultValue
1126 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1127 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1128 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1129 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1130 del(pcd
.SkuInfoList
['COMMON'])
1131 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1132 del(pcd
.SkuInfoList
['COMMON'])
1133 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1134 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1135 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1136 del(pcd
.SkuInfoList
['DEFAULT'])
1140 ## Add external modules
1142 # The external modules are mostly those listed in FDF file, which don't
1145 # @param FilePath The path of module description file
1147 def AddModule(self
, FilePath
):
1148 FilePath
= NormPath(FilePath
)
1149 if FilePath
not in self
.Modules
:
1150 Module
= ModuleBuildClassObject()
1151 Module
.MetaFile
= FilePath
1152 self
.Modules
.append(Module
)
1154 ## Add external PCDs
1156 # The external PCDs are mostly those listed in FDF file to specify address
1157 # or offset information.
1159 # @param Name Name of the PCD
1160 # @param Guid Token space guid of the PCD
1161 # @param Value Value of the PCD
1163 def AddPcd(self
, Name
, Guid
, Value
):
1164 if (Name
, Guid
) not in self
.Pcds
:
1165 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1166 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1168 _Macros
= property(_GetMacros
)
1169 Arch
= property(_GetArch
, _SetArch
)
1170 Platform
= property(_GetPlatformName
)
1171 PlatformName
= property(_GetPlatformName
)
1172 Guid
= property(_GetFileGuid
)
1173 Version
= property(_GetVersion
)
1174 DscSpecification
= property(_GetDscSpec
)
1175 OutputDirectory
= property(_GetOutpuDir
)
1176 SupArchList
= property(_GetSupArch
)
1177 BuildTargets
= property(_GetBuildTarget
)
1178 SkuName
= property(_GetSkuName
, _SetSkuName
)
1179 SkuIdentifier
= property(_GetSkuIdentifier
)
1180 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1181 VarCheckFlag
= property(_GetVarCheckFlag
)
1182 FlashDefinition
= property(_GetFdfFile
)
1183 BuildNumber
= property(_GetBuildNumber
)
1184 MakefileName
= property(_GetMakefileName
)
1185 BsBaseAddress
= property(_GetBsBaseAddress
)
1186 RtBaseAddress
= property(_GetRtBaseAddress
)
1187 LoadFixAddress
= property(_GetLoadFixAddress
)
1188 RFCLanguages
= property(_GetRFCLanguages
)
1189 ISOLanguages
= property(_GetISOLanguages
)
1190 VpdToolGuid
= property(_GetVpdToolGuid
)
1191 SkuIds
= property(_GetSkuIds
)
1192 Modules
= property(_GetModules
)
1193 LibraryInstances
= property(_GetLibraryInstances
)
1194 LibraryClasses
= property(_GetLibraryClasses
)
1195 Pcds
= property(_GetPcds
)
1196 BuildOptions
= property(_GetBuildOptions
)
1198 ## Platform build information from DEC file
1200 # This class is used to retrieve information stored in database and convert them
1201 # into PackageBuildClassObject form for easier use for AutoGen.
1203 class DecBuildData(PackageBuildClassObject
):
1204 # dict used to convert PCD type in database to string used by build tool
1205 _PCD_TYPE_STRING_
= {
1206 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1207 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1208 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1209 MODEL_PCD_DYNAMIC
: "Dynamic",
1210 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1211 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1212 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1213 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1214 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1215 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1216 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1219 # dict used to convert part of [Defines] to members of DecBuildData directly
1224 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1225 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1226 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1227 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1231 ## Constructor of DecBuildData
1233 # Initialize object of DecBuildData
1235 # @param FilePath The path of package description file
1236 # @param RawData The raw data of DEC file
1237 # @param BuildDataBase Database used to retrieve module information
1238 # @param Arch The target architecture
1239 # @param Platform (not used for DecBuildData)
1240 # @param Macros Macros used for replacement in DSC file
1242 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1243 self
.MetaFile
= File
1244 self
._PackageDir
= File
.Dir
1245 self
._RawData
= RawData
1246 self
._Bdb
= BuildDataBase
1248 self
._Target
= Target
1249 self
._Toolchain
= Toolchain
1253 def __setitem__(self
, key
, value
):
1254 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1257 def __getitem__(self
, key
):
1258 return self
.__dict
__[self
._PROPERTY
_[key
]]
1260 ## "in" test support
1261 def __contains__(self
, key
):
1262 return key
in self
._PROPERTY
_
1264 ## Set all internal used members of DecBuildData to None
1267 self
._PackageName
= None
1269 self
._Version
= None
1270 self
._PkgUniFile
= None
1271 self
._Protocols
= None
1274 self
._Includes
= None
1275 self
._LibraryClasses
= None
1277 self
.__Macros
= None
1279 ## Get current effective macros
1280 def _GetMacros(self
):
1281 if self
.__Macros
== None:
1283 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1284 return self
.__Macros
1292 # Changing the default ARCH to another may affect all other information
1293 # because all information in a platform may be ARCH-related. That's
1294 # why we need to clear all internal used members, in order to cause all
1295 # information to be re-retrieved.
1297 # @param Value The value of ARCH
1299 def _SetArch(self
, Value
):
1300 if self
._Arch
== Value
:
1305 ## Retrieve all information in [Defines] section
1307 # (Retriving all [Defines] information in one-shot is just to save time.)
1309 def _GetHeaderInfo(self
):
1310 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1311 for Record
in RecordList
:
1314 self
[Name
] = Record
[2]
1315 self
._Header
= 'DUMMY'
1317 ## Retrieve package name
1318 def _GetPackageName(self
):
1319 if self
._PackageName
== None:
1320 if self
._Header
== None:
1321 self
._GetHeaderInfo
()
1322 if self
._PackageName
== None:
1323 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1324 return self
._PackageName
1326 ## Retrieve file guid
1327 def _GetFileGuid(self
):
1328 if self
._Guid
== None:
1329 if self
._Header
== None:
1330 self
._GetHeaderInfo
()
1331 if self
._Guid
== None:
1332 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1335 ## Retrieve package version
1336 def _GetVersion(self
):
1337 if self
._Version
== None:
1338 if self
._Header
== None:
1339 self
._GetHeaderInfo
()
1340 if self
._Version
== None:
1342 return self
._Version
1344 ## Retrieve protocol definitions (name/value pairs)
1345 def _GetProtocol(self
):
1346 if self
._Protocols
== None:
1348 # tdict is a special kind of dict, used for selecting correct
1349 # protocol defition for given ARCH
1351 ProtocolDict
= tdict(True)
1353 # find out all protocol definitions for specific and 'common' arch
1354 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1355 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1356 if Name
not in NameList
:
1357 NameList
.append(Name
)
1358 ProtocolDict
[Arch
, Name
] = Guid
1359 # use sdict to keep the order
1360 self
._Protocols
= sdict()
1361 for Name
in NameList
:
1363 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1364 # will automatically turn to 'common' ARCH for trying
1366 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1367 return self
._Protocols
1369 ## Retrieve PPI definitions (name/value pairs)
1371 if self
._Ppis
== None:
1373 # tdict is a special kind of dict, used for selecting correct
1374 # PPI defition for given ARCH
1376 PpiDict
= tdict(True)
1378 # find out all PPI definitions for specific arch and 'common' arch
1379 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1380 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1381 if Name
not in NameList
:
1382 NameList
.append(Name
)
1383 PpiDict
[Arch
, Name
] = Guid
1384 # use sdict to keep the order
1385 self
._Ppis
= sdict()
1386 for Name
in NameList
:
1388 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1389 # will automatically turn to 'common' ARCH for trying
1391 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1394 ## Retrieve GUID definitions (name/value pairs)
1396 if self
._Guids
== None:
1398 # tdict is a special kind of dict, used for selecting correct
1399 # GUID defition for given ARCH
1401 GuidDict
= tdict(True)
1403 # find out all protocol definitions for specific and 'common' arch
1404 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1405 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1406 if Name
not in NameList
:
1407 NameList
.append(Name
)
1408 GuidDict
[Arch
, Name
] = Guid
1409 # use sdict to keep the order
1410 self
._Guids
= sdict()
1411 for Name
in NameList
:
1413 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1414 # will automatically turn to 'common' ARCH for trying
1416 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1419 ## Retrieve public include paths declared in this package
1420 def _GetInclude(self
):
1421 if self
._Includes
== None:
1423 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1424 Macros
= self
._Macros
1425 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1426 for Record
in RecordList
:
1427 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1430 ErrorCode
, ErrorInfo
= File
.Validate()
1432 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1434 # avoid duplicate include path
1435 if File
not in self
._Includes
:
1436 self
._Includes
.append(File
)
1437 return self
._Includes
1439 ## Retrieve library class declarations (not used in build at present)
1440 def _GetLibraryClass(self
):
1441 if self
._LibraryClasses
== None:
1443 # tdict is a special kind of dict, used for selecting correct
1444 # library class declaration for given ARCH
1446 LibraryClassDict
= tdict(True)
1447 LibraryClassSet
= set()
1448 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1449 Macros
= self
._Macros
1450 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1451 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1452 # check the file validation
1453 ErrorCode
, ErrorInfo
= File
.Validate()
1455 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1456 LibraryClassSet
.add(LibraryClass
)
1457 LibraryClassDict
[Arch
, LibraryClass
] = File
1458 self
._LibraryClasses
= sdict()
1459 for LibraryClass
in LibraryClassSet
:
1460 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1461 return self
._LibraryClasses
1463 ## Retrieve PCD declarations
1465 if self
._Pcds
== None:
1466 self
._Pcds
= sdict()
1467 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1468 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1469 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1470 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1471 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1474 ## Retrieve PCD declarations for given type
1475 def _GetPcd(self
, Type
):
1478 # tdict is a special kind of dict, used for selecting correct
1479 # PCD declaration for given ARCH
1481 PcdDict
= tdict(True, 3)
1482 # for summarizing PCD
1484 # find out all PCDs of the 'type'
1485 RecordList
= self
._RawData
[Type
, self
._Arch
]
1486 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1487 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1488 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1490 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1492 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1493 # will automatically turn to 'common' ARCH and try again
1495 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1499 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1501 validateranges
, validlists
, expressions
= self
._RawData
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
1502 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1505 self
._PCD
_TYPE
_STRING
_[Type
],
1513 list(validateranges
),
1520 _Macros
= property(_GetMacros
)
1521 Arch
= property(_GetArch
, _SetArch
)
1522 PackageName
= property(_GetPackageName
)
1523 Guid
= property(_GetFileGuid
)
1524 Version
= property(_GetVersion
)
1526 Protocols
= property(_GetProtocol
)
1527 Ppis
= property(_GetPpi
)
1528 Guids
= property(_GetGuid
)
1529 Includes
= property(_GetInclude
)
1530 LibraryClasses
= property(_GetLibraryClass
)
1531 Pcds
= property(_GetPcds
)
1533 ## Module build information from INF file
1535 # This class is used to retrieve information stored in database and convert them
1536 # into ModuleBuildClassObject form for easier use for AutoGen.
1538 class InfBuildData(ModuleBuildClassObject
):
1539 # dict used to convert PCD type in database to string used by build tool
1540 _PCD_TYPE_STRING_
= {
1541 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1542 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1543 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1544 MODEL_PCD_DYNAMIC
: "Dynamic",
1545 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1546 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1547 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1548 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1549 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1550 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1551 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1554 # dict used to convert part of [Defines] to members of InfBuildData directly
1559 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1560 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1561 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1565 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1566 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1567 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1568 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1569 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1570 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1571 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1572 TAB_INF_DEFINES_VERSION
: "_Version",
1573 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1574 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1576 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1579 # dict used to convert Component type to Module type
1582 "SECURITY_CORE" : "SEC",
1583 "PEI_CORE" : "PEI_CORE",
1584 "COMBINED_PEIM_DRIVER" : "PEIM",
1585 "PIC_PEIM" : "PEIM",
1586 "RELOCATABLE_PEIM" : "PEIM",
1587 "PE32_PEIM" : "PEIM",
1588 "BS_DRIVER" : "DXE_DRIVER",
1589 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1590 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1591 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1592 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1593 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1594 # "BS_DRIVER" : "UEFI_DRIVER",
1595 "APPLICATION" : "UEFI_APPLICATION",
1599 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1600 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1601 # dict used to convert old tool name used in [nmake] section to new ones
1609 ## Constructor of DscBuildData
1611 # Initialize object of DscBuildData
1613 # @param FilePath The path of platform description file
1614 # @param RawData The raw data of DSC file
1615 # @param BuildDataBase Database used to retrieve module/package information
1616 # @param Arch The target architecture
1617 # @param Platform The name of platform employing this module
1618 # @param Macros Macros used for replacement in DSC file
1620 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1621 self
.MetaFile
= FilePath
1622 self
._ModuleDir
= FilePath
.Dir
1623 self
._RawData
= RawData
1624 self
._Bdb
= BuildDatabase
1626 self
._Target
= Target
1627 self
._Toolchain
= Toolchain
1628 self
._Platform
= 'COMMON'
1629 self
._SourceOverridePath
= None
1630 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1631 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1635 def __setitem__(self
, key
, value
):
1636 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1639 def __getitem__(self
, key
):
1640 return self
.__dict
__[self
._PROPERTY
_[key
]]
1642 ## "in" test support
1643 def __contains__(self
, key
):
1644 return key
in self
._PROPERTY
_
1646 ## Set all internal used members of InfBuildData to None
1648 self
._HeaderComments
= None
1649 self
._TailComments
= None
1650 self
._Header
_ = None
1651 self
._AutoGenVersion
= None
1652 self
._BaseName
= None
1653 self
._DxsFile
= None
1654 self
._ModuleType
= None
1655 self
._ComponentType
= None
1656 self
._BuildType
= None
1658 self
._Version
= None
1659 self
._PcdIsDriver
= None
1660 self
._BinaryModule
= None
1662 self
._MakefileName
= None
1663 self
._CustomMakefile
= None
1664 self
._Specification
= None
1665 self
._LibraryClass
= None
1666 self
._ModuleEntryPointList
= None
1667 self
._ModuleUnloadImageList
= None
1668 self
._ConstructorList
= None
1669 self
._DestructorList
= None
1671 self
._Binaries
= None
1672 self
._Sources
= None
1673 self
._LibraryClasses
= None
1674 self
._Libraries
= None
1675 self
._Protocols
= None
1676 self
._ProtocolComments
= None
1678 self
._PpiComments
= None
1680 self
._GuidsUsedByPcd
= sdict()
1681 self
._GuidComments
= None
1682 self
._Includes
= None
1683 self
._Packages
= None
1685 self
._PcdComments
= None
1686 self
._BuildOptions
= None
1688 self
._DepexExpression
= None
1689 self
.__Macros
= None
1691 ## Get current effective macros
1692 def _GetMacros(self
):
1693 if self
.__Macros
== None:
1695 # EDK_GLOBAL defined macros can be applied to EDK module
1696 if self
.AutoGenVersion
< 0x00010005:
1697 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1698 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1699 return self
.__Macros
1707 # Changing the default ARCH to another may affect all other information
1708 # because all information in a platform may be ARCH-related. That's
1709 # why we need to clear all internal used members, in order to cause all
1710 # information to be re-retrieved.
1712 # @param Value The value of ARCH
1714 def _SetArch(self
, Value
):
1715 if self
._Arch
== Value
:
1720 ## Return the name of platform employing this module
1721 def _GetPlatform(self
):
1722 return self
._Platform
1724 ## Change the name of platform employing this module
1726 # Changing the default name of platform to another may affect some information
1727 # because they may be PLATFORM-related. That's why we need to clear all internal
1728 # used members, in order to cause all information to be re-retrieved.
1730 def _SetPlatform(self
, Value
):
1731 if self
._Platform
== Value
:
1733 self
._Platform
= Value
1735 def _GetHeaderComments(self
):
1736 if not self
._HeaderComments
:
1737 self
._HeaderComments
= []
1738 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1739 for Record
in RecordList
:
1740 self
._HeaderComments
.append(Record
[0])
1741 return self
._HeaderComments
1742 def _GetTailComments(self
):
1743 if not self
._TailComments
:
1744 self
._TailComments
= []
1745 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1746 for Record
in RecordList
:
1747 self
._TailComments
.append(Record
[0])
1748 return self
._TailComments
1749 ## Retrieve all information in [Defines] section
1751 # (Retriving all [Defines] information in one-shot is just to save time.)
1753 def _GetHeaderInfo(self
):
1754 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1755 for Record
in RecordList
:
1756 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1757 # items defined _PROPERTY_ don't need additional processing
1760 if self
._Defs
== None:
1761 self
._Defs
= sdict()
1762 self
._Defs
[Name
] = Value
1763 # some special items in [Defines] section need special treatment
1764 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1765 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1766 Name
= 'UEFI_SPECIFICATION_VERSION'
1767 if self
._Specification
== None:
1768 self
._Specification
= sdict()
1769 self
._Specification
[Name
] = GetHexVerValue(Value
)
1770 if self
._Specification
[Name
] == None:
1771 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1772 "'%s' format is not supported for %s" % (Value
, Name
),
1773 File
=self
.MetaFile
, Line
=Record
[-1])
1774 elif Name
== 'LIBRARY_CLASS':
1775 if self
._LibraryClass
== None:
1776 self
._LibraryClass
= []
1777 ValueList
= GetSplitValueList(Value
)
1778 LibraryClass
= ValueList
[0]
1779 if len(ValueList
) > 1:
1780 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1782 SupModuleList
= SUP_MODULE_LIST
1783 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1784 elif Name
== 'ENTRY_POINT':
1785 if self
._ModuleEntryPointList
== None:
1786 self
._ModuleEntryPointList
= []
1787 self
._ModuleEntryPointList
.append(Value
)
1788 elif Name
== 'UNLOAD_IMAGE':
1789 if self
._ModuleUnloadImageList
== None:
1790 self
._ModuleUnloadImageList
= []
1793 self
._ModuleUnloadImageList
.append(Value
)
1794 elif Name
== 'CONSTRUCTOR':
1795 if self
._ConstructorList
== None:
1796 self
._ConstructorList
= []
1799 self
._ConstructorList
.append(Value
)
1800 elif Name
== 'DESTRUCTOR':
1801 if self
._DestructorList
== None:
1802 self
._DestructorList
= []
1805 self
._DestructorList
.append(Value
)
1806 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1807 TokenList
= GetSplitValueList(Value
)
1808 if self
._CustomMakefile
== None:
1809 self
._CustomMakefile
= {}
1810 if len(TokenList
) < 2:
1811 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1812 self
._CustomMakefile
['GCC'] = TokenList
[0]
1814 if TokenList
[0] not in ['MSFT', 'GCC']:
1815 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1816 "No supported family [%s]" % TokenList
[0],
1817 File
=self
.MetaFile
, Line
=Record
[-1])
1818 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1820 if self
._Defs
== None:
1821 self
._Defs
= sdict()
1822 self
._Defs
[Name
] = Value
1825 # Retrieve information in sections specific to Edk.x modules
1827 if self
.AutoGenVersion
>= 0x00010005:
1828 if not self
._ModuleType
:
1829 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1830 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1831 if self
._ModuleType
not in SUP_MODULE_LIST
:
1832 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1833 for Record
in RecordList
:
1835 if Name
== "MODULE_TYPE":
1838 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1839 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1840 File
=self
.MetaFile
, Line
=LineNo
)
1841 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1842 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1843 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
)
1844 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1845 and 'PCI_CLASS_CODE' in self
._Defs
:
1846 self
._BuildType
= 'UEFI_OPTIONROM'
1847 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1848 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1849 self
._BuildType
= 'UEFI_HII'
1851 self
._BuildType
= self
._ModuleType
.upper()
1854 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1855 # check the file validation
1856 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1858 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1859 File
=self
.MetaFile
, Line
=LineNo
)
1860 if self
.Sources
== None:
1862 self
._Sources
.append(File
)
1864 if not self
._ComponentType
:
1865 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1866 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1867 self
._BuildType
= self
._ComponentType
.upper()
1868 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1869 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1870 if self
._ComponentType
== 'LIBRARY':
1871 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1872 # make use some [nmake] section macros
1873 Macros
= self
._Macros
1874 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1875 Macros
['PROCESSOR'] = self
._Arch
1876 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1877 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1878 Value
= ReplaceMacro(Value
, Macros
, True)
1879 if Name
== "IMAGE_ENTRY_POINT":
1880 if self
._ModuleEntryPointList
== None:
1881 self
._ModuleEntryPointList
= []
1882 self
._ModuleEntryPointList
.append(Value
)
1883 elif Name
== "DPX_SOURCE":
1884 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1885 # check the file validation
1886 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1888 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1889 File
=self
.MetaFile
, Line
=LineNo
)
1890 if self
.Sources
== None:
1892 self
._Sources
.append(File
)
1894 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1895 if len(ToolList
) == 0 or len(ToolList
) != 1:
1897 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1898 # File=self.MetaFile, Line=LineNo)
1900 if self
._BuildOptions
== None:
1901 self
._BuildOptions
= sdict()
1903 if ToolList
[0] in self
._TOOL
_CODE
_:
1904 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1907 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1908 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1909 #ignore not replaced macros in value
1910 ValueList
= GetSplitList(' ' + Value
, '/D')
1911 Dummy
= ValueList
[0]
1912 for Index
in range(1, len(ValueList
)):
1913 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1915 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1916 Value
= Dummy
.strip()
1917 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1918 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1920 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1921 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1922 # set _Header to non-None in order to avoid database re-querying
1923 self
._Header
_ = 'DUMMY'
1925 ## Retrieve file version
1926 def _GetInfVersion(self
):
1927 if self
._AutoGenVersion
== None:
1928 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1929 for Record
in RecordList
:
1930 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1931 self
._AutoGenVersion
= int(Record
[2], 0)
1933 if self
._AutoGenVersion
== None:
1934 self
._AutoGenVersion
= 0x00010000
1935 return self
._AutoGenVersion
1937 ## Retrieve BASE_NAME
1938 def _GetBaseName(self
):
1939 if self
._BaseName
== None:
1940 if self
._Header
_ == None:
1941 self
._GetHeaderInfo
()
1942 if self
._BaseName
== None:
1943 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1944 return self
._BaseName
1947 def _GetDxsFile(self
):
1948 if self
._DxsFile
== None:
1949 if self
._Header
_ == None:
1950 self
._GetHeaderInfo
()
1951 if self
._DxsFile
== None:
1953 return self
._DxsFile
1955 ## Retrieve MODULE_TYPE
1956 def _GetModuleType(self
):
1957 if self
._ModuleType
== None:
1958 if self
._Header
_ == None:
1959 self
._GetHeaderInfo
()
1960 if self
._ModuleType
== None:
1961 self
._ModuleType
= 'BASE'
1962 if self
._ModuleType
not in SUP_MODULE_LIST
:
1963 self
._ModuleType
= "USER_DEFINED"
1964 return self
._ModuleType
1966 ## Retrieve COMPONENT_TYPE
1967 def _GetComponentType(self
):
1968 if self
._ComponentType
== None:
1969 if self
._Header
_ == None:
1970 self
._GetHeaderInfo
()
1971 if self
._ComponentType
== None:
1972 self
._ComponentType
= 'USER_DEFINED'
1973 return self
._ComponentType
1975 ## Retrieve "BUILD_TYPE"
1976 def _GetBuildType(self
):
1977 if self
._BuildType
== None:
1978 if self
._Header
_ == None:
1979 self
._GetHeaderInfo
()
1980 if not self
._BuildType
:
1981 self
._BuildType
= "BASE"
1982 return self
._BuildType
1984 ## Retrieve file guid
1985 def _GetFileGuid(self
):
1986 if self
._Guid
== None:
1987 if self
._Header
_ == None:
1988 self
._GetHeaderInfo
()
1989 if self
._Guid
== None:
1990 self
._Guid
= '00000000-0000-0000-000000000000'
1993 ## Retrieve module version
1994 def _GetVersion(self
):
1995 if self
._Version
== None:
1996 if self
._Header
_ == None:
1997 self
._GetHeaderInfo
()
1998 if self
._Version
== None:
1999 self
._Version
= '0.0'
2000 return self
._Version
2002 ## Retrieve PCD_IS_DRIVER
2003 def _GetPcdIsDriver(self
):
2004 if self
._PcdIsDriver
== None:
2005 if self
._Header
_ == None:
2006 self
._GetHeaderInfo
()
2007 if self
._PcdIsDriver
== None:
2008 self
._PcdIsDriver
= ''
2009 return self
._PcdIsDriver
2012 def _GetShadow(self
):
2013 if self
._Shadow
== None:
2014 if self
._Header
_ == None:
2015 self
._GetHeaderInfo
()
2016 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
2019 self
._Shadow
= False
2022 ## Retrieve CUSTOM_MAKEFILE
2023 def _GetMakefile(self
):
2024 if self
._CustomMakefile
== None:
2025 if self
._Header
_ == None:
2026 self
._GetHeaderInfo
()
2027 if self
._CustomMakefile
== None:
2028 self
._CustomMakefile
= {}
2029 return self
._CustomMakefile
2031 ## Retrieve EFI_SPECIFICATION_VERSION
2033 if self
._Specification
== None:
2034 if self
._Header
_ == None:
2035 self
._GetHeaderInfo
()
2036 if self
._Specification
== None:
2037 self
._Specification
= {}
2038 return self
._Specification
2040 ## Retrieve LIBRARY_CLASS
2041 def _GetLibraryClass(self
):
2042 if self
._LibraryClass
== None:
2043 if self
._Header
_ == None:
2044 self
._GetHeaderInfo
()
2045 if self
._LibraryClass
== None:
2046 self
._LibraryClass
= []
2047 return self
._LibraryClass
2049 ## Retrieve ENTRY_POINT
2050 def _GetEntryPoint(self
):
2051 if self
._ModuleEntryPointList
== None:
2052 if self
._Header
_ == None:
2053 self
._GetHeaderInfo
()
2054 if self
._ModuleEntryPointList
== None:
2055 self
._ModuleEntryPointList
= []
2056 return self
._ModuleEntryPointList
2058 ## Retrieve UNLOAD_IMAGE
2059 def _GetUnloadImage(self
):
2060 if self
._ModuleUnloadImageList
== None:
2061 if self
._Header
_ == None:
2062 self
._GetHeaderInfo
()
2063 if self
._ModuleUnloadImageList
== None:
2064 self
._ModuleUnloadImageList
= []
2065 return self
._ModuleUnloadImageList
2067 ## Retrieve CONSTRUCTOR
2068 def _GetConstructor(self
):
2069 if self
._ConstructorList
== None:
2070 if self
._Header
_ == None:
2071 self
._GetHeaderInfo
()
2072 if self
._ConstructorList
== None:
2073 self
._ConstructorList
= []
2074 return self
._ConstructorList
2076 ## Retrieve DESTRUCTOR
2077 def _GetDestructor(self
):
2078 if self
._DestructorList
== None:
2079 if self
._Header
_ == None:
2080 self
._GetHeaderInfo
()
2081 if self
._DestructorList
== None:
2082 self
._DestructorList
= []
2083 return self
._DestructorList
2085 ## Retrieve definies other than above ones
2086 def _GetDefines(self
):
2087 if self
._Defs
== None:
2088 if self
._Header
_ == None:
2089 self
._GetHeaderInfo
()
2090 if self
._Defs
== None:
2091 self
._Defs
= sdict()
2094 ## Retrieve binary files
2095 def _GetBinaries(self
):
2096 if self
._Binaries
== None:
2098 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2099 Macros
= self
._Macros
2100 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2101 Macros
['PROCESSOR'] = self
._Arch
2102 for Record
in RecordList
:
2103 FileType
= Record
[0]
2108 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2110 Target
= TokenList
[0]
2111 if len(TokenList
) > 1:
2112 FeatureFlag
= Record
[1:]
2114 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2115 # check the file validation
2116 ErrorCode
, ErrorInfo
= File
.Validate()
2118 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2119 self
._Binaries
.append(File
)
2120 return self
._Binaries
2122 ## Retrieve binary files with error check.
2123 def _GetBinaryFiles(self
):
2124 Binaries
= self
._GetBinaries
()
2125 if GlobalData
.gIgnoreSource
and Binaries
== []:
2126 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2127 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2130 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2131 def _IsSupportedArch(self
):
2132 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2136 ## Retrieve source files
2137 def _GetSourceFiles(self
):
2138 #Ignore all source files in a binary build mode
2139 if GlobalData
.gIgnoreSource
:
2141 return self
._Sources
2143 if self
._Sources
== None:
2145 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2146 Macros
= self
._Macros
2147 for Record
in RecordList
:
2149 ToolChainFamily
= Record
[1]
2151 ToolCode
= Record
[3]
2152 FeatureFlag
= Record
[4]
2153 if self
.AutoGenVersion
< 0x00010005:
2154 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2155 Macros
['PROCESSOR'] = self
._Arch
2156 # old module source files (Edk)
2157 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
2158 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2159 # check the file validation
2160 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2162 if File
.Ext
.lower() == '.h':
2163 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2164 File
=self
.MetaFile
, Line
=LineNo
)
2167 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2169 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2170 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2171 # check the file validation
2172 ErrorCode
, ErrorInfo
= File
.Validate()
2174 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2176 self
._Sources
.append(File
)
2177 return self
._Sources
2179 ## Retrieve library classes employed by this module
2180 def _GetLibraryClassUses(self
):
2181 if self
._LibraryClasses
== None:
2182 self
._LibraryClasses
= sdict()
2183 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2184 for Record
in RecordList
:
2186 Instance
= Record
[1]
2188 Instance
= NormPath(Instance
, self
._Macros
)
2189 self
._LibraryClasses
[Lib
] = Instance
2190 return self
._LibraryClasses
2192 ## Retrieve library names (for Edk.x style of modules)
2193 def _GetLibraryNames(self
):
2194 if self
._Libraries
== None:
2195 self
._Libraries
= []
2196 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2197 for Record
in RecordList
:
2198 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2199 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2200 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2201 if LibraryName
not in self
._Libraries
:
2202 self
._Libraries
.append(LibraryName
)
2203 return self
._Libraries
2205 def _GetProtocolComments(self
):
2206 self
._GetProtocols
()
2207 return self
._ProtocolComments
2208 ## Retrieve protocols consumed/produced by this module
2209 def _GetProtocols(self
):
2210 if self
._Protocols
== None:
2211 self
._Protocols
= sdict()
2212 self
._ProtocolComments
= sdict()
2213 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2214 for Record
in RecordList
:
2216 Value
= ProtocolValue(CName
, self
.Packages
)
2218 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2219 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2220 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2221 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2222 self
._Protocols
[CName
] = Value
2223 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2225 for CmtRec
in CommentRecords
:
2226 Comments
.append(CmtRec
[0])
2227 self
._ProtocolComments
[CName
] = Comments
2228 return self
._Protocols
2230 def _GetPpiComments(self
):
2232 return self
._PpiComments
2233 ## Retrieve PPIs consumed/produced by this module
2235 if self
._Ppis
== None:
2236 self
._Ppis
= sdict()
2237 self
._PpiComments
= sdict()
2238 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2239 for Record
in RecordList
:
2241 Value
= PpiValue(CName
, self
.Packages
)
2243 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2244 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2245 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2246 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2247 self
._Ppis
[CName
] = Value
2248 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2250 for CmtRec
in CommentRecords
:
2251 Comments
.append(CmtRec
[0])
2252 self
._PpiComments
[CName
] = Comments
2255 def _GetGuidComments(self
):
2257 return self
._GuidComments
2258 ## Retrieve GUIDs consumed/produced by this module
2259 def _GetGuids(self
):
2260 if self
._Guids
== None:
2261 self
._Guids
= sdict()
2262 self
._GuidComments
= sdict()
2263 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2264 for Record
in RecordList
:
2266 Value
= GuidValue(CName
, self
.Packages
)
2268 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2269 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2270 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2271 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2272 self
._Guids
[CName
] = Value
2273 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2275 for CmtRec
in CommentRecords
:
2276 Comments
.append(CmtRec
[0])
2277 self
._GuidComments
[CName
] = Comments
2280 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2281 def _GetIncludes(self
):
2282 if self
._Includes
== None:
2284 if self
._SourceOverridePath
:
2285 self
._Includes
.append(self
._SourceOverridePath
)
2287 Macros
= self
._Macros
2288 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2289 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2291 Macros
['PROCESSOR'] = self
._Arch
2292 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2293 for Record
in RecordList
:
2294 if Record
[0].find('EDK_SOURCE') > -1:
2295 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2296 File
= NormPath(Record
[0], self
._Macros
)
2298 File
= os
.path
.join(self
._ModuleDir
, File
)
2300 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2301 File
= RealPath(os
.path
.normpath(File
))
2303 self
._Includes
.append(File
)
2305 #TRICK: let compiler to choose correct header file
2306 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2307 File
= NormPath(Record
[0], self
._Macros
)
2309 File
= os
.path
.join(self
._ModuleDir
, File
)
2311 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2312 File
= RealPath(os
.path
.normpath(File
))
2314 self
._Includes
.append(File
)
2316 File
= NormPath(Record
[0], Macros
)
2318 File
= os
.path
.join(self
._ModuleDir
, File
)
2320 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2321 File
= RealPath(os
.path
.normpath(File
))
2323 self
._Includes
.append(File
)
2324 return self
._Includes
2326 ## Retrieve packages this module depends on
2327 def _GetPackages(self
):
2328 if self
._Packages
== None:
2330 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2331 Macros
= self
._Macros
2332 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2333 for Record
in RecordList
:
2334 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2336 # check the file validation
2337 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2339 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2340 # parse this package now. we need it to get protocol/ppi/guid value
2341 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2342 self
._Packages
.append(Package
)
2343 return self
._Packages
2345 ## Retrieve PCD comments
2346 def _GetPcdComments(self
):
2348 return self
._PcdComments
2349 ## Retrieve PCDs used in this module
2351 if self
._Pcds
== None:
2352 self
._Pcds
= sdict()
2353 self
._PcdComments
= sdict()
2354 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2355 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2356 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2357 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2358 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2361 ## Retrieve build options specific to this module
2362 def _GetBuildOptions(self
):
2363 if self
._BuildOptions
== None:
2364 self
._BuildOptions
= sdict()
2365 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2366 for Record
in RecordList
:
2367 ToolChainFamily
= Record
[0]
2368 ToolChain
= Record
[1]
2370 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2371 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2373 # concatenate the option string if they're for the same tool
2374 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2375 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2376 return self
._BuildOptions
2378 ## Retrieve dependency expression
2379 def _GetDepex(self
):
2380 if self
._Depex
== None:
2381 self
._Depex
= tdict(False, 2)
2382 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2384 # If the module has only Binaries and no Sources, then ignore [Depex]
2385 if self
.Sources
== None or self
.Sources
== []:
2386 if self
.Binaries
!= None and self
.Binaries
!= []:
2389 # PEIM and DXE drivers must have a valid [Depex] section
2390 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2391 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2392 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2393 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2394 % self
.ModuleType
, File
=self
.MetaFile
)
2396 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2397 for Record
in RecordList
:
2398 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2399 EdkLogger
.error('build', FORMAT_INVALID
,
2400 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2404 for Record
in RecordList
:
2405 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2407 ModuleType
= Record
[4]
2408 TokenList
= DepexStr
.split()
2409 if (Arch
, ModuleType
) not in Depex
:
2410 Depex
[Arch
, ModuleType
] = []
2411 DepexList
= Depex
[Arch
, ModuleType
]
2412 for Token
in TokenList
:
2413 if Token
in DEPEX_SUPPORTED_OPCODE
:
2414 DepexList
.append(Token
)
2415 elif Token
.endswith(".inf"): # module file name
2416 ModuleFile
= os
.path
.normpath(Token
)
2417 Module
= self
.BuildDatabase
[ModuleFile
]
2419 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2420 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2421 DepexList
.append(Module
.Guid
)
2423 # get the GUID value now
2424 Value
= ProtocolValue(Token
, self
.Packages
)
2426 Value
= PpiValue(Token
, self
.Packages
)
2428 Value
= GuidValue(Token
, self
.Packages
)
2430 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2431 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2432 "Value of [%s] is not found in" % Token
,
2433 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2434 DepexList
.append(Value
)
2435 for Arch
, ModuleType
in Depex
:
2436 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2439 ## Retrieve depedency expression
2440 def _GetDepexExpression(self
):
2441 if self
._DepexExpression
== None:
2442 self
._DepexExpression
= tdict(False, 2)
2443 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2444 DepexExpression
= sdict()
2445 for Record
in RecordList
:
2446 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2448 ModuleType
= Record
[4]
2449 TokenList
= DepexStr
.split()
2450 if (Arch
, ModuleType
) not in DepexExpression
:
2451 DepexExpression
[Arch
, ModuleType
] = ''
2452 for Token
in TokenList
:
2453 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2454 for Arch
, ModuleType
in DepexExpression
:
2455 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2456 return self
._DepexExpression
2458 def GetGuidsUsedByPcd(self
):
2459 return self
._GuidsUsedByPcd
2460 ## Retrieve PCD for given type
2461 def _GetPcd(self
, Type
):
2463 PcdDict
= tdict(True, 4)
2465 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2466 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2467 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2468 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2469 # get the guid value
2470 if TokenSpaceGuid
not in self
.Guids
:
2471 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2473 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2474 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2475 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2476 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2477 self
.Guids
[TokenSpaceGuid
] = Value
2478 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2479 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2481 for CmtRec
in CommentRecords
:
2482 Comments
.append(CmtRec
[0])
2483 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2485 # resolve PCD type, value, datum info, etc. by getting its definition from package
2486 for PcdCName
, TokenSpaceGuid
in PcdList
:
2487 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2490 ValueList
= AnalyzePcdData(Setting
)
2491 DefaultValue
= ValueList
[0]
2492 Pcd
= PcdClassObject(
2502 self
.Guids
[TokenSpaceGuid
]
2504 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2505 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2506 Pcd
.Offset
= ValueList
[1]
2508 # get necessary info from package declaring this PCD
2509 for Package
in self
.Packages
:
2511 # 'dynamic' in INF means its type is determined by platform;
2512 # if platform doesn't give its type, use 'lowest' one in the
2513 # following order, if any
2515 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2517 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2518 if Type
== MODEL_PCD_DYNAMIC
:
2520 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2521 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2527 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2528 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2530 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2533 # Check whether the token value exist or not.
2535 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2539 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2540 File
=self
.MetaFile
, Line
=LineNo
,
2544 # Check hexadecimal token value length and format.
2546 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2547 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2548 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2552 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2553 File
=self
.MetaFile
, Line
=LineNo
,
2558 # Check decimal token value length and format.
2562 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2563 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2567 "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
)),
2568 File
=self
.MetaFile
, Line
=LineNo
,
2575 "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
)),
2576 File
=self
.MetaFile
, Line
=LineNo
,
2580 Pcd
.DatumType
= PcdInPackage
.DatumType
2581 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2582 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2583 if Pcd
.DefaultValue
in [None, '']:
2584 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2590 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2591 File
=self
.MetaFile
, Line
=LineNo
,
2592 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2594 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2598 ## check whether current module is binary module
2599 def _IsBinaryModule(self
):
2600 if self
.Binaries
and not self
.Sources
:
2602 elif GlobalData
.gIgnoreSource
:
2607 _Macros
= property(_GetMacros
)
2608 Arch
= property(_GetArch
, _SetArch
)
2609 Platform
= property(_GetPlatform
, _SetPlatform
)
2611 HeaderComments
= property(_GetHeaderComments
)
2612 TailComments
= property(_GetTailComments
)
2613 AutoGenVersion
= property(_GetInfVersion
)
2614 BaseName
= property(_GetBaseName
)
2615 ModuleType
= property(_GetModuleType
)
2616 ComponentType
= property(_GetComponentType
)
2617 BuildType
= property(_GetBuildType
)
2618 Guid
= property(_GetFileGuid
)
2619 Version
= property(_GetVersion
)
2620 PcdIsDriver
= property(_GetPcdIsDriver
)
2621 Shadow
= property(_GetShadow
)
2622 CustomMakefile
= property(_GetMakefile
)
2623 Specification
= property(_GetSpec
)
2624 LibraryClass
= property(_GetLibraryClass
)
2625 ModuleEntryPointList
= property(_GetEntryPoint
)
2626 ModuleUnloadImageList
= property(_GetUnloadImage
)
2627 ConstructorList
= property(_GetConstructor
)
2628 DestructorList
= property(_GetDestructor
)
2629 Defines
= property(_GetDefines
)
2630 DxsFile
= property(_GetDxsFile
)
2632 Binaries
= property(_GetBinaryFiles
)
2633 Sources
= property(_GetSourceFiles
)
2634 LibraryClasses
= property(_GetLibraryClassUses
)
2635 Libraries
= property(_GetLibraryNames
)
2636 Protocols
= property(_GetProtocols
)
2637 ProtocolComments
= property(_GetProtocolComments
)
2638 Ppis
= property(_GetPpis
)
2639 PpiComments
= property(_GetPpiComments
)
2640 Guids
= property(_GetGuids
)
2641 GuidComments
= property(_GetGuidComments
)
2642 Includes
= property(_GetIncludes
)
2643 Packages
= property(_GetPackages
)
2644 Pcds
= property(_GetPcds
)
2645 PcdComments
= property(_GetPcdComments
)
2646 BuildOptions
= property(_GetBuildOptions
)
2647 Depex
= property(_GetDepex
)
2648 DepexExpression
= property(_GetDepexExpression
)
2649 IsBinaryModule
= property(_IsBinaryModule
)
2650 IsSupportedArch
= property(_IsSupportedArch
)
2654 # This class defined the build database for all modules, packages and platform.
2655 # It will call corresponding parser for the given file if it cannot find it in
2658 # @param DbPath Path of database file
2659 # @param GlobalMacros Global macros used for replacement during file parsing
2660 # @prarm RenewDb=False Create new database file if it's already there
2662 class WorkspaceDatabase(object):
2666 # internal class used for call corresponding file parser and caching the result
2667 # to avoid unnecessary re-parsing
2669 class BuildObjectFactory(object):
2672 ".inf" : MODEL_FILE_INF
,
2673 ".dec" : MODEL_FILE_DEC
,
2674 ".dsc" : MODEL_FILE_DSC
,
2679 MODEL_FILE_INF
: InfParser
,
2680 MODEL_FILE_DEC
: DecParser
,
2681 MODEL_FILE_DSC
: DscParser
,
2684 # convert to xxxBuildData object
2686 MODEL_FILE_INF
: InfBuildData
,
2687 MODEL_FILE_DEC
: DecBuildData
,
2688 MODEL_FILE_DSC
: DscBuildData
,
2691 _CACHE_
= {} # (FilePath, Arch) : <object>
2694 def __init__(self
, WorkspaceDb
):
2695 self
.WorkspaceDb
= WorkspaceDb
2697 # key = (FilePath, Arch=None)
2698 def __contains__(self
, Key
):
2704 return (FilePath
, Arch
) in self
._CACHE
_
2706 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2707 def __getitem__(self
, Key
):
2709 KeyLength
= len(Key
)
2723 # if it's generated before, just return the cached one
2724 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2725 if Key
in self
._CACHE
_:
2726 return self
._CACHE
_[Key
]
2730 if Ext
not in self
._FILE
_TYPE
_:
2732 FileType
= self
._FILE
_TYPE
_[Ext
]
2733 if FileType
not in self
._GENERATOR
_:
2736 # get the parser ready for this file
2737 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2740 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2742 # alwasy do post-process, in case of macros change
2743 MetaFile
.DoPostProcess()
2744 # object the build is based on
2745 BuildObject
= self
._GENERATOR
_[FileType
](
2753 self
._CACHE
_[Key
] = BuildObject
2756 # placeholder for file format conversion
2757 class TransformObjectFactory
:
2758 def __init__(self
, WorkspaceDb
):
2759 self
.WorkspaceDb
= WorkspaceDb
2761 # key = FilePath, Arch
2762 def __getitem__(self
, Key
):
2765 ## Constructor of WorkspaceDatabase
2767 # @param DbPath Path of database file
2768 # @param GlobalMacros Global macros used for replacement during file parsing
2769 # @prarm RenewDb=False Create new database file if it's already there
2771 def __init__(self
, DbPath
, RenewDb
=False):
2772 self
._DbClosedFlag
= False
2774 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2776 # don't create necessary path for db in memory
2777 if DbPath
!= ':memory:':
2778 DbDir
= os
.path
.split(DbPath
)[0]
2779 if not os
.path
.exists(DbDir
):
2782 # remove db file in case inconsistency between db and file in file system
2783 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2786 # create db with optimized parameters
2787 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2788 self
.Conn
.execute("PRAGMA synchronous=OFF")
2789 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2790 self
.Conn
.execute("PRAGMA count_changes=OFF")
2791 self
.Conn
.execute("PRAGMA cache_size=8192")
2792 #self.Conn.execute("PRAGMA page_size=8192")
2794 # to avoid non-ascii character conversion issue
2795 self
.Conn
.text_factory
= str
2796 self
.Cur
= self
.Conn
.cursor()
2798 # create table for internal uses
2799 self
.TblDataModel
= TableDataModel(self
.Cur
)
2800 self
.TblFile
= TableFile(self
.Cur
)
2801 self
.Platform
= None
2803 # conversion object for build or file format conversion purpose
2804 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2805 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2807 ## Check whether workspace database need to be renew.
2808 # The renew reason maybe:
2809 # 1) If user force to renew;
2810 # 2) If user do not force renew, and
2811 # a) If the time of last modified python source is newer than database file;
2812 # b) If the time of last modified frozen executable file is newer than database file;
2814 # @param force User force renew database
2815 # @param DbPath The absolute path of workspace database file
2817 # @return Bool value for whether need renew workspace databse
2819 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2820 # if database does not exist, we need do nothing
2821 if not os
.path
.exists(DbPath
): return False
2823 # if user force to renew database, then not check whether database is out of date
2824 if force
: return True
2827 # Check the time of last modified source file or build.exe
2828 # if is newer than time of database, then database need to be re-created.
2830 timeOfToolModified
= 0
2831 if hasattr(sys
, "frozen"):
2832 exePath
= os
.path
.abspath(sys
.executable
)
2833 timeOfToolModified
= os
.stat(exePath
).st_mtime
2835 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2836 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2837 if rootPath
== "" or rootPath
== None:
2838 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2839 determine whether database file is out of date!\n")
2841 # walk the root path of source or build's binary to get the time last modified.
2843 for root
, dirs
, files
in os
.walk (rootPath
):
2845 # bypass source control folder
2846 if dir.lower() in [".svn", "_svn", "cvs"]:
2850 ext
= os
.path
.splitext(file)[1]
2851 if ext
.lower() == ".py": # only check .py files
2852 fd
= os
.stat(os
.path
.join(root
, file))
2853 if timeOfToolModified
< fd
.st_mtime
:
2854 timeOfToolModified
= fd
.st_mtime
2855 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2856 EdkLogger
.verbose("\nWorkspace database is out of data!")
2861 ## Initialize build database
2862 def InitDatabase(self
):
2863 EdkLogger
.verbose("\nInitialize build database started ...")
2868 self
.TblDataModel
.Create(False)
2869 self
.TblFile
.Create(False)
2872 # Initialize table DataModel
2874 self
.TblDataModel
.InitTable()
2875 EdkLogger
.verbose("Initialize build database ... DONE!")
2879 # @param Table: The instance of the table to be queried
2881 def QueryTable(self
, Table
):
2887 ## Close entire database
2890 # Close the connection and cursor
2893 if not self
._DbClosedFlag
:
2897 self
._DbClosedFlag
= True
2899 ## Summarize all packages in the database
2900 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2901 self
.Platform
= Platform
2903 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2905 # Get Package related to Modules
2907 for Module
in Pa
.Modules
:
2908 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2909 for Package
in ModuleObj
.Packages
:
2910 if Package
not in PackageList
:
2911 PackageList
.append(Package
)
2913 # Get Packages related to Libraries
2915 for Lib
in Pa
.LibraryInstances
:
2916 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2917 for Package
in LibObj
.Packages
:
2918 if Package
not in PackageList
:
2919 PackageList
.append(Package
)
2923 ## Summarize all platforms in the database
2924 def _GetPlatformList(self
):
2926 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2928 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2931 if Platform
!= None:
2932 PlatformList
.append(Platform
)
2935 PlatformList
= property(_GetPlatformList
)
2939 # This acts like the main() function for the script, unless it is 'import'ed into another
2942 if __name__
== '__main__':