2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 import Common
.LongFilePathOs
as os
23 import Common
.EdkLogger
as EdkLogger
24 import Common
.GlobalData
as GlobalData
25 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
27 from Common
.String
import *
28 from Common
.DataType
import *
29 from Common
.Misc
import *
32 from CommonDataClass
.CommonClass
import SkuInfoClass
34 from MetaDataTable
import *
35 from MetaFileTable
import *
36 from MetaFileParser
import *
37 from BuildClassObject
import *
38 from WorkspaceCommon
import GetDeclaredPcd
39 from Common
.Misc
import AnalyzeDscPcd
40 from Common
.Misc
import ProcessDuplicatedInf
42 from Common
.Parsing
import IsValidWord
43 from Common
.VariableAttributes
import VariableAttributes
44 import Common
.GlobalData
as GlobalData
46 ## Platform build information from DSC file
48 # This class is used to retrieve information stored in database and convert them
49 # into PlatformBuildClassObject form for easier use for AutoGen.
51 class DscBuildData(PlatformBuildClassObject
):
52 # dict used to convert PCD type in database to string used by build tool
54 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
55 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
56 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
57 MODEL_PCD_DYNAMIC
: "Dynamic",
58 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
59 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
60 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
61 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
62 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
63 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
64 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
67 # dict used to convert part of [Defines] to members of DscBuildData directly
72 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
73 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
74 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
75 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
76 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
77 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
78 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
79 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
80 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
81 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
82 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
83 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
84 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
85 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
86 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
89 # used to compose dummy library class name for those forced library instances
90 _NullLibraryNumber
= 0
92 ## Constructor of DscBuildData
94 # Initialize object of DscBuildData
96 # @param FilePath The path of platform description file
97 # @param RawData The raw data of DSC file
98 # @param BuildDataBase Database used to retrieve module/package information
99 # @param Arch The target architecture
100 # @param Platform (not used for DscBuildData)
101 # @param Macros Macros used for replacement in DSC file
103 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
104 self
.MetaFile
= FilePath
105 self
._RawData
= RawData
106 self
._Bdb
= BuildDataBase
108 self
._Target
= Target
109 self
._Toolchain
= Toolchain
111 self
._HandleOverridePath
()
114 def __setitem__(self
, key
, value
):
115 self
.__dict
__[self
._PROPERTY
_[key
]] = value
118 def __getitem__(self
, key
):
119 return self
.__dict
__[self
._PROPERTY
_[key
]]
122 def __contains__(self
, key
):
123 return key
in self
._PROPERTY
_
125 ## Set all internal used members of DscBuildData to None
128 self
._PlatformName
= None
131 self
._DscSpecification
= None
132 self
._OutputDirectory
= None
133 self
._SupArchList
= None
134 self
._BuildTargets
= None
136 self
._SkuIdentifier
= None
137 self
._AvilableSkuIds
= None
138 self
._PcdInfoFlag
= None
139 self
._VarCheckFlag
= None
140 self
._FlashDefinition
= None
141 self
._Prebuild
= None
142 self
._Postbuild
= None
143 self
._BuildNumber
= None
144 self
._MakefileName
= None
145 self
._BsBaseAddress
= None
146 self
._RtBaseAddress
= None
149 self
._LibraryInstances
= None
150 self
._LibraryClasses
= None
153 self
._BuildOptions
= None
154 self
._ModuleTypeOptions
= None
155 self
._LoadFixAddress
= None
156 self
._RFCLanguages
= None
157 self
._ISOLanguages
= None
158 self
._VpdToolGuid
= None
162 ## handle Override Path of Module
163 def _HandleOverridePath(self
):
164 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
165 Macros
= self
._Macros
166 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
167 for Record
in RecordList
:
170 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
171 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
173 SourceOverridePath
= mws
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
175 # Check if the source override path exists
176 if not os
.path
.isdir(SourceOverridePath
):
177 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
179 #Add to GlobalData Variables
180 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
182 ## Get current effective macros
183 def _GetMacros(self
):
184 if self
.__Macros
== None:
186 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
187 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
188 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
197 # Changing the default ARCH to another may affect all other information
198 # because all information in a platform may be ARCH-related. That's
199 # why we need to clear all internal used members, in order to cause all
200 # information to be re-retrieved.
202 # @param Value The value of ARCH
204 def _SetArch(self
, Value
):
205 if self
._Arch
== Value
:
210 ## Retrieve all information in [Defines] section
212 # (Retriving all [Defines] information in one-shot is just to save time.)
214 def _GetHeaderInfo(self
):
215 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
216 for Record
in RecordList
:
218 # items defined _PROPERTY_ don't need additional processing
220 # some special items in [Defines] section need special treatment
221 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
222 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
223 if ' ' in self
._OutputDirectory
:
224 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
225 File
=self
.MetaFile
, Line
=Record
[-1],
226 ExtraData
=self
._OutputDirectory
)
227 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
228 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
229 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
231 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
233 elif Name
== TAB_DSC_PREBUILD
:
234 self
._Prebuild
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
235 elif Name
== TAB_DSC_POSTBUILD
:
236 self
._Postbuild
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
237 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
238 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
239 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
240 self
._BuildTargets
= GetSplitValueList(Record
[2])
241 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
242 if self
._SkuName
== None:
243 self
._SkuName
= Record
[2]
244 self
._SkuIdentifier
= Record
[2]
245 self
._AvilableSkuIds
= Record
[2]
246 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
247 self
._PcdInfoFlag
= Record
[2]
248 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
249 self
._VarCheckFlag
= Record
[2]
250 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
252 self
._LoadFixAddress
= int (Record
[2], 0)
254 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
255 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
256 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
257 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
258 File
=self
.MetaFile
, Line
=Record
[-1])
259 LanguageCodes
= Record
[2][1:-1]
260 if not LanguageCodes
:
261 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
262 File
=self
.MetaFile
, Line
=Record
[-1])
263 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
264 # check whether there is empty entries in the list
265 if None in LanguageList
:
266 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
267 File
=self
.MetaFile
, Line
=Record
[-1])
268 self
._RFCLanguages
= LanguageList
269 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
270 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
271 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
272 File
=self
.MetaFile
, Line
=Record
[-1])
273 LanguageCodes
= Record
[2][1:-1]
274 if not LanguageCodes
:
275 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
276 File
=self
.MetaFile
, Line
=Record
[-1])
277 if len(LanguageCodes
)%3:
278 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
279 File
=self
.MetaFile
, Line
=Record
[-1])
281 for i
in range(0, len(LanguageCodes
), 3):
282 LanguageList
.append(LanguageCodes
[i
:i
+3])
283 self
._ISOLanguages
= LanguageList
284 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
286 # try to convert GUID to a real UUID value to see whether the GUID is format
287 # for VPD_TOOL_GUID is correct.
292 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
293 self
._VpdToolGuid
= Record
[2]
295 self
[Name
] = Record
[2]
296 # set _Header to non-None in order to avoid database re-querying
297 self
._Header
= 'DUMMY'
299 ## Retrieve platform name
300 def _GetPlatformName(self
):
301 if self
._PlatformName
== None:
302 if self
._Header
== None:
303 self
._GetHeaderInfo
()
304 if self
._PlatformName
== None:
305 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
306 return self
._PlatformName
308 ## Retrieve file guid
309 def _GetFileGuid(self
):
310 if self
._Guid
== None:
311 if self
._Header
== None:
312 self
._GetHeaderInfo
()
313 if self
._Guid
== None:
314 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
317 ## Retrieve platform version
318 def _GetVersion(self
):
319 if self
._Version
== None:
320 if self
._Header
== None:
321 self
._GetHeaderInfo
()
322 if self
._Version
== None:
323 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
326 ## Retrieve platform description file version
327 def _GetDscSpec(self
):
328 if self
._DscSpecification
== None:
329 if self
._Header
== None:
330 self
._GetHeaderInfo
()
331 if self
._DscSpecification
== None:
332 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
333 return self
._DscSpecification
335 ## Retrieve OUTPUT_DIRECTORY
336 def _GetOutpuDir(self
):
337 if self
._OutputDirectory
== None:
338 if self
._Header
== None:
339 self
._GetHeaderInfo
()
340 if self
._OutputDirectory
== None:
341 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
342 return self
._OutputDirectory
344 ## Retrieve SUPPORTED_ARCHITECTURES
345 def _GetSupArch(self
):
346 if self
._SupArchList
== None:
347 if self
._Header
== None:
348 self
._GetHeaderInfo
()
349 if self
._SupArchList
== None:
350 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
351 return self
._SupArchList
353 ## Retrieve BUILD_TARGETS
354 def _GetBuildTarget(self
):
355 if self
._BuildTargets
== None:
356 if self
._Header
== None:
357 self
._GetHeaderInfo
()
358 if self
._BuildTargets
== None:
359 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
360 return self
._BuildTargets
362 def _GetPcdInfoFlag(self
):
363 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
365 elif self
._PcdInfoFlag
.upper() == 'TRUE':
369 def _GetVarCheckFlag(self
):
370 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
372 elif self
._VarCheckFlag
.upper() == 'TRUE':
376 def _GetAviableSkuIds(self
):
377 if self
._AvilableSkuIds
:
378 return self
._AvilableSkuIds
379 return self
.SkuIdentifier
380 def _GetSkuIdentifier(self
):
383 if self
._SkuIdentifier
== None:
384 if self
._Header
== None:
385 self
._GetHeaderInfo
()
386 return self
._SkuIdentifier
387 ## Retrieve SKUID_IDENTIFIER
388 def _GetSkuName(self
):
389 if self
._SkuName
== None:
390 if self
._Header
== None:
391 self
._GetHeaderInfo
()
392 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
393 self
._SkuName
= 'DEFAULT'
396 ## Override SKUID_IDENTIFIER
397 def _SetSkuName(self
, Value
):
398 self
._SkuName
= Value
401 def _GetFdfFile(self
):
402 if self
._FlashDefinition
== None:
403 if self
._Header
== None:
404 self
._GetHeaderInfo
()
405 if self
._FlashDefinition
== None:
406 self
._FlashDefinition
= ''
407 return self
._FlashDefinition
409 def _GetPrebuild(self
):
410 if self
._Prebuild
== None:
411 if self
._Header
== None:
412 self
._GetHeaderInfo
()
413 if self
._Prebuild
== None:
415 return self
._Prebuild
417 def _GetPostbuild(self
):
418 if self
._Postbuild
== None:
419 if self
._Header
== None:
420 self
._GetHeaderInfo
()
421 if self
._Postbuild
== None:
423 return self
._Postbuild
425 ## Retrieve FLASH_DEFINITION
426 def _GetBuildNumber(self
):
427 if self
._BuildNumber
== None:
428 if self
._Header
== None:
429 self
._GetHeaderInfo
()
430 if self
._BuildNumber
== None:
431 self
._BuildNumber
= ''
432 return self
._BuildNumber
434 ## Retrieve MAKEFILE_NAME
435 def _GetMakefileName(self
):
436 if self
._MakefileName
== None:
437 if self
._Header
== None:
438 self
._GetHeaderInfo
()
439 if self
._MakefileName
== None:
440 self
._MakefileName
= ''
441 return self
._MakefileName
443 ## Retrieve BsBaseAddress
444 def _GetBsBaseAddress(self
):
445 if self
._BsBaseAddress
== None:
446 if self
._Header
== None:
447 self
._GetHeaderInfo
()
448 if self
._BsBaseAddress
== None:
449 self
._BsBaseAddress
= ''
450 return self
._BsBaseAddress
452 ## Retrieve RtBaseAddress
453 def _GetRtBaseAddress(self
):
454 if self
._RtBaseAddress
== None:
455 if self
._Header
== None:
456 self
._GetHeaderInfo
()
457 if self
._RtBaseAddress
== None:
458 self
._RtBaseAddress
= ''
459 return self
._RtBaseAddress
461 ## Retrieve the top address for the load fix address
462 def _GetLoadFixAddress(self
):
463 if self
._LoadFixAddress
== None:
464 if self
._Header
== None:
465 self
._GetHeaderInfo
()
467 if self
._LoadFixAddress
== None:
468 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
471 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
473 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
476 # If command line defined, should override the value in DSC file.
478 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
480 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
482 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']))
484 if self
._LoadFixAddress
< 0:
485 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
486 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
487 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
489 return self
._LoadFixAddress
491 ## Retrieve RFCLanguage filter
492 def _GetRFCLanguages(self
):
493 if self
._RFCLanguages
== None:
494 if self
._Header
== None:
495 self
._GetHeaderInfo
()
496 if self
._RFCLanguages
== None:
497 self
._RFCLanguages
= []
498 return self
._RFCLanguages
500 ## Retrieve ISOLanguage filter
501 def _GetISOLanguages(self
):
502 if self
._ISOLanguages
== None:
503 if self
._Header
== None:
504 self
._GetHeaderInfo
()
505 if self
._ISOLanguages
== None:
506 self
._ISOLanguages
= []
507 return self
._ISOLanguages
508 ## Retrieve the GUID string for VPD tool
509 def _GetVpdToolGuid(self
):
510 if self
._VpdToolGuid
== None:
511 if self
._Header
== None:
512 self
._GetHeaderInfo
()
513 if self
._VpdToolGuid
== None:
514 self
._VpdToolGuid
= ''
515 return self
._VpdToolGuid
517 ## Retrieve [SkuIds] section information
518 def _GetSkuIds(self
):
519 if self
._SkuIds
== None:
520 self
._SkuIds
= sdict()
521 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
522 for Record
in RecordList
:
523 if Record
[0] in [None, '']:
524 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
525 File
=self
.MetaFile
, Line
=Record
[-1])
526 if Record
[1] in [None, '']:
527 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
528 File
=self
.MetaFile
, Line
=Record
[-1])
529 self
._SkuIds
[Record
[1]] = Record
[0]
530 if 'DEFAULT' not in self
._SkuIds
:
531 self
._SkuIds
['DEFAULT'] = '0'
532 if 'COMMON' not in self
._SkuIds
:
533 self
._SkuIds
['COMMON'] = '0'
536 ## Retrieve [Components] section information
537 def _GetModules(self
):
538 if self
._Modules
!= None:
541 self
._Modules
= sdict()
542 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
543 Macros
= self
._Macros
544 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
545 for Record
in RecordList
:
546 DuplicatedFile
= False
548 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
552 # check the file validation
553 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
555 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
558 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
559 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
560 DuplicatedFile
= True
562 Module
= ModuleBuildClassObject()
563 Module
.MetaFile
= ModuleFile
565 # get module private library instance
566 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
567 for Record
in RecordList
:
568 LibraryClass
= Record
[0]
569 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
572 # check the file validation
573 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
575 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
578 if LibraryClass
== '' or LibraryClass
== 'NULL':
579 self
._NullLibraryNumber
+= 1
580 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
581 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
582 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
583 if LibraryPath
not in self
.LibraryInstances
:
584 self
.LibraryInstances
.append(LibraryPath
)
586 # get module private PCD setting
587 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
588 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
589 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
590 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
591 TokenList
= GetSplitValueList(Setting
)
592 DefaultValue
= TokenList
[0]
593 if len(TokenList
) > 1:
594 MaxDatumSize
= TokenList
[1]
597 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
598 Pcd
= PcdClassObject(
610 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
612 # get module private build options
613 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
614 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
615 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
616 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
618 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
619 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
621 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
622 if DuplicatedFile
and not RecordList
:
623 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
625 if len(RecordList
) != 1:
626 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
627 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
628 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
629 ModuleFile
.Arch
= self
._Arch
631 self
._Modules
[ModuleFile
] = Module
634 ## Retrieve all possible library instances used in this platform
635 def _GetLibraryInstances(self
):
636 if self
._LibraryInstances
== None:
637 self
._GetLibraryClasses
()
638 return self
._LibraryInstances
640 ## Retrieve [LibraryClasses] information
641 def _GetLibraryClasses(self
):
642 if self
._LibraryClasses
== None:
643 self
._LibraryInstances
= []
645 # tdict is a special dict kind of type, used for selecting correct
646 # library instance for given library class and module type
648 LibraryClassDict
= tdict(True, 3)
649 # track all library class names
650 LibraryClassSet
= set()
651 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
652 Macros
= self
._Macros
653 for Record
in RecordList
:
654 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
655 if LibraryClass
== '' or LibraryClass
== 'NULL':
656 self
._NullLibraryNumber
+= 1
657 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
658 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
659 LibraryClassSet
.add(LibraryClass
)
660 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
661 # check the file validation
662 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
664 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
667 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
668 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
669 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
670 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
671 if LibraryInstance
not in self
._LibraryInstances
:
672 self
._LibraryInstances
.append(LibraryInstance
)
674 # resolve the specific library instance for each class and each module type
675 self
._LibraryClasses
= tdict(True)
676 for LibraryClass
in LibraryClassSet
:
677 # try all possible module types
678 for ModuleType
in SUP_MODULE_LIST
:
679 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
680 if LibraryInstance
== None:
682 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
684 # for Edk style library instances, which are listed in different section
685 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
686 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
687 for Record
in RecordList
:
688 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
690 # check the file validation
691 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
693 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
695 if File
not in self
._LibraryInstances
:
696 self
._LibraryInstances
.append(File
)
698 # we need the module name as the library class name, so we have
699 # to parse it here. (self._Bdb[] will trigger a file parse if it
700 # hasn't been parsed)
702 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
703 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
704 return self
._LibraryClasses
706 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
707 if self
._DecPcds
== None:
708 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
710 if GlobalData
.gFdfParser
:
711 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
714 for Inf
in FdfInfList
:
715 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
716 if ModuleFile
in self
._Modules
:
718 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
719 PkgSet
.update(ModuleData
.Packages
)
723 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
724 self
._DecPcds
.update(DecPcds
)
726 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
727 EdkLogger
.error('build', PARSER_ERROR
,
728 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
729 File
=self
.MetaFile
, Line
=LineNo
)
730 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
731 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
732 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
733 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
734 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
736 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
737 except WrnExpression
, Value
:
738 ValueList
[Index
] = Value
.result
739 except EvaluationException
, Excpt
:
740 if hasattr(Excpt
, 'Pcd'):
741 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
742 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
743 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
744 " of the DSC file" % Excpt
.Pcd
,
745 File
=self
.MetaFile
, Line
=LineNo
)
747 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
748 File
=self
.MetaFile
, Line
=LineNo
)
750 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
751 File
=self
.MetaFile
, Line
=LineNo
)
752 if ValueList
[Index
] == 'True':
753 ValueList
[Index
] = '1'
754 elif ValueList
[Index
] == 'False':
755 ValueList
[Index
] = '0'
757 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
759 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
760 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
763 ## Retrieve all PCD settings in platform
765 if self
._Pcds
== None:
767 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
768 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
769 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
770 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
771 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
772 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
773 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
774 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
775 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
778 ## Retrieve [BuildOptions]
779 def _GetBuildOptions(self
):
780 if self
._BuildOptions
== None:
781 self
._BuildOptions
= sdict()
783 # Retrieve build option for EDKII and EDK style module
785 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
786 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
787 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
788 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
790 # Only flags can be appended
792 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
793 self
._BuildOptions
[CurKey
] = Option
795 self
._BuildOptions
[CurKey
] += ' ' + Option
796 return self
._BuildOptions
798 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
799 if self
._ModuleTypeOptions
== None:
800 self
._ModuleTypeOptions
= sdict()
801 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
803 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
804 DriverType
= '%s.%s' % (Edk
, ModuleType
)
805 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, DriverType
]
806 for ToolChainFamily
, ToolChain
, Option
, Arch
, Type
, Dummy3
, Dummy4
in RecordList
:
807 if Type
== DriverType
:
808 Key
= (ToolChainFamily
, ToolChain
, Edk
)
809 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
810 options
[Key
] = Option
812 options
[Key
] += ' ' + Option
813 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
815 ## Retrieve non-dynamic PCD settings
817 # @param Type PCD type
819 # @retval a dict object contains settings of given PCD type
821 def _GetPcd(self
, Type
):
824 # tdict is a special dict kind of type, used for selecting correct
825 # PCD settings for certain ARCH
828 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
830 PcdDict
= tdict(True, 3)
832 # Find out all possible PCD candidates for self._Arch
833 RecordList
= self
._RawData
[Type
, self
._Arch
]
834 PcdValueDict
= sdict()
835 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
836 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
837 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
838 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
840 #handle pcd value override
841 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
842 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
845 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
846 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
847 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
849 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
851 PcdsKeys
= PcdValueDict
.keys()
852 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
854 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
858 if 'COMMON' in PcdSetting
:
859 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
860 if 'DEFAULT' in PcdSetting
:
861 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
862 if SkuObj
.SystemSkuId
in PcdSetting
:
863 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
865 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
868 self
._PCD
_TYPE
_STRING
_[Type
],
879 ## Retrieve dynamic PCD settings
881 # @param Type PCD type
883 # @retval a dict object contains settings of given PCD type
885 def _GetDynamicPcd(self
, Type
):
887 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
891 # tdict is a special dict kind of type, used for selecting correct
892 # PCD settings for certain ARCH and SKU
894 PcdDict
= tdict(True, 4)
896 # Find out all possible PCD candidates for self._Arch
897 RecordList
= self
._RawData
[Type
, self
._Arch
]
898 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
900 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
901 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
902 if SkuName
not in AvailableSkuIdSet
:
905 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
906 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
907 # Remove redundant PCD candidates, per the ARCH and SKU
908 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
910 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
914 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
915 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
916 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
917 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
918 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
919 if MaxDatumSize
.strip():
920 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
923 if pcdObject
.MaxDatumSize
:
924 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
927 if CurrentMaxSize
> PcdMaxSize
:
928 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
930 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
933 self
._PCD
_TYPE
_STRING
_[Type
],
943 for pcd
in Pcds
.values():
944 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
945 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
946 valuefromDec
= pcdDecObject
.DefaultValue
947 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
948 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
949 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
950 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
951 del(pcd
.SkuInfoList
['COMMON'])
952 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
953 del(pcd
.SkuInfoList
['COMMON'])
954 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
955 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
956 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
957 del(pcd
.SkuInfoList
['DEFAULT'])
961 def CompareVarAttr(self
, Attr1
, Attr2
):
962 if not Attr1
or not Attr2
: # for empty string
964 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
965 Attr1Set
= set(Attr1s
)
966 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
967 Attr2Set
= set(Attr2s
)
968 if Attr2Set
== Attr1Set
:
972 ## Retrieve dynamic HII PCD settings
974 # @param Type PCD type
976 # @retval a dict object contains settings of given PCD type
978 def _GetDynamicHiiPcd(self
, Type
):
980 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
985 # tdict is a special dict kind of type, used for selecting correct
986 # PCD settings for certain ARCH and SKU
988 PcdDict
= tdict(True, 4)
990 RecordList
= self
._RawData
[Type
, self
._Arch
]
991 # Find out all possible PCD candidates for self._Arch
992 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
994 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
995 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
996 if SkuName
not in AvailableSkuIdSet
:
998 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
999 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1000 # Remove redundant PCD candidates, per the ARCH and SKU
1001 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
1003 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1006 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1008 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1010 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1011 ExtraData
= "[%s]" % VarAttribute
)
1013 FormatCorrect
= True
1014 if VariableOffset
.isdigit():
1015 if int(VariableOffset
,10) > 0xFFFF:
1017 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
1018 if int(VariableOffset
,16) > 0xFFFF:
1020 # For Offset written in "A.B"
1021 elif VariableOffset
.find('.') > -1:
1022 VariableOffsetList
= VariableOffset
.split(".")
1023 if not (len(VariableOffsetList
) == 2
1024 and IsValidWord(VariableOffsetList
[0])
1025 and IsValidWord(VariableOffsetList
[1])):
1026 FormatCorrect
= False
1028 FormatCorrect
= False
1029 if not FormatCorrect
:
1030 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1033 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1034 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1035 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1037 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1038 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
)]))
1040 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
= VarAttribute
)
1041 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1042 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1043 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1044 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1046 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1049 self
._PCD
_TYPE
_STRING
_[Type
],
1054 {SkuName
: SkuInfo
},
1057 pcdDecObject
.validateranges
,
1058 pcdDecObject
.validlists
,
1059 pcdDecObject
.expressions
1063 for pcd
in Pcds
.values():
1064 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1065 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1066 # Only fix the value while no value provided in DSC file.
1067 for sku
in pcd
.SkuInfoList
.values():
1068 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
1069 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1070 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1071 valuefromDec
= pcdDecObject
.DefaultValue
1072 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
1073 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1074 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1075 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1076 del(pcd
.SkuInfoList
['COMMON'])
1077 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1078 del(pcd
.SkuInfoList
['COMMON'])
1080 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1081 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1082 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1083 del(pcd
.SkuInfoList
['DEFAULT'])
1086 if pcd
.MaxDatumSize
.strip():
1087 MaxSize
= int(pcd
.MaxDatumSize
,0)
1090 if pcdDecObject
.DatumType
== 'VOID*':
1091 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1093 if skuobj
.HiiDefaultValue
.startswith("L"):
1094 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
1095 elif skuobj
.HiiDefaultValue
.startswith("{"):
1096 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1098 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
1101 pcd
.MaxDatumSize
= str(MaxSize
)
1104 ## Retrieve dynamic VPD PCD settings
1106 # @param Type PCD type
1108 # @retval a dict object contains settings of given PCD type
1110 def _GetDynamicVpdPcd(self
, Type
):
1112 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
1116 # tdict is a special dict kind of type, used for selecting correct
1117 # PCD settings for certain ARCH and SKU
1119 PcdDict
= tdict(True, 4)
1121 # Find out all possible PCD candidates for self._Arch
1122 RecordList
= self
._RawData
[Type
, self
._Arch
]
1123 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1125 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1126 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1127 if SkuName
not in AvailableSkuIdSet
:
1130 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1131 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1132 # Remove redundant PCD candidates, per the ARCH and SKU
1133 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1134 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1138 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1139 # For the Integer & Boolean type, the optional data can only be InitialValue.
1140 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1141 # until the DEC parser has been called.
1143 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1144 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1145 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1146 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1147 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1148 if MaxDatumSize
.strip():
1149 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1152 if pcdObject
.MaxDatumSize
:
1153 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1156 if CurrentMaxSize
> PcdMaxSize
:
1157 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1159 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1162 self
._PCD
_TYPE
_STRING
_[Type
],
1167 {SkuName
: SkuInfo
},
1171 for pcd
in Pcds
.values():
1172 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1173 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1174 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1175 valuefromDec
= pcdDecObject
.DefaultValue
1176 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1177 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1178 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1179 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1180 del(pcd
.SkuInfoList
['COMMON'])
1181 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1182 del(pcd
.SkuInfoList
['COMMON'])
1183 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1184 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1185 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1186 del(pcd
.SkuInfoList
['DEFAULT'])
1190 ## Add external modules
1192 # The external modules are mostly those listed in FDF file, which don't
1195 # @param FilePath The path of module description file
1197 def AddModule(self
, FilePath
):
1198 FilePath
= NormPath(FilePath
)
1199 if FilePath
not in self
.Modules
:
1200 Module
= ModuleBuildClassObject()
1201 Module
.MetaFile
= FilePath
1202 self
.Modules
.append(Module
)
1204 ## Add external PCDs
1206 # The external PCDs are mostly those listed in FDF file to specify address
1207 # or offset information.
1209 # @param Name Name of the PCD
1210 # @param Guid Token space guid of the PCD
1211 # @param Value Value of the PCD
1213 def AddPcd(self
, Name
, Guid
, Value
):
1214 if (Name
, Guid
) not in self
.Pcds
:
1215 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1216 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1218 _Macros
= property(_GetMacros
)
1219 Arch
= property(_GetArch
, _SetArch
)
1220 Platform
= property(_GetPlatformName
)
1221 PlatformName
= property(_GetPlatformName
)
1222 Guid
= property(_GetFileGuid
)
1223 Version
= property(_GetVersion
)
1224 DscSpecification
= property(_GetDscSpec
)
1225 OutputDirectory
= property(_GetOutpuDir
)
1226 SupArchList
= property(_GetSupArch
)
1227 BuildTargets
= property(_GetBuildTarget
)
1228 SkuName
= property(_GetSkuName
, _SetSkuName
)
1229 SkuIdentifier
= property(_GetSkuIdentifier
)
1230 AvilableSkuIds
= property(_GetAviableSkuIds
)
1231 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1232 VarCheckFlag
= property(_GetVarCheckFlag
)
1233 FlashDefinition
= property(_GetFdfFile
)
1234 Prebuild
= property(_GetPrebuild
)
1235 Postbuild
= property(_GetPostbuild
)
1236 BuildNumber
= property(_GetBuildNumber
)
1237 MakefileName
= property(_GetMakefileName
)
1238 BsBaseAddress
= property(_GetBsBaseAddress
)
1239 RtBaseAddress
= property(_GetRtBaseAddress
)
1240 LoadFixAddress
= property(_GetLoadFixAddress
)
1241 RFCLanguages
= property(_GetRFCLanguages
)
1242 ISOLanguages
= property(_GetISOLanguages
)
1243 VpdToolGuid
= property(_GetVpdToolGuid
)
1244 SkuIds
= property(_GetSkuIds
)
1245 Modules
= property(_GetModules
)
1246 LibraryInstances
= property(_GetLibraryInstances
)
1247 LibraryClasses
= property(_GetLibraryClasses
)
1248 Pcds
= property(_GetPcds
)
1249 BuildOptions
= property(_GetBuildOptions
)
1251 ## Platform build information from DEC file
1253 # This class is used to retrieve information stored in database and convert them
1254 # into PackageBuildClassObject form for easier use for AutoGen.
1256 class DecBuildData(PackageBuildClassObject
):
1257 # dict used to convert PCD type in database to string used by build tool
1258 _PCD_TYPE_STRING_
= {
1259 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1260 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1261 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1262 MODEL_PCD_DYNAMIC
: "Dynamic",
1263 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1264 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1265 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1266 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1267 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1268 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1269 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1272 # dict used to convert part of [Defines] to members of DecBuildData directly
1277 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1278 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1279 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1280 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1284 ## Constructor of DecBuildData
1286 # Initialize object of DecBuildData
1288 # @param FilePath The path of package description file
1289 # @param RawData The raw data of DEC file
1290 # @param BuildDataBase Database used to retrieve module information
1291 # @param Arch The target architecture
1292 # @param Platform (not used for DecBuildData)
1293 # @param Macros Macros used for replacement in DSC file
1295 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1296 self
.MetaFile
= File
1297 self
._PackageDir
= File
.Dir
1298 self
._RawData
= RawData
1299 self
._Bdb
= BuildDataBase
1301 self
._Target
= Target
1302 self
._Toolchain
= Toolchain
1306 def __setitem__(self
, key
, value
):
1307 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1310 def __getitem__(self
, key
):
1311 return self
.__dict
__[self
._PROPERTY
_[key
]]
1313 ## "in" test support
1314 def __contains__(self
, key
):
1315 return key
in self
._PROPERTY
_
1317 ## Set all internal used members of DecBuildData to None
1320 self
._PackageName
= None
1322 self
._Version
= None
1323 self
._PkgUniFile
= None
1324 self
._Protocols
= None
1327 self
._Includes
= None
1328 self
._LibraryClasses
= None
1330 self
.__Macros
= None
1331 self
._PrivateProtocols
= None
1332 self
._PrivatePpis
= None
1333 self
._PrivateGuids
= None
1334 self
._PrivateIncludes
= None
1336 ## Get current effective macros
1337 def _GetMacros(self
):
1338 if self
.__Macros
== None:
1340 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1341 return self
.__Macros
1349 # Changing the default ARCH to another may affect all other information
1350 # because all information in a platform may be ARCH-related. That's
1351 # why we need to clear all internal used members, in order to cause all
1352 # information to be re-retrieved.
1354 # @param Value The value of ARCH
1356 def _SetArch(self
, Value
):
1357 if self
._Arch
== Value
:
1362 ## Retrieve all information in [Defines] section
1364 # (Retriving all [Defines] information in one-shot is just to save time.)
1366 def _GetHeaderInfo(self
):
1367 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1368 for Record
in RecordList
:
1371 self
[Name
] = Record
[2]
1372 self
._Header
= 'DUMMY'
1374 ## Retrieve package name
1375 def _GetPackageName(self
):
1376 if self
._PackageName
== None:
1377 if self
._Header
== None:
1378 self
._GetHeaderInfo
()
1379 if self
._PackageName
== None:
1380 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1381 return self
._PackageName
1383 ## Retrieve file guid
1384 def _GetFileGuid(self
):
1385 if self
._Guid
== None:
1386 if self
._Header
== None:
1387 self
._GetHeaderInfo
()
1388 if self
._Guid
== None:
1389 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1392 ## Retrieve package version
1393 def _GetVersion(self
):
1394 if self
._Version
== None:
1395 if self
._Header
== None:
1396 self
._GetHeaderInfo
()
1397 if self
._Version
== None:
1399 return self
._Version
1401 ## Retrieve protocol definitions (name/value pairs)
1402 def _GetProtocol(self
):
1403 if self
._Protocols
== None:
1405 # tdict is a special kind of dict, used for selecting correct
1406 # protocol defition for given ARCH
1408 ProtocolDict
= tdict(True)
1409 PrivateProtocolDict
= tdict(True)
1411 PrivateNameList
= []
1412 # find out all protocol definitions for specific and 'common' arch
1413 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1414 for Name
, Guid
, Dummy
, Arch
, PrivateFlag
, ID
, LineNo
in RecordList
:
1415 if PrivateFlag
== 'PRIVATE':
1416 if Name
not in PrivateNameList
:
1417 PrivateNameList
.append(Name
)
1418 PrivateProtocolDict
[Arch
, Name
] = Guid
1419 if Name
not in NameList
:
1420 NameList
.append(Name
)
1421 ProtocolDict
[Arch
, Name
] = Guid
1422 # use sdict to keep the order
1423 self
._Protocols
= sdict()
1424 self
._PrivateProtocols
= sdict()
1425 for Name
in NameList
:
1427 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1428 # will automatically turn to 'common' ARCH for trying
1430 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1431 for Name
in PrivateNameList
:
1432 self
._PrivateProtocols
[Name
] = PrivateProtocolDict
[self
._Arch
, Name
]
1433 return self
._Protocols
1435 ## Retrieve PPI definitions (name/value pairs)
1437 if self
._Ppis
== None:
1439 # tdict is a special kind of dict, used for selecting correct
1440 # PPI defition for given ARCH
1442 PpiDict
= tdict(True)
1443 PrivatePpiDict
= tdict(True)
1445 PrivateNameList
= []
1446 # find out all PPI definitions for specific arch and 'common' arch
1447 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1448 for Name
, Guid
, Dummy
, Arch
, PrivateFlag
, ID
, LineNo
in RecordList
:
1449 if PrivateFlag
== 'PRIVATE':
1450 if Name
not in PrivateNameList
:
1451 PrivateNameList
.append(Name
)
1452 PrivatePpiDict
[Arch
, Name
] = Guid
1453 if Name
not in NameList
:
1454 NameList
.append(Name
)
1455 PpiDict
[Arch
, Name
] = Guid
1456 # use sdict to keep the order
1457 self
._Ppis
= sdict()
1458 self
._PrivatePpis
= sdict()
1459 for Name
in NameList
:
1461 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1462 # will automatically turn to 'common' ARCH for trying
1464 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1465 for Name
in PrivateNameList
:
1466 self
._PrivatePpis
[Name
] = PrivatePpiDict
[self
._Arch
, Name
]
1469 ## Retrieve GUID definitions (name/value pairs)
1471 if self
._Guids
== None:
1473 # tdict is a special kind of dict, used for selecting correct
1474 # GUID defition for given ARCH
1476 GuidDict
= tdict(True)
1477 PrivateGuidDict
= tdict(True)
1479 PrivateNameList
= []
1480 # find out all protocol definitions for specific and 'common' arch
1481 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1482 for Name
, Guid
, Dummy
, Arch
, PrivateFlag
, ID
, LineNo
in RecordList
:
1483 if PrivateFlag
== 'PRIVATE':
1484 if Name
not in PrivateNameList
:
1485 PrivateNameList
.append(Name
)
1486 PrivateGuidDict
[Arch
, Name
] = Guid
1487 if Name
not in NameList
:
1488 NameList
.append(Name
)
1489 GuidDict
[Arch
, Name
] = Guid
1490 # use sdict to keep the order
1491 self
._Guids
= sdict()
1492 self
._PrivateGuids
= sdict()
1493 for Name
in NameList
:
1495 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1496 # will automatically turn to 'common' ARCH for trying
1498 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1499 for Name
in PrivateNameList
:
1500 self
._PrivateGuids
[Name
] = PrivateGuidDict
[self
._Arch
, Name
]
1503 ## Retrieve public include paths declared in this package
1504 def _GetInclude(self
):
1505 if self
._Includes
== None:
1507 self
._PrivateIncludes
= []
1508 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1509 Macros
= self
._Macros
1510 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1511 for Record
in RecordList
:
1512 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1515 ErrorCode
, ErrorInfo
= File
.Validate()
1517 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1519 # avoid duplicate include path
1520 if File
not in self
._Includes
:
1521 self
._Includes
.append(File
)
1522 if Record
[4] == 'PRIVATE':
1523 if File
not in self
._PrivateIncludes
:
1524 self
._PrivateIncludes
.append(File
)
1525 return self
._Includes
1527 ## Retrieve library class declarations (not used in build at present)
1528 def _GetLibraryClass(self
):
1529 if self
._LibraryClasses
== None:
1531 # tdict is a special kind of dict, used for selecting correct
1532 # library class declaration for given ARCH
1534 LibraryClassDict
= tdict(True)
1535 LibraryClassSet
= set()
1536 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1537 Macros
= self
._Macros
1538 for LibraryClass
, File
, Dummy
, Arch
, PrivateFlag
, ID
, LineNo
in RecordList
:
1539 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1540 # check the file validation
1541 ErrorCode
, ErrorInfo
= File
.Validate()
1543 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1544 LibraryClassSet
.add(LibraryClass
)
1545 LibraryClassDict
[Arch
, LibraryClass
] = File
1546 self
._LibraryClasses
= sdict()
1547 for LibraryClass
in LibraryClassSet
:
1548 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1549 return self
._LibraryClasses
1551 ## Retrieve PCD declarations
1553 if self
._Pcds
== None:
1554 self
._Pcds
= sdict()
1555 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1556 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1557 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1558 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1559 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1562 ## Retrieve PCD declarations for given type
1563 def _GetPcd(self
, Type
):
1566 # tdict is a special kind of dict, used for selecting correct
1567 # PCD declaration for given ARCH
1569 PcdDict
= tdict(True, 3)
1570 # for summarizing PCD
1572 # find out all PCDs of the 'type'
1573 RecordList
= self
._RawData
[Type
, self
._Arch
]
1574 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, PrivateFlag
, Dummy1
, Dummy2
in RecordList
:
1575 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1576 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1578 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1580 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1581 # will automatically turn to 'common' ARCH and try again
1583 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1587 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1589 validateranges
, validlists
, expressions
= self
._RawData
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
1590 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1593 self
._PCD
_TYPE
_STRING
_[Type
],
1601 list(validateranges
),
1608 _Macros
= property(_GetMacros
)
1609 Arch
= property(_GetArch
, _SetArch
)
1610 PackageName
= property(_GetPackageName
)
1611 Guid
= property(_GetFileGuid
)
1612 Version
= property(_GetVersion
)
1614 Protocols
= property(_GetProtocol
)
1615 Ppis
= property(_GetPpi
)
1616 Guids
= property(_GetGuid
)
1617 Includes
= property(_GetInclude
)
1618 LibraryClasses
= property(_GetLibraryClass
)
1619 Pcds
= property(_GetPcds
)
1621 ## Module build information from INF file
1623 # This class is used to retrieve information stored in database and convert them
1624 # into ModuleBuildClassObject form for easier use for AutoGen.
1626 class InfBuildData(ModuleBuildClassObject
):
1627 # dict used to convert PCD type in database to string used by build tool
1628 _PCD_TYPE_STRING_
= {
1629 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1630 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1631 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1632 MODEL_PCD_DYNAMIC
: "Dynamic",
1633 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1634 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1635 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1636 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1637 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1638 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1639 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1642 # dict used to convert part of [Defines] to members of InfBuildData directly
1647 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1648 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1649 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1653 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1654 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1655 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1656 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1657 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1658 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1659 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1660 TAB_INF_DEFINES_VERSION
: "_Version",
1661 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1662 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1664 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1667 # dict used to convert Component type to Module type
1670 "SECURITY_CORE" : "SEC",
1671 "PEI_CORE" : "PEI_CORE",
1672 "COMBINED_PEIM_DRIVER" : "PEIM",
1673 "PIC_PEIM" : "PEIM",
1674 "RELOCATABLE_PEIM" : "PEIM",
1675 "PE32_PEIM" : "PEIM",
1676 "BS_DRIVER" : "DXE_DRIVER",
1677 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1678 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1679 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1680 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1681 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1682 # "BS_DRIVER" : "UEFI_DRIVER",
1683 "APPLICATION" : "UEFI_APPLICATION",
1687 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1688 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1689 # dict used to convert old tool name used in [nmake] section to new ones
1697 ## Constructor of DscBuildData
1699 # Initialize object of DscBuildData
1701 # @param FilePath The path of platform description file
1702 # @param RawData The raw data of DSC file
1703 # @param BuildDataBase Database used to retrieve module/package information
1704 # @param Arch The target architecture
1705 # @param Platform The name of platform employing this module
1706 # @param Macros Macros used for replacement in DSC file
1708 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1709 self
.MetaFile
= FilePath
1710 self
._ModuleDir
= FilePath
.Dir
1711 self
._RawData
= RawData
1712 self
._Bdb
= BuildDatabase
1714 self
._Target
= Target
1715 self
._Toolchain
= Toolchain
1716 self
._Platform
= 'COMMON'
1717 self
._SourceOverridePath
= None
1718 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1719 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1723 def __setitem__(self
, key
, value
):
1724 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1727 def __getitem__(self
, key
):
1728 return self
.__dict
__[self
._PROPERTY
_[key
]]
1730 ## "in" test support
1731 def __contains__(self
, key
):
1732 return key
in self
._PROPERTY
_
1734 ## Set all internal used members of InfBuildData to None
1736 self
._HeaderComments
= None
1737 self
._TailComments
= None
1738 self
._Header
_ = None
1739 self
._AutoGenVersion
= None
1740 self
._BaseName
= None
1741 self
._DxsFile
= None
1742 self
._ModuleType
= None
1743 self
._ComponentType
= None
1744 self
._BuildType
= None
1746 self
._Version
= None
1747 self
._PcdIsDriver
= None
1748 self
._BinaryModule
= None
1750 self
._MakefileName
= None
1751 self
._CustomMakefile
= None
1752 self
._Specification
= None
1753 self
._LibraryClass
= None
1754 self
._ModuleEntryPointList
= None
1755 self
._ModuleUnloadImageList
= None
1756 self
._ConstructorList
= None
1757 self
._DestructorList
= None
1759 self
._Binaries
= None
1760 self
._Sources
= None
1761 self
._LibraryClasses
= None
1762 self
._Libraries
= None
1763 self
._Protocols
= None
1764 self
._ProtocolComments
= None
1766 self
._PpiComments
= None
1768 self
._GuidsUsedByPcd
= sdict()
1769 self
._GuidComments
= None
1770 self
._Includes
= None
1771 self
._Packages
= None
1773 self
._PcdComments
= None
1774 self
._BuildOptions
= None
1776 self
._DepexExpression
= None
1777 self
.__Macros
= None
1779 ## Get current effective macros
1780 def _GetMacros(self
):
1781 if self
.__Macros
== None:
1783 # EDK_GLOBAL defined macros can be applied to EDK module
1784 if self
.AutoGenVersion
< 0x00010005:
1785 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1786 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1787 return self
.__Macros
1795 # Changing the default ARCH to another may affect all other information
1796 # because all information in a platform may be ARCH-related. That's
1797 # why we need to clear all internal used members, in order to cause all
1798 # information to be re-retrieved.
1800 # @param Value The value of ARCH
1802 def _SetArch(self
, Value
):
1803 if self
._Arch
== Value
:
1808 ## Return the name of platform employing this module
1809 def _GetPlatform(self
):
1810 return self
._Platform
1812 ## Change the name of platform employing this module
1814 # Changing the default name of platform to another may affect some information
1815 # because they may be PLATFORM-related. That's why we need to clear all internal
1816 # used members, in order to cause all information to be re-retrieved.
1818 def _SetPlatform(self
, Value
):
1819 if self
._Platform
== Value
:
1821 self
._Platform
= Value
1823 def _GetHeaderComments(self
):
1824 if not self
._HeaderComments
:
1825 self
._HeaderComments
= []
1826 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1827 for Record
in RecordList
:
1828 self
._HeaderComments
.append(Record
[0])
1829 return self
._HeaderComments
1830 def _GetTailComments(self
):
1831 if not self
._TailComments
:
1832 self
._TailComments
= []
1833 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1834 for Record
in RecordList
:
1835 self
._TailComments
.append(Record
[0])
1836 return self
._TailComments
1837 ## Retrieve all information in [Defines] section
1839 # (Retriving all [Defines] information in one-shot is just to save time.)
1841 def _GetHeaderInfo(self
):
1842 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1843 for Record
in RecordList
:
1844 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1845 # items defined _PROPERTY_ don't need additional processing
1848 if self
._Defs
== None:
1849 self
._Defs
= sdict()
1850 self
._Defs
[Name
] = Value
1851 # some special items in [Defines] section need special treatment
1852 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1853 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1854 Name
= 'UEFI_SPECIFICATION_VERSION'
1855 if self
._Specification
== None:
1856 self
._Specification
= sdict()
1857 self
._Specification
[Name
] = GetHexVerValue(Value
)
1858 if self
._Specification
[Name
] == None:
1859 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1860 "'%s' format is not supported for %s" % (Value
, Name
),
1861 File
=self
.MetaFile
, Line
=Record
[-1])
1862 elif Name
== 'LIBRARY_CLASS':
1863 if self
._LibraryClass
== None:
1864 self
._LibraryClass
= []
1865 ValueList
= GetSplitValueList(Value
)
1866 LibraryClass
= ValueList
[0]
1867 if len(ValueList
) > 1:
1868 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1870 SupModuleList
= SUP_MODULE_LIST
1871 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1872 elif Name
== 'ENTRY_POINT':
1873 if self
._ModuleEntryPointList
== None:
1874 self
._ModuleEntryPointList
= []
1875 self
._ModuleEntryPointList
.append(Value
)
1876 elif Name
== 'UNLOAD_IMAGE':
1877 if self
._ModuleUnloadImageList
== None:
1878 self
._ModuleUnloadImageList
= []
1881 self
._ModuleUnloadImageList
.append(Value
)
1882 elif Name
== 'CONSTRUCTOR':
1883 if self
._ConstructorList
== None:
1884 self
._ConstructorList
= []
1887 self
._ConstructorList
.append(Value
)
1888 elif Name
== 'DESTRUCTOR':
1889 if self
._DestructorList
== None:
1890 self
._DestructorList
= []
1893 self
._DestructorList
.append(Value
)
1894 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1895 TokenList
= GetSplitValueList(Value
)
1896 if self
._CustomMakefile
== None:
1897 self
._CustomMakefile
= {}
1898 if len(TokenList
) < 2:
1899 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1900 self
._CustomMakefile
['GCC'] = TokenList
[0]
1902 if TokenList
[0] not in ['MSFT', 'GCC']:
1903 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1904 "No supported family [%s]" % TokenList
[0],
1905 File
=self
.MetaFile
, Line
=Record
[-1])
1906 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1908 if self
._Defs
== None:
1909 self
._Defs
= sdict()
1910 self
._Defs
[Name
] = Value
1913 # Retrieve information in sections specific to Edk.x modules
1915 if self
.AutoGenVersion
>= 0x00010005:
1916 if not self
._ModuleType
:
1917 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1918 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1919 if self
._ModuleType
not in SUP_MODULE_LIST
:
1920 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1921 for Record
in RecordList
:
1923 if Name
== "MODULE_TYPE":
1926 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1927 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
, ' '.join(l
for l
in SUP_MODULE_LIST
)),
1928 File
=self
.MetaFile
, Line
=LineNo
)
1929 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1930 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1931 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
)
1932 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1933 and 'PCI_CLASS_CODE' in self
._Defs
and 'PCI_REVISION' in self
._Defs
:
1934 self
._BuildType
= 'UEFI_OPTIONROM'
1935 if 'PCI_COMPRESS' in self
._Defs
:
1936 if self
._Defs
['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):
1937 EdkLogger
.error("build", FORMAT_INVALID
, "Expected TRUE/FALSE for PCI_COMPRESS: %s" %self
.MetaFile
)
1939 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1940 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1941 self
._BuildType
= 'UEFI_HII'
1943 self
._BuildType
= self
._ModuleType
.upper()
1946 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1947 # check the file validation
1948 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1950 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1951 File
=self
.MetaFile
, Line
=LineNo
)
1952 if self
.Sources
== None:
1954 self
._Sources
.append(File
)
1956 if not self
._ComponentType
:
1957 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1958 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1959 self
._BuildType
= self
._ComponentType
.upper()
1960 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1961 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1962 if self
._ComponentType
== 'LIBRARY':
1963 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1964 # make use some [nmake] section macros
1965 Macros
= self
._Macros
1966 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1967 Macros
['PROCESSOR'] = self
._Arch
1968 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1969 for Name
, Value
, Dummy
, Arch
, Platform
, ID
, LineNo
in RecordList
:
1970 Value
= ReplaceMacro(Value
, Macros
, True)
1971 if Name
== "IMAGE_ENTRY_POINT":
1972 if self
._ModuleEntryPointList
== None:
1973 self
._ModuleEntryPointList
= []
1974 self
._ModuleEntryPointList
.append(Value
)
1975 elif Name
== "DPX_SOURCE":
1976 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1977 # check the file validation
1978 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1980 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1981 File
=self
.MetaFile
, Line
=LineNo
)
1982 if self
.Sources
== None:
1984 self
._Sources
.append(File
)
1986 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1987 if len(ToolList
) == 0 or len(ToolList
) != 1:
1989 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1990 # File=self.MetaFile, Line=LineNo)
1992 if self
._BuildOptions
== None:
1993 self
._BuildOptions
= sdict()
1995 if ToolList
[0] in self
._TOOL
_CODE
_:
1996 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1999 ToolChain
= "*_*_*_%s_FLAGS" % Tool
2000 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
2001 #ignore not replaced macros in value
2002 ValueList
= GetSplitList(' ' + Value
, '/D')
2003 Dummy
= ValueList
[0]
2004 for Index
in range(1, len(ValueList
)):
2005 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
2007 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
2008 Value
= Dummy
.strip()
2009 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2010 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
2012 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2013 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
2014 # set _Header to non-None in order to avoid database re-querying
2015 self
._Header
_ = 'DUMMY'
2017 ## Retrieve file version
2018 def _GetInfVersion(self
):
2019 if self
._AutoGenVersion
== None:
2020 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
2021 for Record
in RecordList
:
2022 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
2023 if '.' in Record
[2]:
2024 ValueList
= Record
[2].split('.')
2025 Major
= '%04o' % int(ValueList
[0], 0)
2026 Minor
= '%04o' % int(ValueList
[1], 0)
2027 self
._AutoGenVersion
= int('0x' + Major
+ Minor
, 0)
2029 self
._AutoGenVersion
= int(Record
[2], 0)
2031 if self
._AutoGenVersion
== None:
2032 self
._AutoGenVersion
= 0x00010000
2033 return self
._AutoGenVersion
2035 ## Retrieve BASE_NAME
2036 def _GetBaseName(self
):
2037 if self
._BaseName
== None:
2038 if self
._Header
_ == None:
2039 self
._GetHeaderInfo
()
2040 if self
._BaseName
== None:
2041 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
2042 return self
._BaseName
2045 def _GetDxsFile(self
):
2046 if self
._DxsFile
== None:
2047 if self
._Header
_ == None:
2048 self
._GetHeaderInfo
()
2049 if self
._DxsFile
== None:
2051 return self
._DxsFile
2053 ## Retrieve MODULE_TYPE
2054 def _GetModuleType(self
):
2055 if self
._ModuleType
== None:
2056 if self
._Header
_ == None:
2057 self
._GetHeaderInfo
()
2058 if self
._ModuleType
== None:
2059 self
._ModuleType
= 'BASE'
2060 if self
._ModuleType
not in SUP_MODULE_LIST
:
2061 self
._ModuleType
= "USER_DEFINED"
2062 return self
._ModuleType
2064 ## Retrieve COMPONENT_TYPE
2065 def _GetComponentType(self
):
2066 if self
._ComponentType
== None:
2067 if self
._Header
_ == None:
2068 self
._GetHeaderInfo
()
2069 if self
._ComponentType
== None:
2070 self
._ComponentType
= 'USER_DEFINED'
2071 return self
._ComponentType
2073 ## Retrieve "BUILD_TYPE"
2074 def _GetBuildType(self
):
2075 if self
._BuildType
== None:
2076 if self
._Header
_ == None:
2077 self
._GetHeaderInfo
()
2078 if not self
._BuildType
:
2079 self
._BuildType
= "BASE"
2080 return self
._BuildType
2082 ## Retrieve file guid
2083 def _GetFileGuid(self
):
2084 if self
._Guid
== None:
2085 if self
._Header
_ == None:
2086 self
._GetHeaderInfo
()
2087 if self
._Guid
== None:
2088 self
._Guid
= '00000000-0000-0000-0000-000000000000'
2091 ## Retrieve module version
2092 def _GetVersion(self
):
2093 if self
._Version
== None:
2094 if self
._Header
_ == None:
2095 self
._GetHeaderInfo
()
2096 if self
._Version
== None:
2097 self
._Version
= '0.0'
2098 return self
._Version
2100 ## Retrieve PCD_IS_DRIVER
2101 def _GetPcdIsDriver(self
):
2102 if self
._PcdIsDriver
== None:
2103 if self
._Header
_ == None:
2104 self
._GetHeaderInfo
()
2105 if self
._PcdIsDriver
== None:
2106 self
._PcdIsDriver
= ''
2107 return self
._PcdIsDriver
2110 def _GetShadow(self
):
2111 if self
._Shadow
== None:
2112 if self
._Header
_ == None:
2113 self
._GetHeaderInfo
()
2114 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
2117 self
._Shadow
= False
2120 ## Retrieve CUSTOM_MAKEFILE
2121 def _GetMakefile(self
):
2122 if self
._CustomMakefile
== None:
2123 if self
._Header
_ == None:
2124 self
._GetHeaderInfo
()
2125 if self
._CustomMakefile
== None:
2126 self
._CustomMakefile
= {}
2127 return self
._CustomMakefile
2129 ## Retrieve EFI_SPECIFICATION_VERSION
2131 if self
._Specification
== None:
2132 if self
._Header
_ == None:
2133 self
._GetHeaderInfo
()
2134 if self
._Specification
== None:
2135 self
._Specification
= {}
2136 return self
._Specification
2138 ## Retrieve LIBRARY_CLASS
2139 def _GetLibraryClass(self
):
2140 if self
._LibraryClass
== None:
2141 if self
._Header
_ == None:
2142 self
._GetHeaderInfo
()
2143 if self
._LibraryClass
== None:
2144 self
._LibraryClass
= []
2145 return self
._LibraryClass
2147 ## Retrieve ENTRY_POINT
2148 def _GetEntryPoint(self
):
2149 if self
._ModuleEntryPointList
== None:
2150 if self
._Header
_ == None:
2151 self
._GetHeaderInfo
()
2152 if self
._ModuleEntryPointList
== None:
2153 self
._ModuleEntryPointList
= []
2154 return self
._ModuleEntryPointList
2156 ## Retrieve UNLOAD_IMAGE
2157 def _GetUnloadImage(self
):
2158 if self
._ModuleUnloadImageList
== None:
2159 if self
._Header
_ == None:
2160 self
._GetHeaderInfo
()
2161 if self
._ModuleUnloadImageList
== None:
2162 self
._ModuleUnloadImageList
= []
2163 return self
._ModuleUnloadImageList
2165 ## Retrieve CONSTRUCTOR
2166 def _GetConstructor(self
):
2167 if self
._ConstructorList
== None:
2168 if self
._Header
_ == None:
2169 self
._GetHeaderInfo
()
2170 if self
._ConstructorList
== None:
2171 self
._ConstructorList
= []
2172 return self
._ConstructorList
2174 ## Retrieve DESTRUCTOR
2175 def _GetDestructor(self
):
2176 if self
._DestructorList
== None:
2177 if self
._Header
_ == None:
2178 self
._GetHeaderInfo
()
2179 if self
._DestructorList
== None:
2180 self
._DestructorList
= []
2181 return self
._DestructorList
2183 ## Retrieve definies other than above ones
2184 def _GetDefines(self
):
2185 if self
._Defs
== None:
2186 if self
._Header
_ == None:
2187 self
._GetHeaderInfo
()
2188 if self
._Defs
== None:
2189 self
._Defs
= sdict()
2192 ## Retrieve binary files
2193 def _GetBinaries(self
):
2194 if self
._Binaries
== None:
2196 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2197 Macros
= self
._Macros
2198 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2199 Macros
['PROCESSOR'] = self
._Arch
2200 for Record
in RecordList
:
2201 FileType
= Record
[0]
2206 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2208 Target
= TokenList
[0]
2209 if len(TokenList
) > 1:
2210 FeatureFlag
= Record
[1:]
2212 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2213 # check the file validation
2214 ErrorCode
, ErrorInfo
= File
.Validate()
2216 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2217 self
._Binaries
.append(File
)
2218 return self
._Binaries
2220 ## Retrieve binary files with error check.
2221 def _GetBinaryFiles(self
):
2222 Binaries
= self
._GetBinaries
()
2223 if GlobalData
.gIgnoreSource
and Binaries
== []:
2224 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2225 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2228 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2229 def _IsSupportedArch(self
):
2230 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2234 ## Retrieve source files
2235 def _GetSourceFiles(self
):
2236 #Ignore all source files in a binary build mode
2237 if GlobalData
.gIgnoreSource
:
2239 return self
._Sources
2241 if self
._Sources
== None:
2243 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2244 Macros
= self
._Macros
2245 for Record
in RecordList
:
2247 ToolChainFamily
= Record
[1]
2249 ToolCode
= Record
[3]
2250 FeatureFlag
= Record
[4]
2251 if self
.AutoGenVersion
< 0x00010005:
2252 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2253 Macros
['PROCESSOR'] = self
._Arch
2254 SourceFile
= NormPath(Record
[0], Macros
)
2255 if SourceFile
[0] == os
.path
.sep
:
2256 SourceFile
= mws
.join(GlobalData
.gWorkspace
, SourceFile
[1:])
2257 # old module source files (Edk)
2258 File
= PathClass(SourceFile
, self
._ModuleDir
, self
._SourceOverridePath
,
2259 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2260 # check the file validation
2261 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2263 if File
.Ext
.lower() == '.h':
2264 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2265 File
=self
.MetaFile
, Line
=LineNo
)
2268 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2270 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2271 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2272 # check the file validation
2273 ErrorCode
, ErrorInfo
= File
.Validate()
2275 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2277 self
._Sources
.append(File
)
2278 return self
._Sources
2280 ## Retrieve library classes employed by this module
2281 def _GetLibraryClassUses(self
):
2282 if self
._LibraryClasses
== None:
2283 self
._LibraryClasses
= sdict()
2284 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2285 for Record
in RecordList
:
2287 Instance
= Record
[1]
2289 Instance
= NormPath(Instance
, self
._Macros
)
2290 self
._LibraryClasses
[Lib
] = Instance
2291 return self
._LibraryClasses
2293 ## Retrieve library names (for Edk.x style of modules)
2294 def _GetLibraryNames(self
):
2295 if self
._Libraries
== None:
2296 self
._Libraries
= []
2297 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2298 for Record
in RecordList
:
2299 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2300 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2301 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2302 if LibraryName
not in self
._Libraries
:
2303 self
._Libraries
.append(LibraryName
)
2304 return self
._Libraries
2306 def _GetProtocolComments(self
):
2307 self
._GetProtocols
()
2308 return self
._ProtocolComments
2309 ## Retrieve protocols consumed/produced by this module
2310 def _GetProtocols(self
):
2311 if self
._Protocols
== None:
2312 self
._Protocols
= sdict()
2313 self
._ProtocolComments
= sdict()
2314 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2315 for Record
in RecordList
:
2317 Value
= ProtocolValue(CName
, self
.Packages
, self
.MetaFile
.Path
)
2319 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2320 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2321 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2322 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2323 self
._Protocols
[CName
] = Value
2324 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2326 for CmtRec
in CommentRecords
:
2327 Comments
.append(CmtRec
[0])
2328 self
._ProtocolComments
[CName
] = Comments
2329 return self
._Protocols
2331 def _GetPpiComments(self
):
2333 return self
._PpiComments
2334 ## Retrieve PPIs consumed/produced by this module
2336 if self
._Ppis
== None:
2337 self
._Ppis
= sdict()
2338 self
._PpiComments
= sdict()
2339 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2340 for Record
in RecordList
:
2342 Value
= PpiValue(CName
, self
.Packages
, self
.MetaFile
.Path
)
2344 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2345 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2346 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2347 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2348 self
._Ppis
[CName
] = Value
2349 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2351 for CmtRec
in CommentRecords
:
2352 Comments
.append(CmtRec
[0])
2353 self
._PpiComments
[CName
] = Comments
2356 def _GetGuidComments(self
):
2358 return self
._GuidComments
2359 ## Retrieve GUIDs consumed/produced by this module
2360 def _GetGuids(self
):
2361 if self
._Guids
== None:
2362 self
._Guids
= sdict()
2363 self
._GuidComments
= sdict()
2364 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2365 for Record
in RecordList
:
2367 Value
= GuidValue(CName
, self
.Packages
, self
.MetaFile
.Path
)
2369 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2370 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2371 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2372 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2373 self
._Guids
[CName
] = Value
2374 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2376 for CmtRec
in CommentRecords
:
2377 Comments
.append(CmtRec
[0])
2378 self
._GuidComments
[CName
] = Comments
2381 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2382 def _GetIncludes(self
):
2383 if self
._Includes
== None:
2385 if self
._SourceOverridePath
:
2386 self
._Includes
.append(self
._SourceOverridePath
)
2388 Macros
= self
._Macros
2389 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2390 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2392 Macros
['PROCESSOR'] = self
._Arch
2393 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2394 for Record
in RecordList
:
2395 if Record
[0].find('EDK_SOURCE') > -1:
2396 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2397 File
= NormPath(Record
[0], self
._Macros
)
2399 File
= os
.path
.join(self
._ModuleDir
, File
)
2401 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2402 File
= RealPath(os
.path
.normpath(File
))
2404 self
._Includes
.append(File
)
2406 #TRICK: let compiler to choose correct header file
2407 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2408 File
= NormPath(Record
[0], self
._Macros
)
2410 File
= os
.path
.join(self
._ModuleDir
, File
)
2412 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2413 File
= RealPath(os
.path
.normpath(File
))
2415 self
._Includes
.append(File
)
2417 File
= NormPath(Record
[0], Macros
)
2419 File
= os
.path
.join(self
._ModuleDir
, File
)
2421 File
= mws
.join(GlobalData
.gWorkspace
, File
)
2422 File
= RealPath(os
.path
.normpath(File
))
2424 self
._Includes
.append(File
)
2425 if not File
and Record
[0].find('EFI_SOURCE') > -1:
2426 # tricky to regard WorkSpace as EFI_SOURCE
2427 Macros
['EFI_SOURCE'] = GlobalData
.gWorkspace
2428 File
= NormPath(Record
[0], Macros
)
2430 File
= os
.path
.join(self
._ModuleDir
, File
)
2432 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2433 File
= RealPath(os
.path
.normpath(File
))
2435 self
._Includes
.append(File
)
2436 return self
._Includes
2438 ## Retrieve packages this module depends on
2439 def _GetPackages(self
):
2440 if self
._Packages
== None:
2442 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2443 Macros
= self
._Macros
2444 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2445 for Record
in RecordList
:
2446 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2448 # check the file validation
2449 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2451 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2452 # parse this package now. we need it to get protocol/ppi/guid value
2453 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2454 self
._Packages
.append(Package
)
2455 return self
._Packages
2457 ## Retrieve PCD comments
2458 def _GetPcdComments(self
):
2460 return self
._PcdComments
2461 ## Retrieve PCDs used in this module
2463 if self
._Pcds
== None:
2464 self
._Pcds
= sdict()
2465 self
._PcdComments
= sdict()
2466 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2467 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2468 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2469 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2470 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2473 ## Retrieve build options specific to this module
2474 def _GetBuildOptions(self
):
2475 if self
._BuildOptions
== None:
2476 self
._BuildOptions
= sdict()
2477 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2478 for Record
in RecordList
:
2479 ToolChainFamily
= Record
[0]
2480 ToolChain
= Record
[1]
2482 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
or Option
.startswith('='):
2483 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2485 # concatenate the option string if they're for the same tool
2486 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2487 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2488 return self
._BuildOptions
2490 ## Retrieve dependency expression
2491 def _GetDepex(self
):
2492 if self
._Depex
== None:
2493 self
._Depex
= tdict(False, 2)
2494 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2496 # If the module has only Binaries and no Sources, then ignore [Depex]
2497 if self
.Sources
== None or self
.Sources
== []:
2498 if self
.Binaries
!= None and self
.Binaries
!= []:
2501 # PEIM and DXE drivers must have a valid [Depex] section
2502 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2503 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2504 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2505 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2506 % self
.ModuleType
, File
=self
.MetaFile
)
2508 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2509 for Record
in RecordList
:
2510 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2511 EdkLogger
.error('build', FORMAT_INVALID
,
2512 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2516 for Record
in RecordList
:
2517 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2519 ModuleType
= Record
[4]
2520 TokenList
= DepexStr
.split()
2521 if (Arch
, ModuleType
) not in Depex
:
2522 Depex
[Arch
, ModuleType
] = []
2523 DepexList
= Depex
[Arch
, ModuleType
]
2524 for Token
in TokenList
:
2525 if Token
in DEPEX_SUPPORTED_OPCODE
:
2526 DepexList
.append(Token
)
2527 elif Token
.endswith(".inf"): # module file name
2528 ModuleFile
= os
.path
.normpath(Token
)
2529 Module
= self
.BuildDatabase
[ModuleFile
]
2531 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2532 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2533 DepexList
.append(Module
.Guid
)
2535 # get the GUID value now
2536 Value
= ProtocolValue(Token
, self
.Packages
, self
.MetaFile
.Path
)
2538 Value
= PpiValue(Token
, self
.Packages
, self
.MetaFile
.Path
)
2540 Value
= GuidValue(Token
, self
.Packages
, self
.MetaFile
.Path
)
2542 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2543 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2544 "Value of [%s] is not found in" % Token
,
2545 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2546 DepexList
.append(Value
)
2547 for Arch
, ModuleType
in Depex
:
2548 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2551 ## Retrieve depedency expression
2552 def _GetDepexExpression(self
):
2553 if self
._DepexExpression
== None:
2554 self
._DepexExpression
= tdict(False, 2)
2555 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2556 DepexExpression
= sdict()
2557 for Record
in RecordList
:
2558 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2560 ModuleType
= Record
[4]
2561 TokenList
= DepexStr
.split()
2562 if (Arch
, ModuleType
) not in DepexExpression
:
2563 DepexExpression
[Arch
, ModuleType
] = ''
2564 for Token
in TokenList
:
2565 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2566 for Arch
, ModuleType
in DepexExpression
:
2567 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2568 return self
._DepexExpression
2570 def GetGuidsUsedByPcd(self
):
2571 return self
._GuidsUsedByPcd
2572 ## Retrieve PCD for given type
2573 def _GetPcd(self
, Type
):
2575 PcdDict
= tdict(True, 4)
2577 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2578 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2579 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2580 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2581 # get the guid value
2582 if TokenSpaceGuid
not in self
.Guids
:
2583 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
, self
.MetaFile
.Path
)
2585 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2586 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2587 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2588 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2589 self
.Guids
[TokenSpaceGuid
] = Value
2590 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2591 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2593 for CmtRec
in CommentRecords
:
2594 Comments
.append(CmtRec
[0])
2595 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2597 # resolve PCD type, value, datum info, etc. by getting its definition from package
2598 for PcdCName
, TokenSpaceGuid
in PcdList
:
2599 PcdRealName
= PcdCName
2600 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2603 ValueList
= AnalyzePcdData(Setting
)
2604 DefaultValue
= ValueList
[0]
2605 Pcd
= PcdClassObject(
2615 self
.Guids
[TokenSpaceGuid
]
2617 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2618 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2619 Pcd
.Offset
= ValueList
[1]
2621 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
2622 for Package
in self
.Packages
:
2623 for key
in Package
.Pcds
:
2624 if (Package
.Pcds
[key
].TokenCName
, Package
.Pcds
[key
].TokenSpaceGuidCName
) == (PcdRealName
, TokenSpaceGuid
):
2625 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
2626 Pcd_Type
= item
[0].split('_')[-1]
2627 if Pcd_Type
== Package
.Pcds
[key
].Type
:
2628 Value
= Package
.Pcds
[key
]
2629 Value
.TokenCName
= Package
.Pcds
[key
].TokenCName
+ '_' + Pcd_Type
2631 newkey
= (Value
.TokenCName
, key
[1])
2633 newkey
= (Value
.TokenCName
, key
[1], key
[2])
2634 del Package
.Pcds
[key
]
2635 Package
.Pcds
[newkey
] = Value
2642 # get necessary info from package declaring this PCD
2643 for Package
in self
.Packages
:
2645 # 'dynamic' in INF means its type is determined by platform;
2646 # if platform doesn't give its type, use 'lowest' one in the
2647 # following order, if any
2649 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2651 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2652 if Type
== MODEL_PCD_DYNAMIC
:
2654 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2655 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
2656 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
2657 if str(item
[0]).endswith(T
) and (item
[0], item
[1], T
) in Package
.Pcds
:
2665 if (PcdRealName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2671 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
2672 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
2673 Pcd_Type
= item
[0].split('_')[-1]
2674 if Pcd_Type
== PcdType
:
2682 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2683 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2685 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2688 # Check whether the token value exist or not.
2690 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2694 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdRealName
, str(Package
)),
2695 File
=self
.MetaFile
, Line
=LineNo
,
2699 # Check hexadecimal token value length and format.
2701 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2702 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2703 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2707 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdRealName
, str(Package
)),
2708 File
=self
.MetaFile
, Line
=LineNo
,
2713 # Check decimal token value length and format.
2717 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2718 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2722 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdRealName
, str(Package
)),
2723 File
=self
.MetaFile
, Line
=LineNo
,
2730 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdRealName
, str(Package
)),
2731 File
=self
.MetaFile
, Line
=LineNo
,
2735 Pcd
.DatumType
= PcdInPackage
.DatumType
2736 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2737 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2738 if Pcd
.DefaultValue
in [None, '']:
2739 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2745 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdRealName
, self
.MetaFile
),
2746 File
=self
.MetaFile
, Line
=LineNo
,
2747 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2749 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2753 ## check whether current module is binary module
2754 def _IsBinaryModule(self
):
2755 if self
.Binaries
and not self
.Sources
:
2757 elif GlobalData
.gIgnoreSource
:
2762 _Macros
= property(_GetMacros
)
2763 Arch
= property(_GetArch
, _SetArch
)
2764 Platform
= property(_GetPlatform
, _SetPlatform
)
2766 HeaderComments
= property(_GetHeaderComments
)
2767 TailComments
= property(_GetTailComments
)
2768 AutoGenVersion
= property(_GetInfVersion
)
2769 BaseName
= property(_GetBaseName
)
2770 ModuleType
= property(_GetModuleType
)
2771 ComponentType
= property(_GetComponentType
)
2772 BuildType
= property(_GetBuildType
)
2773 Guid
= property(_GetFileGuid
)
2774 Version
= property(_GetVersion
)
2775 PcdIsDriver
= property(_GetPcdIsDriver
)
2776 Shadow
= property(_GetShadow
)
2777 CustomMakefile
= property(_GetMakefile
)
2778 Specification
= property(_GetSpec
)
2779 LibraryClass
= property(_GetLibraryClass
)
2780 ModuleEntryPointList
= property(_GetEntryPoint
)
2781 ModuleUnloadImageList
= property(_GetUnloadImage
)
2782 ConstructorList
= property(_GetConstructor
)
2783 DestructorList
= property(_GetDestructor
)
2784 Defines
= property(_GetDefines
)
2785 DxsFile
= property(_GetDxsFile
)
2787 Binaries
= property(_GetBinaryFiles
)
2788 Sources
= property(_GetSourceFiles
)
2789 LibraryClasses
= property(_GetLibraryClassUses
)
2790 Libraries
= property(_GetLibraryNames
)
2791 Protocols
= property(_GetProtocols
)
2792 ProtocolComments
= property(_GetProtocolComments
)
2793 Ppis
= property(_GetPpis
)
2794 PpiComments
= property(_GetPpiComments
)
2795 Guids
= property(_GetGuids
)
2796 GuidComments
= property(_GetGuidComments
)
2797 Includes
= property(_GetIncludes
)
2798 Packages
= property(_GetPackages
)
2799 Pcds
= property(_GetPcds
)
2800 PcdComments
= property(_GetPcdComments
)
2801 BuildOptions
= property(_GetBuildOptions
)
2802 Depex
= property(_GetDepex
)
2803 DepexExpression
= property(_GetDepexExpression
)
2804 IsBinaryModule
= property(_IsBinaryModule
)
2805 IsSupportedArch
= property(_IsSupportedArch
)
2809 # This class defined the build database for all modules, packages and platform.
2810 # It will call corresponding parser for the given file if it cannot find it in
2813 # @param DbPath Path of database file
2814 # @param GlobalMacros Global macros used for replacement during file parsing
2815 # @prarm RenewDb=False Create new database file if it's already there
2817 class WorkspaceDatabase(object):
2821 # internal class used for call corresponding file parser and caching the result
2822 # to avoid unnecessary re-parsing
2824 class BuildObjectFactory(object):
2827 ".inf" : MODEL_FILE_INF
,
2828 ".dec" : MODEL_FILE_DEC
,
2829 ".dsc" : MODEL_FILE_DSC
,
2834 MODEL_FILE_INF
: InfParser
,
2835 MODEL_FILE_DEC
: DecParser
,
2836 MODEL_FILE_DSC
: DscParser
,
2839 # convert to xxxBuildData object
2841 MODEL_FILE_INF
: InfBuildData
,
2842 MODEL_FILE_DEC
: DecBuildData
,
2843 MODEL_FILE_DSC
: DscBuildData
,
2846 _CACHE_
= {} # (FilePath, Arch) : <object>
2849 def __init__(self
, WorkspaceDb
):
2850 self
.WorkspaceDb
= WorkspaceDb
2852 # key = (FilePath, Arch=None)
2853 def __contains__(self
, Key
):
2859 return (FilePath
, Arch
) in self
._CACHE
_
2861 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2862 def __getitem__(self
, Key
):
2864 KeyLength
= len(Key
)
2878 # if it's generated before, just return the cached one
2879 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2880 if Key
in self
._CACHE
_:
2881 return self
._CACHE
_[Key
]
2885 if Ext
not in self
._FILE
_TYPE
_:
2887 FileType
= self
._FILE
_TYPE
_[Ext
]
2888 if FileType
not in self
._GENERATOR
_:
2891 # get the parser ready for this file
2892 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2896 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2898 # alwasy do post-process, in case of macros change
2899 MetaFile
.DoPostProcess()
2900 # object the build is based on
2901 BuildObject
= self
._GENERATOR
_[FileType
](
2909 self
._CACHE
_[Key
] = BuildObject
2912 # placeholder for file format conversion
2913 class TransformObjectFactory
:
2914 def __init__(self
, WorkspaceDb
):
2915 self
.WorkspaceDb
= WorkspaceDb
2917 # key = FilePath, Arch
2918 def __getitem__(self
, Key
):
2921 ## Constructor of WorkspaceDatabase
2923 # @param DbPath Path of database file
2924 # @param GlobalMacros Global macros used for replacement during file parsing
2925 # @prarm RenewDb=False Create new database file if it's already there
2927 def __init__(self
, DbPath
, RenewDb
=False):
2928 self
._DbClosedFlag
= False
2930 DbPath
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2932 # don't create necessary path for db in memory
2933 if DbPath
!= ':memory:':
2934 DbDir
= os
.path
.split(DbPath
)[0]
2935 if not os
.path
.exists(DbDir
):
2938 # remove db file in case inconsistency between db and file in file system
2939 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2942 # create db with optimized parameters
2943 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2944 self
.Conn
.execute("PRAGMA synchronous=OFF")
2945 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2946 self
.Conn
.execute("PRAGMA count_changes=OFF")
2947 self
.Conn
.execute("PRAGMA cache_size=8192")
2948 #self.Conn.execute("PRAGMA page_size=8192")
2950 # to avoid non-ascii character conversion issue
2951 self
.Conn
.text_factory
= str
2952 self
.Cur
= self
.Conn
.cursor()
2954 # create table for internal uses
2955 self
.TblDataModel
= TableDataModel(self
.Cur
)
2956 self
.TblFile
= TableFile(self
.Cur
)
2957 self
.Platform
= None
2959 # conversion object for build or file format conversion purpose
2960 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2961 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2963 ## Check whether workspace database need to be renew.
2964 # The renew reason maybe:
2965 # 1) If user force to renew;
2966 # 2) If user do not force renew, and
2967 # a) If the time of last modified python source is newer than database file;
2968 # b) If the time of last modified frozen executable file is newer than database file;
2970 # @param force User force renew database
2971 # @param DbPath The absolute path of workspace database file
2973 # @return Bool value for whether need renew workspace databse
2975 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2976 # if database does not exist, we need do nothing
2977 if not os
.path
.exists(DbPath
): return False
2979 # if user force to renew database, then not check whether database is out of date
2980 if force
: return True
2983 # Check the time of last modified source file or build.exe
2984 # if is newer than time of database, then database need to be re-created.
2986 timeOfToolModified
= 0
2987 if hasattr(sys
, "frozen"):
2988 exePath
= os
.path
.abspath(sys
.executable
)
2989 timeOfToolModified
= os
.stat(exePath
).st_mtime
2991 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2992 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2993 if rootPath
== "" or rootPath
== None:
2994 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2995 determine whether database file is out of date!\n")
2997 # walk the root path of source or build's binary to get the time last modified.
2999 for root
, dirs
, files
in os
.walk (rootPath
):
3001 # bypass source control folder
3002 if dir.lower() in [".svn", "_svn", "cvs"]:
3006 ext
= os
.path
.splitext(file)[1]
3007 if ext
.lower() == ".py": # only check .py files
3008 fd
= os
.stat(os
.path
.join(root
, file))
3009 if timeOfToolModified
< fd
.st_mtime
:
3010 timeOfToolModified
= fd
.st_mtime
3011 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
3012 EdkLogger
.verbose("\nWorkspace database is out of data!")
3017 ## Initialize build database
3018 def InitDatabase(self
):
3019 EdkLogger
.verbose("\nInitialize build database started ...")
3024 self
.TblDataModel
.Create(False)
3025 self
.TblFile
.Create(False)
3028 # Initialize table DataModel
3030 self
.TblDataModel
.InitTable()
3031 EdkLogger
.verbose("Initialize build database ... DONE!")
3035 # @param Table: The instance of the table to be queried
3037 def QueryTable(self
, Table
):
3043 ## Close entire database
3046 # Close the connection and cursor
3049 if not self
._DbClosedFlag
:
3053 self
._DbClosedFlag
= True
3055 ## Summarize all packages in the database
3056 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
3057 self
.Platform
= Platform
3059 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
3061 # Get Package related to Modules
3063 for Module
in Pa
.Modules
:
3064 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
3065 for Package
in ModuleObj
.Packages
:
3066 if Package
not in PackageList
:
3067 PackageList
.append(Package
)
3069 # Get Packages related to Libraries
3071 for Lib
in Pa
.LibraryInstances
:
3072 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
3073 for Package
in LibObj
.Packages
:
3074 if Package
not in PackageList
:
3075 PackageList
.append(Package
)
3079 ## Summarize all platforms in the database
3080 def _GetPlatformList(self
):
3082 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
3084 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
3087 if Platform
!= None:
3088 PlatformList
.append(Platform
)
3091 def _MapPlatform(self
, Dscfile
):
3092 Platform
= self
.BuildObject
[PathClass(Dscfile
), 'COMMON']
3093 if Platform
== None:
3094 EdkLogger
.error('build', PARSER_ERROR
, "Failed to parser DSC file: %s" % Dscfile
)
3097 PlatformList
= property(_GetPlatformList
)
3101 # This acts like the main() function for the script, unless it is 'import'ed into another
3104 if __name__
== '__main__':