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
1332 ## Get current effective macros
1333 def _GetMacros(self
):
1334 if self
.__Macros
== None:
1336 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1337 return self
.__Macros
1345 # Changing the default ARCH to another may affect all other information
1346 # because all information in a platform may be ARCH-related. That's
1347 # why we need to clear all internal used members, in order to cause all
1348 # information to be re-retrieved.
1350 # @param Value The value of ARCH
1352 def _SetArch(self
, Value
):
1353 if self
._Arch
== Value
:
1358 ## Retrieve all information in [Defines] section
1360 # (Retriving all [Defines] information in one-shot is just to save time.)
1362 def _GetHeaderInfo(self
):
1363 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1364 for Record
in RecordList
:
1367 self
[Name
] = Record
[2]
1368 self
._Header
= 'DUMMY'
1370 ## Retrieve package name
1371 def _GetPackageName(self
):
1372 if self
._PackageName
== None:
1373 if self
._Header
== None:
1374 self
._GetHeaderInfo
()
1375 if self
._PackageName
== None:
1376 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1377 return self
._PackageName
1379 ## Retrieve file guid
1380 def _GetFileGuid(self
):
1381 if self
._Guid
== None:
1382 if self
._Header
== None:
1383 self
._GetHeaderInfo
()
1384 if self
._Guid
== None:
1385 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1388 ## Retrieve package version
1389 def _GetVersion(self
):
1390 if self
._Version
== None:
1391 if self
._Header
== None:
1392 self
._GetHeaderInfo
()
1393 if self
._Version
== None:
1395 return self
._Version
1397 ## Retrieve protocol definitions (name/value pairs)
1398 def _GetProtocol(self
):
1399 if self
._Protocols
== None:
1401 # tdict is a special kind of dict, used for selecting correct
1402 # protocol defition for given ARCH
1404 ProtocolDict
= tdict(True)
1406 # find out all protocol definitions for specific and 'common' arch
1407 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1408 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1409 if Name
not in NameList
:
1410 NameList
.append(Name
)
1411 ProtocolDict
[Arch
, Name
] = Guid
1412 # use sdict to keep the order
1413 self
._Protocols
= sdict()
1414 for Name
in NameList
:
1416 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1417 # will automatically turn to 'common' ARCH for trying
1419 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1420 return self
._Protocols
1422 ## Retrieve PPI definitions (name/value pairs)
1424 if self
._Ppis
== None:
1426 # tdict is a special kind of dict, used for selecting correct
1427 # PPI defition for given ARCH
1429 PpiDict
= tdict(True)
1431 # find out all PPI definitions for specific arch and 'common' arch
1432 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1433 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1434 if Name
not in NameList
:
1435 NameList
.append(Name
)
1436 PpiDict
[Arch
, Name
] = Guid
1437 # use sdict to keep the order
1438 self
._Ppis
= sdict()
1439 for Name
in NameList
:
1441 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1442 # will automatically turn to 'common' ARCH for trying
1444 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1447 ## Retrieve GUID definitions (name/value pairs)
1449 if self
._Guids
== None:
1451 # tdict is a special kind of dict, used for selecting correct
1452 # GUID defition for given ARCH
1454 GuidDict
= tdict(True)
1456 # find out all protocol definitions for specific and 'common' arch
1457 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1458 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1459 if Name
not in NameList
:
1460 NameList
.append(Name
)
1461 GuidDict
[Arch
, Name
] = Guid
1462 # use sdict to keep the order
1463 self
._Guids
= sdict()
1464 for Name
in NameList
:
1466 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1467 # will automatically turn to 'common' ARCH for trying
1469 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1472 ## Retrieve public include paths declared in this package
1473 def _GetInclude(self
):
1474 if self
._Includes
== None:
1476 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1477 Macros
= self
._Macros
1478 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1479 for Record
in RecordList
:
1480 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1483 ErrorCode
, ErrorInfo
= File
.Validate()
1485 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1487 # avoid duplicate include path
1488 if File
not in self
._Includes
:
1489 self
._Includes
.append(File
)
1490 return self
._Includes
1492 ## Retrieve library class declarations (not used in build at present)
1493 def _GetLibraryClass(self
):
1494 if self
._LibraryClasses
== None:
1496 # tdict is a special kind of dict, used for selecting correct
1497 # library class declaration for given ARCH
1499 LibraryClassDict
= tdict(True)
1500 LibraryClassSet
= set()
1501 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1502 Macros
= self
._Macros
1503 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1504 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1505 # check the file validation
1506 ErrorCode
, ErrorInfo
= File
.Validate()
1508 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1509 LibraryClassSet
.add(LibraryClass
)
1510 LibraryClassDict
[Arch
, LibraryClass
] = File
1511 self
._LibraryClasses
= sdict()
1512 for LibraryClass
in LibraryClassSet
:
1513 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1514 return self
._LibraryClasses
1516 ## Retrieve PCD declarations
1518 if self
._Pcds
== None:
1519 self
._Pcds
= sdict()
1520 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1521 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1522 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1523 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1524 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1527 ## Retrieve PCD declarations for given type
1528 def _GetPcd(self
, Type
):
1531 # tdict is a special kind of dict, used for selecting correct
1532 # PCD declaration for given ARCH
1534 PcdDict
= tdict(True, 3)
1535 # for summarizing PCD
1537 # find out all PCDs of the 'type'
1538 RecordList
= self
._RawData
[Type
, self
._Arch
]
1539 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1540 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1541 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1543 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1545 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1546 # will automatically turn to 'common' ARCH and try again
1548 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1552 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1554 validateranges
, validlists
, expressions
= self
._RawData
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
1555 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1558 self
._PCD
_TYPE
_STRING
_[Type
],
1566 list(validateranges
),
1573 _Macros
= property(_GetMacros
)
1574 Arch
= property(_GetArch
, _SetArch
)
1575 PackageName
= property(_GetPackageName
)
1576 Guid
= property(_GetFileGuid
)
1577 Version
= property(_GetVersion
)
1579 Protocols
= property(_GetProtocol
)
1580 Ppis
= property(_GetPpi
)
1581 Guids
= property(_GetGuid
)
1582 Includes
= property(_GetInclude
)
1583 LibraryClasses
= property(_GetLibraryClass
)
1584 Pcds
= property(_GetPcds
)
1586 ## Module build information from INF file
1588 # This class is used to retrieve information stored in database and convert them
1589 # into ModuleBuildClassObject form for easier use for AutoGen.
1591 class InfBuildData(ModuleBuildClassObject
):
1592 # dict used to convert PCD type in database to string used by build tool
1593 _PCD_TYPE_STRING_
= {
1594 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1595 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1596 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1597 MODEL_PCD_DYNAMIC
: "Dynamic",
1598 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1599 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1600 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1601 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1602 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1603 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1604 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1607 # dict used to convert part of [Defines] to members of InfBuildData directly
1612 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1613 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1614 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1618 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1619 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1620 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1621 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1622 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1623 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1624 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1625 TAB_INF_DEFINES_VERSION
: "_Version",
1626 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1627 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1629 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1632 # dict used to convert Component type to Module type
1635 "SECURITY_CORE" : "SEC",
1636 "PEI_CORE" : "PEI_CORE",
1637 "COMBINED_PEIM_DRIVER" : "PEIM",
1638 "PIC_PEIM" : "PEIM",
1639 "RELOCATABLE_PEIM" : "PEIM",
1640 "PE32_PEIM" : "PEIM",
1641 "BS_DRIVER" : "DXE_DRIVER",
1642 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1643 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1644 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1645 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1646 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1647 # "BS_DRIVER" : "UEFI_DRIVER",
1648 "APPLICATION" : "UEFI_APPLICATION",
1652 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1653 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1654 # dict used to convert old tool name used in [nmake] section to new ones
1662 ## Constructor of DscBuildData
1664 # Initialize object of DscBuildData
1666 # @param FilePath The path of platform description file
1667 # @param RawData The raw data of DSC file
1668 # @param BuildDataBase Database used to retrieve module/package information
1669 # @param Arch The target architecture
1670 # @param Platform The name of platform employing this module
1671 # @param Macros Macros used for replacement in DSC file
1673 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1674 self
.MetaFile
= FilePath
1675 self
._ModuleDir
= FilePath
.Dir
1676 self
._RawData
= RawData
1677 self
._Bdb
= BuildDatabase
1679 self
._Target
= Target
1680 self
._Toolchain
= Toolchain
1681 self
._Platform
= 'COMMON'
1682 self
._SourceOverridePath
= None
1683 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1684 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1688 def __setitem__(self
, key
, value
):
1689 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1692 def __getitem__(self
, key
):
1693 return self
.__dict
__[self
._PROPERTY
_[key
]]
1695 ## "in" test support
1696 def __contains__(self
, key
):
1697 return key
in self
._PROPERTY
_
1699 ## Set all internal used members of InfBuildData to None
1701 self
._HeaderComments
= None
1702 self
._TailComments
= None
1703 self
._Header
_ = None
1704 self
._AutoGenVersion
= None
1705 self
._BaseName
= None
1706 self
._DxsFile
= None
1707 self
._ModuleType
= None
1708 self
._ComponentType
= None
1709 self
._BuildType
= None
1711 self
._Version
= None
1712 self
._PcdIsDriver
= None
1713 self
._BinaryModule
= None
1715 self
._MakefileName
= None
1716 self
._CustomMakefile
= None
1717 self
._Specification
= None
1718 self
._LibraryClass
= None
1719 self
._ModuleEntryPointList
= None
1720 self
._ModuleUnloadImageList
= None
1721 self
._ConstructorList
= None
1722 self
._DestructorList
= None
1724 self
._Binaries
= None
1725 self
._Sources
= None
1726 self
._LibraryClasses
= None
1727 self
._Libraries
= None
1728 self
._Protocols
= None
1729 self
._ProtocolComments
= None
1731 self
._PpiComments
= None
1733 self
._GuidsUsedByPcd
= sdict()
1734 self
._GuidComments
= None
1735 self
._Includes
= None
1736 self
._Packages
= None
1738 self
._PcdComments
= None
1739 self
._BuildOptions
= None
1741 self
._DepexExpression
= None
1742 self
.__Macros
= None
1744 ## Get current effective macros
1745 def _GetMacros(self
):
1746 if self
.__Macros
== None:
1748 # EDK_GLOBAL defined macros can be applied to EDK module
1749 if self
.AutoGenVersion
< 0x00010005:
1750 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1751 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1752 return self
.__Macros
1760 # Changing the default ARCH to another may affect all other information
1761 # because all information in a platform may be ARCH-related. That's
1762 # why we need to clear all internal used members, in order to cause all
1763 # information to be re-retrieved.
1765 # @param Value The value of ARCH
1767 def _SetArch(self
, Value
):
1768 if self
._Arch
== Value
:
1773 ## Return the name of platform employing this module
1774 def _GetPlatform(self
):
1775 return self
._Platform
1777 ## Change the name of platform employing this module
1779 # Changing the default name of platform to another may affect some information
1780 # because they may be PLATFORM-related. That's why we need to clear all internal
1781 # used members, in order to cause all information to be re-retrieved.
1783 def _SetPlatform(self
, Value
):
1784 if self
._Platform
== Value
:
1786 self
._Platform
= Value
1788 def _GetHeaderComments(self
):
1789 if not self
._HeaderComments
:
1790 self
._HeaderComments
= []
1791 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1792 for Record
in RecordList
:
1793 self
._HeaderComments
.append(Record
[0])
1794 return self
._HeaderComments
1795 def _GetTailComments(self
):
1796 if not self
._TailComments
:
1797 self
._TailComments
= []
1798 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1799 for Record
in RecordList
:
1800 self
._TailComments
.append(Record
[0])
1801 return self
._TailComments
1802 ## Retrieve all information in [Defines] section
1804 # (Retriving all [Defines] information in one-shot is just to save time.)
1806 def _GetHeaderInfo(self
):
1807 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1808 for Record
in RecordList
:
1809 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1810 # items defined _PROPERTY_ don't need additional processing
1813 if self
._Defs
== None:
1814 self
._Defs
= sdict()
1815 self
._Defs
[Name
] = Value
1816 # some special items in [Defines] section need special treatment
1817 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1818 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1819 Name
= 'UEFI_SPECIFICATION_VERSION'
1820 if self
._Specification
== None:
1821 self
._Specification
= sdict()
1822 self
._Specification
[Name
] = GetHexVerValue(Value
)
1823 if self
._Specification
[Name
] == None:
1824 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1825 "'%s' format is not supported for %s" % (Value
, Name
),
1826 File
=self
.MetaFile
, Line
=Record
[-1])
1827 elif Name
== 'LIBRARY_CLASS':
1828 if self
._LibraryClass
== None:
1829 self
._LibraryClass
= []
1830 ValueList
= GetSplitValueList(Value
)
1831 LibraryClass
= ValueList
[0]
1832 if len(ValueList
) > 1:
1833 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1835 SupModuleList
= SUP_MODULE_LIST
1836 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1837 elif Name
== 'ENTRY_POINT':
1838 if self
._ModuleEntryPointList
== None:
1839 self
._ModuleEntryPointList
= []
1840 self
._ModuleEntryPointList
.append(Value
)
1841 elif Name
== 'UNLOAD_IMAGE':
1842 if self
._ModuleUnloadImageList
== None:
1843 self
._ModuleUnloadImageList
= []
1846 self
._ModuleUnloadImageList
.append(Value
)
1847 elif Name
== 'CONSTRUCTOR':
1848 if self
._ConstructorList
== None:
1849 self
._ConstructorList
= []
1852 self
._ConstructorList
.append(Value
)
1853 elif Name
== 'DESTRUCTOR':
1854 if self
._DestructorList
== None:
1855 self
._DestructorList
= []
1858 self
._DestructorList
.append(Value
)
1859 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1860 TokenList
= GetSplitValueList(Value
)
1861 if self
._CustomMakefile
== None:
1862 self
._CustomMakefile
= {}
1863 if len(TokenList
) < 2:
1864 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1865 self
._CustomMakefile
['GCC'] = TokenList
[0]
1867 if TokenList
[0] not in ['MSFT', 'GCC']:
1868 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1869 "No supported family [%s]" % TokenList
[0],
1870 File
=self
.MetaFile
, Line
=Record
[-1])
1871 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1873 if self
._Defs
== None:
1874 self
._Defs
= sdict()
1875 self
._Defs
[Name
] = Value
1878 # Retrieve information in sections specific to Edk.x modules
1880 if self
.AutoGenVersion
>= 0x00010005:
1881 if not self
._ModuleType
:
1882 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1883 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1884 if self
._ModuleType
not in SUP_MODULE_LIST
:
1885 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1886 for Record
in RecordList
:
1888 if Name
== "MODULE_TYPE":
1891 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1892 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
, ' '.join(l
for l
in SUP_MODULE_LIST
)),
1893 File
=self
.MetaFile
, Line
=LineNo
)
1894 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1895 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1896 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
)
1897 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1898 and 'PCI_CLASS_CODE' in self
._Defs
:
1899 self
._BuildType
= 'UEFI_OPTIONROM'
1900 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1901 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1902 self
._BuildType
= 'UEFI_HII'
1904 self
._BuildType
= self
._ModuleType
.upper()
1907 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1908 # check the file validation
1909 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1911 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1912 File
=self
.MetaFile
, Line
=LineNo
)
1913 if self
.Sources
== None:
1915 self
._Sources
.append(File
)
1917 if not self
._ComponentType
:
1918 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1919 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1920 self
._BuildType
= self
._ComponentType
.upper()
1921 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1922 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1923 if self
._ComponentType
== 'LIBRARY':
1924 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1925 # make use some [nmake] section macros
1926 Macros
= self
._Macros
1927 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1928 Macros
['PROCESSOR'] = self
._Arch
1929 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1930 for Name
, Value
, Dummy
, Arch
, Platform
, ID
, LineNo
in RecordList
:
1931 Value
= ReplaceMacro(Value
, Macros
, True)
1932 if Name
== "IMAGE_ENTRY_POINT":
1933 if self
._ModuleEntryPointList
== None:
1934 self
._ModuleEntryPointList
= []
1935 self
._ModuleEntryPointList
.append(Value
)
1936 elif Name
== "DPX_SOURCE":
1937 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1938 # check the file validation
1939 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1941 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1942 File
=self
.MetaFile
, Line
=LineNo
)
1943 if self
.Sources
== None:
1945 self
._Sources
.append(File
)
1947 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1948 if len(ToolList
) == 0 or len(ToolList
) != 1:
1950 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1951 # File=self.MetaFile, Line=LineNo)
1953 if self
._BuildOptions
== None:
1954 self
._BuildOptions
= sdict()
1956 if ToolList
[0] in self
._TOOL
_CODE
_:
1957 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1960 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1961 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1962 #ignore not replaced macros in value
1963 ValueList
= GetSplitList(' ' + Value
, '/D')
1964 Dummy
= ValueList
[0]
1965 for Index
in range(1, len(ValueList
)):
1966 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1968 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1969 Value
= Dummy
.strip()
1970 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1971 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1973 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1974 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1975 # set _Header to non-None in order to avoid database re-querying
1976 self
._Header
_ = 'DUMMY'
1978 ## Retrieve file version
1979 def _GetInfVersion(self
):
1980 if self
._AutoGenVersion
== None:
1981 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1982 for Record
in RecordList
:
1983 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1984 if '.' in Record
[2]:
1985 ValueList
= Record
[2].split('.')
1986 Major
= '%04o' % int(ValueList
[0], 0)
1987 Minor
= '%04o' % int(ValueList
[1], 0)
1988 self
._AutoGenVersion
= int('0x' + Major
+ Minor
, 0)
1990 self
._AutoGenVersion
= int(Record
[2], 0)
1992 if self
._AutoGenVersion
== None:
1993 self
._AutoGenVersion
= 0x00010000
1994 return self
._AutoGenVersion
1996 ## Retrieve BASE_NAME
1997 def _GetBaseName(self
):
1998 if self
._BaseName
== None:
1999 if self
._Header
_ == None:
2000 self
._GetHeaderInfo
()
2001 if self
._BaseName
== None:
2002 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
2003 return self
._BaseName
2006 def _GetDxsFile(self
):
2007 if self
._DxsFile
== None:
2008 if self
._Header
_ == None:
2009 self
._GetHeaderInfo
()
2010 if self
._DxsFile
== None:
2012 return self
._DxsFile
2014 ## Retrieve MODULE_TYPE
2015 def _GetModuleType(self
):
2016 if self
._ModuleType
== None:
2017 if self
._Header
_ == None:
2018 self
._GetHeaderInfo
()
2019 if self
._ModuleType
== None:
2020 self
._ModuleType
= 'BASE'
2021 if self
._ModuleType
not in SUP_MODULE_LIST
:
2022 self
._ModuleType
= "USER_DEFINED"
2023 return self
._ModuleType
2025 ## Retrieve COMPONENT_TYPE
2026 def _GetComponentType(self
):
2027 if self
._ComponentType
== None:
2028 if self
._Header
_ == None:
2029 self
._GetHeaderInfo
()
2030 if self
._ComponentType
== None:
2031 self
._ComponentType
= 'USER_DEFINED'
2032 return self
._ComponentType
2034 ## Retrieve "BUILD_TYPE"
2035 def _GetBuildType(self
):
2036 if self
._BuildType
== None:
2037 if self
._Header
_ == None:
2038 self
._GetHeaderInfo
()
2039 if not self
._BuildType
:
2040 self
._BuildType
= "BASE"
2041 return self
._BuildType
2043 ## Retrieve file guid
2044 def _GetFileGuid(self
):
2045 if self
._Guid
== None:
2046 if self
._Header
_ == None:
2047 self
._GetHeaderInfo
()
2048 if self
._Guid
== None:
2049 self
._Guid
= '00000000-0000-0000-0000-000000000000'
2052 ## Retrieve module version
2053 def _GetVersion(self
):
2054 if self
._Version
== None:
2055 if self
._Header
_ == None:
2056 self
._GetHeaderInfo
()
2057 if self
._Version
== None:
2058 self
._Version
= '0.0'
2059 return self
._Version
2061 ## Retrieve PCD_IS_DRIVER
2062 def _GetPcdIsDriver(self
):
2063 if self
._PcdIsDriver
== None:
2064 if self
._Header
_ == None:
2065 self
._GetHeaderInfo
()
2066 if self
._PcdIsDriver
== None:
2067 self
._PcdIsDriver
= ''
2068 return self
._PcdIsDriver
2071 def _GetShadow(self
):
2072 if self
._Shadow
== None:
2073 if self
._Header
_ == None:
2074 self
._GetHeaderInfo
()
2075 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
2078 self
._Shadow
= False
2081 ## Retrieve CUSTOM_MAKEFILE
2082 def _GetMakefile(self
):
2083 if self
._CustomMakefile
== None:
2084 if self
._Header
_ == None:
2085 self
._GetHeaderInfo
()
2086 if self
._CustomMakefile
== None:
2087 self
._CustomMakefile
= {}
2088 return self
._CustomMakefile
2090 ## Retrieve EFI_SPECIFICATION_VERSION
2092 if self
._Specification
== None:
2093 if self
._Header
_ == None:
2094 self
._GetHeaderInfo
()
2095 if self
._Specification
== None:
2096 self
._Specification
= {}
2097 return self
._Specification
2099 ## Retrieve LIBRARY_CLASS
2100 def _GetLibraryClass(self
):
2101 if self
._LibraryClass
== None:
2102 if self
._Header
_ == None:
2103 self
._GetHeaderInfo
()
2104 if self
._LibraryClass
== None:
2105 self
._LibraryClass
= []
2106 return self
._LibraryClass
2108 ## Retrieve ENTRY_POINT
2109 def _GetEntryPoint(self
):
2110 if self
._ModuleEntryPointList
== None:
2111 if self
._Header
_ == None:
2112 self
._GetHeaderInfo
()
2113 if self
._ModuleEntryPointList
== None:
2114 self
._ModuleEntryPointList
= []
2115 return self
._ModuleEntryPointList
2117 ## Retrieve UNLOAD_IMAGE
2118 def _GetUnloadImage(self
):
2119 if self
._ModuleUnloadImageList
== None:
2120 if self
._Header
_ == None:
2121 self
._GetHeaderInfo
()
2122 if self
._ModuleUnloadImageList
== None:
2123 self
._ModuleUnloadImageList
= []
2124 return self
._ModuleUnloadImageList
2126 ## Retrieve CONSTRUCTOR
2127 def _GetConstructor(self
):
2128 if self
._ConstructorList
== None:
2129 if self
._Header
_ == None:
2130 self
._GetHeaderInfo
()
2131 if self
._ConstructorList
== None:
2132 self
._ConstructorList
= []
2133 return self
._ConstructorList
2135 ## Retrieve DESTRUCTOR
2136 def _GetDestructor(self
):
2137 if self
._DestructorList
== None:
2138 if self
._Header
_ == None:
2139 self
._GetHeaderInfo
()
2140 if self
._DestructorList
== None:
2141 self
._DestructorList
= []
2142 return self
._DestructorList
2144 ## Retrieve definies other than above ones
2145 def _GetDefines(self
):
2146 if self
._Defs
== None:
2147 if self
._Header
_ == None:
2148 self
._GetHeaderInfo
()
2149 if self
._Defs
== None:
2150 self
._Defs
= sdict()
2153 ## Retrieve binary files
2154 def _GetBinaries(self
):
2155 if self
._Binaries
== None:
2157 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2158 Macros
= self
._Macros
2159 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2160 Macros
['PROCESSOR'] = self
._Arch
2161 for Record
in RecordList
:
2162 FileType
= Record
[0]
2167 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2169 Target
= TokenList
[0]
2170 if len(TokenList
) > 1:
2171 FeatureFlag
= Record
[1:]
2173 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2174 # check the file validation
2175 ErrorCode
, ErrorInfo
= File
.Validate()
2177 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2178 self
._Binaries
.append(File
)
2179 return self
._Binaries
2181 ## Retrieve binary files with error check.
2182 def _GetBinaryFiles(self
):
2183 Binaries
= self
._GetBinaries
()
2184 if GlobalData
.gIgnoreSource
and Binaries
== []:
2185 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2186 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2189 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2190 def _IsSupportedArch(self
):
2191 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2195 ## Retrieve source files
2196 def _GetSourceFiles(self
):
2197 #Ignore all source files in a binary build mode
2198 if GlobalData
.gIgnoreSource
:
2200 return self
._Sources
2202 if self
._Sources
== None:
2204 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2205 Macros
= self
._Macros
2206 for Record
in RecordList
:
2208 ToolChainFamily
= Record
[1]
2210 ToolCode
= Record
[3]
2211 FeatureFlag
= Record
[4]
2212 if self
.AutoGenVersion
< 0x00010005:
2213 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2214 Macros
['PROCESSOR'] = self
._Arch
2215 SourceFile
= NormPath(Record
[0], Macros
)
2216 if SourceFile
[0] == os
.path
.sep
:
2217 SourceFile
= mws
.join(GlobalData
.gWorkspace
, SourceFile
[1:])
2218 # old module source files (Edk)
2219 File
= PathClass(SourceFile
, self
._ModuleDir
, self
._SourceOverridePath
,
2220 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2221 # check the file validation
2222 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2224 if File
.Ext
.lower() == '.h':
2225 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2226 File
=self
.MetaFile
, Line
=LineNo
)
2229 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2231 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2232 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2233 # check the file validation
2234 ErrorCode
, ErrorInfo
= File
.Validate()
2236 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2238 self
._Sources
.append(File
)
2239 return self
._Sources
2241 ## Retrieve library classes employed by this module
2242 def _GetLibraryClassUses(self
):
2243 if self
._LibraryClasses
== None:
2244 self
._LibraryClasses
= sdict()
2245 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2246 for Record
in RecordList
:
2248 Instance
= Record
[1]
2250 Instance
= NormPath(Instance
, self
._Macros
)
2251 self
._LibraryClasses
[Lib
] = Instance
2252 return self
._LibraryClasses
2254 ## Retrieve library names (for Edk.x style of modules)
2255 def _GetLibraryNames(self
):
2256 if self
._Libraries
== None:
2257 self
._Libraries
= []
2258 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2259 for Record
in RecordList
:
2260 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2261 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2262 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2263 if LibraryName
not in self
._Libraries
:
2264 self
._Libraries
.append(LibraryName
)
2265 return self
._Libraries
2267 def _GetProtocolComments(self
):
2268 self
._GetProtocols
()
2269 return self
._ProtocolComments
2270 ## Retrieve protocols consumed/produced by this module
2271 def _GetProtocols(self
):
2272 if self
._Protocols
== None:
2273 self
._Protocols
= sdict()
2274 self
._ProtocolComments
= sdict()
2275 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2276 for Record
in RecordList
:
2278 Value
= ProtocolValue(CName
, self
.Packages
)
2280 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2281 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2282 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2283 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2284 self
._Protocols
[CName
] = Value
2285 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2287 for CmtRec
in CommentRecords
:
2288 Comments
.append(CmtRec
[0])
2289 self
._ProtocolComments
[CName
] = Comments
2290 return self
._Protocols
2292 def _GetPpiComments(self
):
2294 return self
._PpiComments
2295 ## Retrieve PPIs consumed/produced by this module
2297 if self
._Ppis
== None:
2298 self
._Ppis
= sdict()
2299 self
._PpiComments
= sdict()
2300 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2301 for Record
in RecordList
:
2303 Value
= PpiValue(CName
, self
.Packages
)
2305 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2306 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2307 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2308 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2309 self
._Ppis
[CName
] = Value
2310 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2312 for CmtRec
in CommentRecords
:
2313 Comments
.append(CmtRec
[0])
2314 self
._PpiComments
[CName
] = Comments
2317 def _GetGuidComments(self
):
2319 return self
._GuidComments
2320 ## Retrieve GUIDs consumed/produced by this module
2321 def _GetGuids(self
):
2322 if self
._Guids
== None:
2323 self
._Guids
= sdict()
2324 self
._GuidComments
= sdict()
2325 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2326 for Record
in RecordList
:
2328 Value
= GuidValue(CName
, self
.Packages
)
2330 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2331 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2332 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2333 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2334 self
._Guids
[CName
] = Value
2335 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2337 for CmtRec
in CommentRecords
:
2338 Comments
.append(CmtRec
[0])
2339 self
._GuidComments
[CName
] = Comments
2342 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2343 def _GetIncludes(self
):
2344 if self
._Includes
== None:
2346 if self
._SourceOverridePath
:
2347 self
._Includes
.append(self
._SourceOverridePath
)
2349 Macros
= self
._Macros
2350 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2351 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2353 Macros
['PROCESSOR'] = self
._Arch
2354 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2355 for Record
in RecordList
:
2356 if Record
[0].find('EDK_SOURCE') > -1:
2357 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2358 File
= NormPath(Record
[0], self
._Macros
)
2360 File
= os
.path
.join(self
._ModuleDir
, File
)
2362 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2363 File
= RealPath(os
.path
.normpath(File
))
2365 self
._Includes
.append(File
)
2367 #TRICK: let compiler to choose correct header file
2368 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2369 File
= NormPath(Record
[0], self
._Macros
)
2371 File
= os
.path
.join(self
._ModuleDir
, File
)
2373 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2374 File
= RealPath(os
.path
.normpath(File
))
2376 self
._Includes
.append(File
)
2378 File
= NormPath(Record
[0], Macros
)
2380 File
= os
.path
.join(self
._ModuleDir
, File
)
2382 File
= mws
.join(GlobalData
.gWorkspace
, File
)
2383 File
= RealPath(os
.path
.normpath(File
))
2385 self
._Includes
.append(File
)
2386 if not File
and Record
[0].find('EFI_SOURCE') > -1:
2387 # tricky to regard WorkSpace as EFI_SOURCE
2388 Macros
['EFI_SOURCE'] = GlobalData
.gWorkspace
2389 File
= NormPath(Record
[0], Macros
)
2391 File
= os
.path
.join(self
._ModuleDir
, File
)
2393 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2394 File
= RealPath(os
.path
.normpath(File
))
2396 self
._Includes
.append(File
)
2397 return self
._Includes
2399 ## Retrieve packages this module depends on
2400 def _GetPackages(self
):
2401 if self
._Packages
== None:
2403 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2404 Macros
= self
._Macros
2405 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2406 for Record
in RecordList
:
2407 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2409 # check the file validation
2410 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2412 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2413 # parse this package now. we need it to get protocol/ppi/guid value
2414 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2415 self
._Packages
.append(Package
)
2416 return self
._Packages
2418 ## Retrieve PCD comments
2419 def _GetPcdComments(self
):
2421 return self
._PcdComments
2422 ## Retrieve PCDs used in this module
2424 if self
._Pcds
== None:
2425 self
._Pcds
= sdict()
2426 self
._PcdComments
= sdict()
2427 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2428 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2429 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2430 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2431 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2434 ## Retrieve build options specific to this module
2435 def _GetBuildOptions(self
):
2436 if self
._BuildOptions
== None:
2437 self
._BuildOptions
= sdict()
2438 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2439 for Record
in RecordList
:
2440 ToolChainFamily
= Record
[0]
2441 ToolChain
= Record
[1]
2443 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
or Option
.startswith('='):
2444 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2446 # concatenate the option string if they're for the same tool
2447 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2448 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2449 return self
._BuildOptions
2451 ## Retrieve dependency expression
2452 def _GetDepex(self
):
2453 if self
._Depex
== None:
2454 self
._Depex
= tdict(False, 2)
2455 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2457 # If the module has only Binaries and no Sources, then ignore [Depex]
2458 if self
.Sources
== None or self
.Sources
== []:
2459 if self
.Binaries
!= None and self
.Binaries
!= []:
2462 # PEIM and DXE drivers must have a valid [Depex] section
2463 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2464 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2465 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2466 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2467 % self
.ModuleType
, File
=self
.MetaFile
)
2469 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2470 for Record
in RecordList
:
2471 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2472 EdkLogger
.error('build', FORMAT_INVALID
,
2473 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2477 for Record
in RecordList
:
2478 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2480 ModuleType
= Record
[4]
2481 TokenList
= DepexStr
.split()
2482 if (Arch
, ModuleType
) not in Depex
:
2483 Depex
[Arch
, ModuleType
] = []
2484 DepexList
= Depex
[Arch
, ModuleType
]
2485 for Token
in TokenList
:
2486 if Token
in DEPEX_SUPPORTED_OPCODE
:
2487 DepexList
.append(Token
)
2488 elif Token
.endswith(".inf"): # module file name
2489 ModuleFile
= os
.path
.normpath(Token
)
2490 Module
= self
.BuildDatabase
[ModuleFile
]
2492 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2493 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2494 DepexList
.append(Module
.Guid
)
2496 # get the GUID value now
2497 Value
= ProtocolValue(Token
, self
.Packages
)
2499 Value
= PpiValue(Token
, self
.Packages
)
2501 Value
= GuidValue(Token
, self
.Packages
)
2503 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2504 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2505 "Value of [%s] is not found in" % Token
,
2506 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2507 DepexList
.append(Value
)
2508 for Arch
, ModuleType
in Depex
:
2509 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2512 ## Retrieve depedency expression
2513 def _GetDepexExpression(self
):
2514 if self
._DepexExpression
== None:
2515 self
._DepexExpression
= tdict(False, 2)
2516 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2517 DepexExpression
= sdict()
2518 for Record
in RecordList
:
2519 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2521 ModuleType
= Record
[4]
2522 TokenList
= DepexStr
.split()
2523 if (Arch
, ModuleType
) not in DepexExpression
:
2524 DepexExpression
[Arch
, ModuleType
] = ''
2525 for Token
in TokenList
:
2526 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2527 for Arch
, ModuleType
in DepexExpression
:
2528 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2529 return self
._DepexExpression
2531 def GetGuidsUsedByPcd(self
):
2532 return self
._GuidsUsedByPcd
2533 ## Retrieve PCD for given type
2534 def _GetPcd(self
, Type
):
2536 PcdDict
= tdict(True, 4)
2538 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2539 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2540 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2541 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2542 # get the guid value
2543 if TokenSpaceGuid
not in self
.Guids
:
2544 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2546 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2547 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2548 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2549 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2550 self
.Guids
[TokenSpaceGuid
] = Value
2551 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2552 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2554 for CmtRec
in CommentRecords
:
2555 Comments
.append(CmtRec
[0])
2556 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2558 # resolve PCD type, value, datum info, etc. by getting its definition from package
2559 for PcdCName
, TokenSpaceGuid
in PcdList
:
2560 PcdRealName
= PcdCName
2561 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2564 ValueList
= AnalyzePcdData(Setting
)
2565 DefaultValue
= ValueList
[0]
2566 Pcd
= PcdClassObject(
2576 self
.Guids
[TokenSpaceGuid
]
2578 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2579 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2580 Pcd
.Offset
= ValueList
[1]
2582 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
2583 for Package
in self
.Packages
:
2584 for key
in Package
.Pcds
:
2585 if (Package
.Pcds
[key
].TokenCName
, Package
.Pcds
[key
].TokenSpaceGuidCName
) == (PcdRealName
, TokenSpaceGuid
):
2586 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
2587 Pcd_Type
= item
[0].split('_')[-1]
2588 if Pcd_Type
== Package
.Pcds
[key
].Type
:
2589 Value
= Package
.Pcds
[key
]
2590 Value
.TokenCName
= Package
.Pcds
[key
].TokenCName
+ '_' + Pcd_Type
2592 newkey
= (Value
.TokenCName
, key
[1])
2594 newkey
= (Value
.TokenCName
, key
[1], key
[2])
2595 del Package
.Pcds
[key
]
2596 Package
.Pcds
[newkey
] = Value
2603 # get necessary info from package declaring this PCD
2604 for Package
in self
.Packages
:
2606 # 'dynamic' in INF means its type is determined by platform;
2607 # if platform doesn't give its type, use 'lowest' one in the
2608 # following order, if any
2610 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2612 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2613 if Type
== MODEL_PCD_DYNAMIC
:
2615 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2616 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
2617 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
2618 if str(item
[0]).endswith(T
) and (item
[0], item
[1], T
) in Package
.Pcds
:
2626 if (PcdRealName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2632 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
2633 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
2634 Pcd_Type
= item
[0].split('_')[-1]
2635 if Pcd_Type
== PcdType
:
2643 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2644 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2646 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2649 # Check whether the token value exist or not.
2651 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2655 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdRealName
, str(Package
)),
2656 File
=self
.MetaFile
, Line
=LineNo
,
2660 # Check hexadecimal token value length and format.
2662 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2663 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2664 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2668 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdRealName
, str(Package
)),
2669 File
=self
.MetaFile
, Line
=LineNo
,
2674 # Check decimal token value length and format.
2678 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2679 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2683 "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
)),
2684 File
=self
.MetaFile
, Line
=LineNo
,
2691 "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
)),
2692 File
=self
.MetaFile
, Line
=LineNo
,
2696 Pcd
.DatumType
= PcdInPackage
.DatumType
2697 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2698 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2699 if Pcd
.DefaultValue
in [None, '']:
2700 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2706 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdRealName
, self
.MetaFile
),
2707 File
=self
.MetaFile
, Line
=LineNo
,
2708 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2710 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2714 ## check whether current module is binary module
2715 def _IsBinaryModule(self
):
2716 if self
.Binaries
and not self
.Sources
:
2718 elif GlobalData
.gIgnoreSource
:
2723 _Macros
= property(_GetMacros
)
2724 Arch
= property(_GetArch
, _SetArch
)
2725 Platform
= property(_GetPlatform
, _SetPlatform
)
2727 HeaderComments
= property(_GetHeaderComments
)
2728 TailComments
= property(_GetTailComments
)
2729 AutoGenVersion
= property(_GetInfVersion
)
2730 BaseName
= property(_GetBaseName
)
2731 ModuleType
= property(_GetModuleType
)
2732 ComponentType
= property(_GetComponentType
)
2733 BuildType
= property(_GetBuildType
)
2734 Guid
= property(_GetFileGuid
)
2735 Version
= property(_GetVersion
)
2736 PcdIsDriver
= property(_GetPcdIsDriver
)
2737 Shadow
= property(_GetShadow
)
2738 CustomMakefile
= property(_GetMakefile
)
2739 Specification
= property(_GetSpec
)
2740 LibraryClass
= property(_GetLibraryClass
)
2741 ModuleEntryPointList
= property(_GetEntryPoint
)
2742 ModuleUnloadImageList
= property(_GetUnloadImage
)
2743 ConstructorList
= property(_GetConstructor
)
2744 DestructorList
= property(_GetDestructor
)
2745 Defines
= property(_GetDefines
)
2746 DxsFile
= property(_GetDxsFile
)
2748 Binaries
= property(_GetBinaryFiles
)
2749 Sources
= property(_GetSourceFiles
)
2750 LibraryClasses
= property(_GetLibraryClassUses
)
2751 Libraries
= property(_GetLibraryNames
)
2752 Protocols
= property(_GetProtocols
)
2753 ProtocolComments
= property(_GetProtocolComments
)
2754 Ppis
= property(_GetPpis
)
2755 PpiComments
= property(_GetPpiComments
)
2756 Guids
= property(_GetGuids
)
2757 GuidComments
= property(_GetGuidComments
)
2758 Includes
= property(_GetIncludes
)
2759 Packages
= property(_GetPackages
)
2760 Pcds
= property(_GetPcds
)
2761 PcdComments
= property(_GetPcdComments
)
2762 BuildOptions
= property(_GetBuildOptions
)
2763 Depex
= property(_GetDepex
)
2764 DepexExpression
= property(_GetDepexExpression
)
2765 IsBinaryModule
= property(_IsBinaryModule
)
2766 IsSupportedArch
= property(_IsSupportedArch
)
2770 # This class defined the build database for all modules, packages and platform.
2771 # It will call corresponding parser for the given file if it cannot find it in
2774 # @param DbPath Path of database file
2775 # @param GlobalMacros Global macros used for replacement during file parsing
2776 # @prarm RenewDb=False Create new database file if it's already there
2778 class WorkspaceDatabase(object):
2782 # internal class used for call corresponding file parser and caching the result
2783 # to avoid unnecessary re-parsing
2785 class BuildObjectFactory(object):
2788 ".inf" : MODEL_FILE_INF
,
2789 ".dec" : MODEL_FILE_DEC
,
2790 ".dsc" : MODEL_FILE_DSC
,
2795 MODEL_FILE_INF
: InfParser
,
2796 MODEL_FILE_DEC
: DecParser
,
2797 MODEL_FILE_DSC
: DscParser
,
2800 # convert to xxxBuildData object
2802 MODEL_FILE_INF
: InfBuildData
,
2803 MODEL_FILE_DEC
: DecBuildData
,
2804 MODEL_FILE_DSC
: DscBuildData
,
2807 _CACHE_
= {} # (FilePath, Arch) : <object>
2810 def __init__(self
, WorkspaceDb
):
2811 self
.WorkspaceDb
= WorkspaceDb
2813 # key = (FilePath, Arch=None)
2814 def __contains__(self
, Key
):
2820 return (FilePath
, Arch
) in self
._CACHE
_
2822 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2823 def __getitem__(self
, Key
):
2825 KeyLength
= len(Key
)
2839 # if it's generated before, just return the cached one
2840 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2841 if Key
in self
._CACHE
_:
2842 return self
._CACHE
_[Key
]
2846 if Ext
not in self
._FILE
_TYPE
_:
2848 FileType
= self
._FILE
_TYPE
_[Ext
]
2849 if FileType
not in self
._GENERATOR
_:
2852 # get the parser ready for this file
2853 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2857 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2859 # alwasy do post-process, in case of macros change
2860 MetaFile
.DoPostProcess()
2861 # object the build is based on
2862 BuildObject
= self
._GENERATOR
_[FileType
](
2870 self
._CACHE
_[Key
] = BuildObject
2873 # placeholder for file format conversion
2874 class TransformObjectFactory
:
2875 def __init__(self
, WorkspaceDb
):
2876 self
.WorkspaceDb
= WorkspaceDb
2878 # key = FilePath, Arch
2879 def __getitem__(self
, Key
):
2882 ## Constructor of WorkspaceDatabase
2884 # @param DbPath Path of database file
2885 # @param GlobalMacros Global macros used for replacement during file parsing
2886 # @prarm RenewDb=False Create new database file if it's already there
2888 def __init__(self
, DbPath
, RenewDb
=False):
2889 self
._DbClosedFlag
= False
2891 DbPath
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2893 # don't create necessary path for db in memory
2894 if DbPath
!= ':memory:':
2895 DbDir
= os
.path
.split(DbPath
)[0]
2896 if not os
.path
.exists(DbDir
):
2899 # remove db file in case inconsistency between db and file in file system
2900 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2903 # create db with optimized parameters
2904 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2905 self
.Conn
.execute("PRAGMA synchronous=OFF")
2906 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2907 self
.Conn
.execute("PRAGMA count_changes=OFF")
2908 self
.Conn
.execute("PRAGMA cache_size=8192")
2909 #self.Conn.execute("PRAGMA page_size=8192")
2911 # to avoid non-ascii character conversion issue
2912 self
.Conn
.text_factory
= str
2913 self
.Cur
= self
.Conn
.cursor()
2915 # create table for internal uses
2916 self
.TblDataModel
= TableDataModel(self
.Cur
)
2917 self
.TblFile
= TableFile(self
.Cur
)
2918 self
.Platform
= None
2920 # conversion object for build or file format conversion purpose
2921 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2922 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2924 ## Check whether workspace database need to be renew.
2925 # The renew reason maybe:
2926 # 1) If user force to renew;
2927 # 2) If user do not force renew, and
2928 # a) If the time of last modified python source is newer than database file;
2929 # b) If the time of last modified frozen executable file is newer than database file;
2931 # @param force User force renew database
2932 # @param DbPath The absolute path of workspace database file
2934 # @return Bool value for whether need renew workspace databse
2936 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2937 # if database does not exist, we need do nothing
2938 if not os
.path
.exists(DbPath
): return False
2940 # if user force to renew database, then not check whether database is out of date
2941 if force
: return True
2944 # Check the time of last modified source file or build.exe
2945 # if is newer than time of database, then database need to be re-created.
2947 timeOfToolModified
= 0
2948 if hasattr(sys
, "frozen"):
2949 exePath
= os
.path
.abspath(sys
.executable
)
2950 timeOfToolModified
= os
.stat(exePath
).st_mtime
2952 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2953 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2954 if rootPath
== "" or rootPath
== None:
2955 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2956 determine whether database file is out of date!\n")
2958 # walk the root path of source or build's binary to get the time last modified.
2960 for root
, dirs
, files
in os
.walk (rootPath
):
2962 # bypass source control folder
2963 if dir.lower() in [".svn", "_svn", "cvs"]:
2967 ext
= os
.path
.splitext(file)[1]
2968 if ext
.lower() == ".py": # only check .py files
2969 fd
= os
.stat(os
.path
.join(root
, file))
2970 if timeOfToolModified
< fd
.st_mtime
:
2971 timeOfToolModified
= fd
.st_mtime
2972 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2973 EdkLogger
.verbose("\nWorkspace database is out of data!")
2978 ## Initialize build database
2979 def InitDatabase(self
):
2980 EdkLogger
.verbose("\nInitialize build database started ...")
2985 self
.TblDataModel
.Create(False)
2986 self
.TblFile
.Create(False)
2989 # Initialize table DataModel
2991 self
.TblDataModel
.InitTable()
2992 EdkLogger
.verbose("Initialize build database ... DONE!")
2996 # @param Table: The instance of the table to be queried
2998 def QueryTable(self
, Table
):
3004 ## Close entire database
3007 # Close the connection and cursor
3010 if not self
._DbClosedFlag
:
3014 self
._DbClosedFlag
= True
3016 ## Summarize all packages in the database
3017 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
3018 self
.Platform
= Platform
3020 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
3022 # Get Package related to Modules
3024 for Module
in Pa
.Modules
:
3025 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
3026 for Package
in ModuleObj
.Packages
:
3027 if Package
not in PackageList
:
3028 PackageList
.append(Package
)
3030 # Get Packages related to Libraries
3032 for Lib
in Pa
.LibraryInstances
:
3033 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
3034 for Package
in LibObj
.Packages
:
3035 if Package
not in PackageList
:
3036 PackageList
.append(Package
)
3040 ## Summarize all platforms in the database
3041 def _GetPlatformList(self
):
3043 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
3045 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
3048 if Platform
!= None:
3049 PlatformList
.append(Platform
)
3052 def _MapPlatform(self
, Dscfile
):
3053 Platform
= self
.BuildObject
[PathClass(Dscfile
), 'COMMON']
3054 if Platform
== None:
3055 EdkLogger
.error('build', PARSER_ERROR
, "Failed to parser DSC file: %s" % Dscfile
)
3058 PlatformList
= property(_GetPlatformList
)
3062 # This acts like the main() function for the script, unless it is 'import'ed into another
3065 if __name__
== '__main__':