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 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 import Common
.LongFilePathOs
as os
22 import Common
.EdkLogger
as EdkLogger
23 import Common
.GlobalData
as GlobalData
24 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
26 from Common
.String
import *
27 from Common
.DataType
import *
28 from Common
.Misc
import *
31 from CommonDataClass
.CommonClass
import SkuInfoClass
33 from MetaDataTable
import *
34 from MetaFileTable
import *
35 from MetaFileParser
import *
36 from BuildClassObject
import *
37 from WorkspaceCommon
import GetDeclaredPcd
38 from Common
.Misc
import AnalyzeDscPcd
39 from Common
.Misc
import ProcessDuplicatedInf
41 from Common
.Parsing
import IsValidWord
42 from Common
.VariableAttributes
import VariableAttributes
43 import Common
.GlobalData
as GlobalData
45 ## Platform build information from DSC file
47 # This class is used to retrieve information stored in database and convert them
48 # into PlatformBuildClassObject form for easier use for AutoGen.
50 class DscBuildData(PlatformBuildClassObject
):
51 # dict used to convert PCD type in database to string used by build tool
53 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
54 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
55 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
56 MODEL_PCD_DYNAMIC
: "Dynamic",
57 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
58 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
59 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
60 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
61 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
62 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
63 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
66 # dict used to convert part of [Defines] to members of DscBuildData directly
71 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
72 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
73 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
74 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
75 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
76 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
77 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
78 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
79 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
80 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
81 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
82 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
83 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
84 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
85 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
88 # used to compose dummy library class name for those forced library instances
89 _NullLibraryNumber
= 0
91 ## Constructor of DscBuildData
93 # Initialize object of DscBuildData
95 # @param FilePath The path of platform description file
96 # @param RawData The raw data of DSC file
97 # @param BuildDataBase Database used to retrieve module/package information
98 # @param Arch The target architecture
99 # @param Platform (not used for DscBuildData)
100 # @param Macros Macros used for replacement in DSC file
102 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
103 self
.MetaFile
= FilePath
104 self
._RawData
= RawData
105 self
._Bdb
= BuildDataBase
107 self
._Target
= Target
108 self
._Toolchain
= Toolchain
110 self
._HandleOverridePath
()
113 def __setitem__(self
, key
, value
):
114 self
.__dict
__[self
._PROPERTY
_[key
]] = value
117 def __getitem__(self
, key
):
118 return self
.__dict
__[self
._PROPERTY
_[key
]]
121 def __contains__(self
, key
):
122 return key
in self
._PROPERTY
_
124 ## Set all internal used members of DscBuildData to None
127 self
._PlatformName
= None
130 self
._DscSpecification
= None
131 self
._OutputDirectory
= None
132 self
._SupArchList
= None
133 self
._BuildTargets
= None
135 self
._SkuIdentifier
= None
136 self
._AvilableSkuIds
= None
137 self
._PcdInfoFlag
= None
138 self
._VarCheckFlag
= None
139 self
._FlashDefinition
= None
140 self
._Prebuild
= None
141 self
._Postbuild
= None
142 self
._BuildNumber
= None
143 self
._MakefileName
= None
144 self
._BsBaseAddress
= None
145 self
._RtBaseAddress
= None
148 self
._LibraryInstances
= None
149 self
._LibraryClasses
= None
152 self
._BuildOptions
= None
153 self
._ModuleTypeOptions
= None
154 self
._LoadFixAddress
= None
155 self
._RFCLanguages
= None
156 self
._ISOLanguages
= None
157 self
._VpdToolGuid
= None
161 ## handle Override Path of Module
162 def _HandleOverridePath(self
):
163 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
164 Macros
= self
._Macros
165 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
166 for Record
in RecordList
:
169 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
170 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
172 SourceOverridePath
= mws
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
174 # Check if the source override path exists
175 if not os
.path
.isdir(SourceOverridePath
):
176 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
178 #Add to GlobalData Variables
179 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
181 ## Get current effective macros
182 def _GetMacros(self
):
183 if self
.__Macros
== None:
185 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
186 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
187 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
196 # Changing the default ARCH to another may affect all other information
197 # because all information in a platform may be ARCH-related. That's
198 # why we need to clear all internal used members, in order to cause all
199 # information to be re-retrieved.
201 # @param Value The value of ARCH
203 def _SetArch(self
, Value
):
204 if self
._Arch
== Value
:
209 ## Retrieve all information in [Defines] section
211 # (Retriving all [Defines] information in one-shot is just to save time.)
213 def _GetHeaderInfo(self
):
214 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
215 for Record
in RecordList
:
217 # items defined _PROPERTY_ don't need additional processing
219 # some special items in [Defines] section need special treatment
220 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
221 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
222 if ' ' in self
._OutputDirectory
:
223 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
224 File
=self
.MetaFile
, Line
=Record
[-1],
225 ExtraData
=self
._OutputDirectory
)
226 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
227 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
228 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
230 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
232 elif Name
== TAB_DSC_PREBUILD
:
233 self
._Prebuild
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
234 elif Name
== TAB_DSC_POSTBUILD
:
235 self
._Postbuild
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
236 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
237 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
238 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
239 self
._BuildTargets
= GetSplitValueList(Record
[2])
240 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
241 if self
._SkuName
== None:
242 self
._SkuName
= Record
[2]
243 self
._SkuIdentifier
= Record
[2]
244 self
._AvilableSkuIds
= Record
[2]
245 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
246 self
._PcdInfoFlag
= Record
[2]
247 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
248 self
._VarCheckFlag
= Record
[2]
249 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
251 self
._LoadFixAddress
= int (Record
[2], 0)
253 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
254 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
255 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
256 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"',
257 File
=self
.MetaFile
, Line
=Record
[-1])
258 LanguageCodes
= Record
[2][1:-1]
259 if not LanguageCodes
:
260 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
261 File
=self
.MetaFile
, Line
=Record
[-1])
262 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
263 # check whether there is empty entries in the list
264 if None in LanguageList
:
265 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
266 File
=self
.MetaFile
, Line
=Record
[-1])
267 self
._RFCLanguages
= LanguageList
268 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
269 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
270 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
271 File
=self
.MetaFile
, Line
=Record
[-1])
272 LanguageCodes
= Record
[2][1:-1]
273 if not LanguageCodes
:
274 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
275 File
=self
.MetaFile
, Line
=Record
[-1])
276 if len(LanguageCodes
)%3:
277 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
278 File
=self
.MetaFile
, Line
=Record
[-1])
280 for i
in range(0, len(LanguageCodes
), 3):
281 LanguageList
.append(LanguageCodes
[i
:i
+3])
282 self
._ISOLanguages
= LanguageList
283 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
285 # try to convert GUID to a real UUID value to see whether the GUID is format
286 # for VPD_TOOL_GUID is correct.
291 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
292 self
._VpdToolGuid
= Record
[2]
294 self
[Name
] = Record
[2]
295 # set _Header to non-None in order to avoid database re-querying
296 self
._Header
= 'DUMMY'
298 ## Retrieve platform name
299 def _GetPlatformName(self
):
300 if self
._PlatformName
== None:
301 if self
._Header
== None:
302 self
._GetHeaderInfo
()
303 if self
._PlatformName
== None:
304 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
305 return self
._PlatformName
307 ## Retrieve file guid
308 def _GetFileGuid(self
):
309 if self
._Guid
== None:
310 if self
._Header
== None:
311 self
._GetHeaderInfo
()
312 if self
._Guid
== None:
313 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
316 ## Retrieve platform version
317 def _GetVersion(self
):
318 if self
._Version
== None:
319 if self
._Header
== None:
320 self
._GetHeaderInfo
()
321 if self
._Version
== None:
322 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
325 ## Retrieve platform description file version
326 def _GetDscSpec(self
):
327 if self
._DscSpecification
== None:
328 if self
._Header
== None:
329 self
._GetHeaderInfo
()
330 if self
._DscSpecification
== None:
331 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
332 return self
._DscSpecification
334 ## Retrieve OUTPUT_DIRECTORY
335 def _GetOutpuDir(self
):
336 if self
._OutputDirectory
== None:
337 if self
._Header
== None:
338 self
._GetHeaderInfo
()
339 if self
._OutputDirectory
== None:
340 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
341 return self
._OutputDirectory
343 ## Retrieve SUPPORTED_ARCHITECTURES
344 def _GetSupArch(self
):
345 if self
._SupArchList
== None:
346 if self
._Header
== None:
347 self
._GetHeaderInfo
()
348 if self
._SupArchList
== None:
349 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
350 return self
._SupArchList
352 ## Retrieve BUILD_TARGETS
353 def _GetBuildTarget(self
):
354 if self
._BuildTargets
== None:
355 if self
._Header
== None:
356 self
._GetHeaderInfo
()
357 if self
._BuildTargets
== None:
358 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
359 return self
._BuildTargets
361 def _GetPcdInfoFlag(self
):
362 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
364 elif self
._PcdInfoFlag
.upper() == 'TRUE':
368 def _GetVarCheckFlag(self
):
369 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
371 elif self
._VarCheckFlag
.upper() == 'TRUE':
375 def _GetAviableSkuIds(self
):
376 if self
._AvilableSkuIds
:
377 return self
._AvilableSkuIds
378 return self
.SkuIdentifier
379 def _GetSkuIdentifier(self
):
382 if self
._SkuIdentifier
== None:
383 if self
._Header
== None:
384 self
._GetHeaderInfo
()
385 return self
._SkuIdentifier
386 ## Retrieve SKUID_IDENTIFIER
387 def _GetSkuName(self
):
388 if self
._SkuName
== None:
389 if self
._Header
== None:
390 self
._GetHeaderInfo
()
391 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
392 self
._SkuName
= 'DEFAULT'
395 ## Override SKUID_IDENTIFIER
396 def _SetSkuName(self
, Value
):
397 self
._SkuName
= Value
400 def _GetFdfFile(self
):
401 if self
._FlashDefinition
== None:
402 if self
._Header
== None:
403 self
._GetHeaderInfo
()
404 if self
._FlashDefinition
== None:
405 self
._FlashDefinition
= ''
406 return self
._FlashDefinition
408 def _GetPrebuild(self
):
409 if self
._Prebuild
== None:
410 if self
._Header
== None:
411 self
._GetHeaderInfo
()
412 if self
._Prebuild
== None:
414 return self
._Prebuild
416 def _GetPostbuild(self
):
417 if self
._Postbuild
== None:
418 if self
._Header
== None:
419 self
._GetHeaderInfo
()
420 if self
._Postbuild
== None:
422 return self
._Postbuild
424 ## Retrieve FLASH_DEFINITION
425 def _GetBuildNumber(self
):
426 if self
._BuildNumber
== None:
427 if self
._Header
== None:
428 self
._GetHeaderInfo
()
429 if self
._BuildNumber
== None:
430 self
._BuildNumber
= ''
431 return self
._BuildNumber
433 ## Retrieve MAKEFILE_NAME
434 def _GetMakefileName(self
):
435 if self
._MakefileName
== None:
436 if self
._Header
== None:
437 self
._GetHeaderInfo
()
438 if self
._MakefileName
== None:
439 self
._MakefileName
= ''
440 return self
._MakefileName
442 ## Retrieve BsBaseAddress
443 def _GetBsBaseAddress(self
):
444 if self
._BsBaseAddress
== None:
445 if self
._Header
== None:
446 self
._GetHeaderInfo
()
447 if self
._BsBaseAddress
== None:
448 self
._BsBaseAddress
= ''
449 return self
._BsBaseAddress
451 ## Retrieve RtBaseAddress
452 def _GetRtBaseAddress(self
):
453 if self
._RtBaseAddress
== None:
454 if self
._Header
== None:
455 self
._GetHeaderInfo
()
456 if self
._RtBaseAddress
== None:
457 self
._RtBaseAddress
= ''
458 return self
._RtBaseAddress
460 ## Retrieve the top address for the load fix address
461 def _GetLoadFixAddress(self
):
462 if self
._LoadFixAddress
== None:
463 if self
._Header
== None:
464 self
._GetHeaderInfo
()
466 if self
._LoadFixAddress
== None:
467 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
470 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
472 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
475 # If command line defined, should override the value in DSC file.
477 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
479 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
481 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']))
483 if self
._LoadFixAddress
< 0:
484 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
485 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
486 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
488 return self
._LoadFixAddress
490 ## Retrieve RFCLanguage filter
491 def _GetRFCLanguages(self
):
492 if self
._RFCLanguages
== None:
493 if self
._Header
== None:
494 self
._GetHeaderInfo
()
495 if self
._RFCLanguages
== None:
496 self
._RFCLanguages
= []
497 return self
._RFCLanguages
499 ## Retrieve ISOLanguage filter
500 def _GetISOLanguages(self
):
501 if self
._ISOLanguages
== None:
502 if self
._Header
== None:
503 self
._GetHeaderInfo
()
504 if self
._ISOLanguages
== None:
505 self
._ISOLanguages
= []
506 return self
._ISOLanguages
507 ## Retrieve the GUID string for VPD tool
508 def _GetVpdToolGuid(self
):
509 if self
._VpdToolGuid
== None:
510 if self
._Header
== None:
511 self
._GetHeaderInfo
()
512 if self
._VpdToolGuid
== None:
513 self
._VpdToolGuid
= ''
514 return self
._VpdToolGuid
516 ## Retrieve [SkuIds] section information
517 def _GetSkuIds(self
):
518 if self
._SkuIds
== None:
519 self
._SkuIds
= sdict()
520 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
521 for Record
in RecordList
:
522 if Record
[0] in [None, '']:
523 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
524 File
=self
.MetaFile
, Line
=Record
[-1])
525 if Record
[1] in [None, '']:
526 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
527 File
=self
.MetaFile
, Line
=Record
[-1])
528 self
._SkuIds
[Record
[1]] = Record
[0]
529 if 'DEFAULT' not in self
._SkuIds
:
530 self
._SkuIds
['DEFAULT'] = '0'
531 if 'COMMON' not in self
._SkuIds
:
532 self
._SkuIds
['COMMON'] = '0'
535 ## Retrieve [Components] section information
536 def _GetModules(self
):
537 if self
._Modules
!= None:
540 self
._Modules
= sdict()
541 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
542 Macros
= self
._Macros
543 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
544 for Record
in RecordList
:
545 DuplicatedFile
= False
546 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
550 # check the file validation
551 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
553 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
556 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
557 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
558 DuplicatedFile
= True
560 Module
= ModuleBuildClassObject()
561 Module
.MetaFile
= ModuleFile
563 # get module private library instance
564 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
565 for Record
in RecordList
:
566 LibraryClass
= Record
[0]
567 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
570 # check the file validation
571 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
573 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
576 if LibraryClass
== '' or LibraryClass
== 'NULL':
577 self
._NullLibraryNumber
+= 1
578 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
579 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
580 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
581 if LibraryPath
not in self
.LibraryInstances
:
582 self
.LibraryInstances
.append(LibraryPath
)
584 # get module private PCD setting
585 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
586 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
587 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
588 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
589 TokenList
= GetSplitValueList(Setting
)
590 DefaultValue
= TokenList
[0]
591 if len(TokenList
) > 1:
592 MaxDatumSize
= TokenList
[1]
595 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
596 Pcd
= PcdClassObject(
608 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
610 # get module private build options
611 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
612 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
613 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
614 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
616 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
617 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
619 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
620 if DuplicatedFile
and not RecordList
:
621 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
623 if len(RecordList
) != 1:
624 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
625 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
626 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
627 ModuleFile
.Arch
= self
._Arch
629 self
._Modules
[ModuleFile
] = Module
632 ## Retrieve all possible library instances used in this platform
633 def _GetLibraryInstances(self
):
634 if self
._LibraryInstances
== None:
635 self
._GetLibraryClasses
()
636 return self
._LibraryInstances
638 ## Retrieve [LibraryClasses] information
639 def _GetLibraryClasses(self
):
640 if self
._LibraryClasses
== None:
641 self
._LibraryInstances
= []
643 # tdict is a special dict kind of type, used for selecting correct
644 # library instance for given library class and module type
646 LibraryClassDict
= tdict(True, 3)
647 # track all library class names
648 LibraryClassSet
= set()
649 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
650 Macros
= self
._Macros
651 for Record
in RecordList
:
652 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
653 if LibraryClass
== '' or LibraryClass
== 'NULL':
654 self
._NullLibraryNumber
+= 1
655 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
656 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
657 LibraryClassSet
.add(LibraryClass
)
658 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
659 # check the file validation
660 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
662 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
665 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
666 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
667 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
668 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
669 if LibraryInstance
not in self
._LibraryInstances
:
670 self
._LibraryInstances
.append(LibraryInstance
)
672 # resolve the specific library instance for each class and each module type
673 self
._LibraryClasses
= tdict(True)
674 for LibraryClass
in LibraryClassSet
:
675 # try all possible module types
676 for ModuleType
in SUP_MODULE_LIST
:
677 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
678 if LibraryInstance
== None:
680 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
682 # for Edk style library instances, which are listed in different section
683 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
684 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
685 for Record
in RecordList
:
686 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
688 # check the file validation
689 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
691 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
693 if File
not in self
._LibraryInstances
:
694 self
._LibraryInstances
.append(File
)
696 # we need the module name as the library class name, so we have
697 # to parse it here. (self._Bdb[] will trigger a file parse if it
698 # hasn't been parsed)
700 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
701 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
702 return self
._LibraryClasses
704 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
705 if self
._DecPcds
== None:
706 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
708 if GlobalData
.gFdfParser
:
709 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
712 for Inf
in FdfInfList
:
713 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
714 if ModuleFile
in self
._Modules
:
716 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
717 PkgSet
.update(ModuleData
.Packages
)
721 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
722 self
._DecPcds
.update(DecPcds
)
724 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
725 EdkLogger
.error('build', PARSER_ERROR
,
726 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
727 File
=self
.MetaFile
, Line
=LineNo
)
728 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
729 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
730 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
731 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
732 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
734 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
735 except WrnExpression
, Value
:
736 ValueList
[Index
] = Value
.result
737 except EvaluationException
, Excpt
:
738 if hasattr(Excpt
, 'Pcd'):
739 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
740 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
741 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
742 " of the DSC file" % Excpt
.Pcd
,
743 File
=self
.MetaFile
, Line
=LineNo
)
745 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
746 File
=self
.MetaFile
, Line
=LineNo
)
748 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
749 File
=self
.MetaFile
, Line
=LineNo
)
750 if ValueList
[Index
] == 'True':
751 ValueList
[Index
] = '1'
752 elif ValueList
[Index
] == 'False':
753 ValueList
[Index
] = '0'
755 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
757 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
758 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
761 ## Retrieve all PCD settings in platform
763 if self
._Pcds
== None:
765 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
766 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
767 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
768 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
769 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
770 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
771 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
772 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
773 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
776 ## Retrieve [BuildOptions]
777 def _GetBuildOptions(self
):
778 if self
._BuildOptions
== None:
779 self
._BuildOptions
= sdict()
781 # Retrieve build option for EDKII and EDK style module
783 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
784 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
785 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
786 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
788 # Only flags can be appended
790 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
791 self
._BuildOptions
[CurKey
] = Option
793 self
._BuildOptions
[CurKey
] += ' ' + Option
794 return self
._BuildOptions
796 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
797 if self
._ModuleTypeOptions
== None:
798 self
._ModuleTypeOptions
= sdict()
799 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
801 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
802 DriverType
= '%s.%s' % (Edk
, ModuleType
)
803 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, DriverType
]
804 for ToolChainFamily
, ToolChain
, Option
, Arch
, Type
, Dummy3
, Dummy4
in RecordList
:
805 if Type
== DriverType
:
806 Key
= (ToolChainFamily
, ToolChain
, Edk
)
807 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
808 options
[Key
] = Option
810 options
[Key
] += ' ' + Option
811 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
813 ## Retrieve non-dynamic PCD settings
815 # @param Type PCD type
817 # @retval a dict object contains settings of given PCD type
819 def _GetPcd(self
, Type
):
822 # tdict is a special dict kind of type, used for selecting correct
823 # PCD settings for certain ARCH
826 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
828 PcdDict
= tdict(True, 3)
830 # Find out all possible PCD candidates for self._Arch
831 RecordList
= self
._RawData
[Type
, self
._Arch
]
832 PcdValueDict
= sdict()
833 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
834 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
835 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
836 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
838 #handle pcd value override
839 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
840 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
843 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
844 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
845 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
847 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
849 PcdsKeys
= PcdValueDict
.keys()
850 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
852 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
856 if 'COMMON' in PcdSetting
:
857 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
858 if 'DEFAULT' in PcdSetting
:
859 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
860 if SkuObj
.SystemSkuId
in PcdSetting
:
861 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
863 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
866 self
._PCD
_TYPE
_STRING
_[Type
],
877 ## Retrieve dynamic PCD settings
879 # @param Type PCD type
881 # @retval a dict object contains settings of given PCD type
883 def _GetDynamicPcd(self
, Type
):
885 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
889 # tdict is a special dict kind of type, used for selecting correct
890 # PCD settings for certain ARCH and SKU
892 PcdDict
= tdict(True, 4)
894 # Find out all possible PCD candidates for self._Arch
895 RecordList
= self
._RawData
[Type
, self
._Arch
]
896 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
898 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
899 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
900 if SkuName
not in AvailableSkuIdSet
:
903 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
904 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
905 # Remove redundant PCD candidates, per the ARCH and SKU
906 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
908 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
912 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
913 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
914 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
915 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
916 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
917 if MaxDatumSize
.strip():
918 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
921 if pcdObject
.MaxDatumSize
:
922 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
925 if CurrentMaxSize
> PcdMaxSize
:
926 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
928 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
931 self
._PCD
_TYPE
_STRING
_[Type
],
941 for pcd
in Pcds
.values():
942 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
943 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
944 valuefromDec
= pcdDecObject
.DefaultValue
945 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
946 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
947 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
948 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
949 del(pcd
.SkuInfoList
['COMMON'])
950 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
951 del(pcd
.SkuInfoList
['COMMON'])
952 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
953 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
954 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
955 del(pcd
.SkuInfoList
['DEFAULT'])
959 def CompareVarAttr(self
, Attr1
, Attr2
):
960 if not Attr1
or not Attr2
: # for empty string
962 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
963 Attr1Set
= set(Attr1s
)
964 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
965 Attr2Set
= set(Attr2s
)
966 if Attr2Set
== Attr1Set
:
970 ## Retrieve dynamic HII PCD settings
972 # @param Type PCD type
974 # @retval a dict object contains settings of given PCD type
976 def _GetDynamicHiiPcd(self
, Type
):
978 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
983 # tdict is a special dict kind of type, used for selecting correct
984 # PCD settings for certain ARCH and SKU
986 PcdDict
= tdict(True, 4)
988 RecordList
= self
._RawData
[Type
, self
._Arch
]
989 # Find out all possible PCD candidates for self._Arch
990 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
992 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
993 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
994 if SkuName
not in AvailableSkuIdSet
:
996 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
997 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
998 # Remove redundant PCD candidates, per the ARCH and SKU
999 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
1001 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1004 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1006 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1008 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1009 ExtraData
= "[%s]" % VarAttribute
)
1011 FormatCorrect
= True
1012 if VariableOffset
.isdigit():
1013 if int(VariableOffset
,10) > 0xFFFF:
1015 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
1016 if int(VariableOffset
,16) > 0xFFFF:
1018 # For Offset written in "A.B"
1019 elif VariableOffset
.find('.') > -1:
1020 VariableOffsetList
= VariableOffset
.split(".")
1021 if not (len(VariableOffsetList
) == 2
1022 and IsValidWord(VariableOffsetList
[0])
1023 and IsValidWord(VariableOffsetList
[1])):
1024 FormatCorrect
= False
1026 FormatCorrect
= False
1027 if not FormatCorrect
:
1028 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1031 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1032 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1033 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1035 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1036 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
)]))
1038 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
= VarAttribute
)
1039 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1040 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1041 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1042 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1044 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1047 self
._PCD
_TYPE
_STRING
_[Type
],
1052 {SkuName
: SkuInfo
},
1055 pcdDecObject
.validateranges
,
1056 pcdDecObject
.validlists
,
1057 pcdDecObject
.expressions
1061 for pcd
in Pcds
.values():
1062 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1063 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1064 # Only fix the value while no value provided in DSC file.
1065 for sku
in pcd
.SkuInfoList
.values():
1066 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
1067 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1068 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1069 valuefromDec
= pcdDecObject
.DefaultValue
1070 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
1071 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1072 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1073 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1074 del(pcd
.SkuInfoList
['COMMON'])
1075 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1076 del(pcd
.SkuInfoList
['COMMON'])
1078 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1079 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1080 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1081 del(pcd
.SkuInfoList
['DEFAULT'])
1084 if pcd
.MaxDatumSize
.strip():
1085 MaxSize
= int(pcd
.MaxDatumSize
,0)
1088 if pcdDecObject
.DatumType
== 'VOID*':
1089 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1091 if skuobj
.HiiDefaultValue
.startswith("L"):
1092 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
1093 elif skuobj
.HiiDefaultValue
.startswith("{"):
1094 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1096 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
1099 pcd
.MaxDatumSize
= str(MaxSize
)
1102 ## Retrieve dynamic VPD PCD settings
1104 # @param Type PCD type
1106 # @retval a dict object contains settings of given PCD type
1108 def _GetDynamicVpdPcd(self
, Type
):
1110 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
1114 # tdict is a special dict kind of type, used for selecting correct
1115 # PCD settings for certain ARCH and SKU
1117 PcdDict
= tdict(True, 4)
1119 # Find out all possible PCD candidates for self._Arch
1120 RecordList
= self
._RawData
[Type
, self
._Arch
]
1121 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1123 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1124 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1125 if SkuName
not in AvailableSkuIdSet
:
1128 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1129 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1130 # Remove redundant PCD candidates, per the ARCH and SKU
1131 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1132 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1136 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1137 # For the Integer & Boolean type, the optional data can only be InitialValue.
1138 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1139 # until the DEC parser has been called.
1141 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1142 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1143 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1144 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1145 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1146 if MaxDatumSize
.strip():
1147 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1150 if pcdObject
.MaxDatumSize
:
1151 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1154 if CurrentMaxSize
> PcdMaxSize
:
1155 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1157 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1160 self
._PCD
_TYPE
_STRING
_[Type
],
1165 {SkuName
: SkuInfo
},
1169 for pcd
in Pcds
.values():
1170 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1171 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1172 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1173 valuefromDec
= pcdDecObject
.DefaultValue
1174 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1175 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1176 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1177 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1178 del(pcd
.SkuInfoList
['COMMON'])
1179 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1180 del(pcd
.SkuInfoList
['COMMON'])
1181 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1182 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1183 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1184 del(pcd
.SkuInfoList
['DEFAULT'])
1188 ## Add external modules
1190 # The external modules are mostly those listed in FDF file, which don't
1193 # @param FilePath The path of module description file
1195 def AddModule(self
, FilePath
):
1196 FilePath
= NormPath(FilePath
)
1197 if FilePath
not in self
.Modules
:
1198 Module
= ModuleBuildClassObject()
1199 Module
.MetaFile
= FilePath
1200 self
.Modules
.append(Module
)
1202 ## Add external PCDs
1204 # The external PCDs are mostly those listed in FDF file to specify address
1205 # or offset information.
1207 # @param Name Name of the PCD
1208 # @param Guid Token space guid of the PCD
1209 # @param Value Value of the PCD
1211 def AddPcd(self
, Name
, Guid
, Value
):
1212 if (Name
, Guid
) not in self
.Pcds
:
1213 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1214 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1216 _Macros
= property(_GetMacros
)
1217 Arch
= property(_GetArch
, _SetArch
)
1218 Platform
= property(_GetPlatformName
)
1219 PlatformName
= property(_GetPlatformName
)
1220 Guid
= property(_GetFileGuid
)
1221 Version
= property(_GetVersion
)
1222 DscSpecification
= property(_GetDscSpec
)
1223 OutputDirectory
= property(_GetOutpuDir
)
1224 SupArchList
= property(_GetSupArch
)
1225 BuildTargets
= property(_GetBuildTarget
)
1226 SkuName
= property(_GetSkuName
, _SetSkuName
)
1227 SkuIdentifier
= property(_GetSkuIdentifier
)
1228 AvilableSkuIds
= property(_GetAviableSkuIds
)
1229 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1230 VarCheckFlag
= property(_GetVarCheckFlag
)
1231 FlashDefinition
= property(_GetFdfFile
)
1232 Prebuild
= property(_GetPrebuild
)
1233 Postbuild
= property(_GetPostbuild
)
1234 BuildNumber
= property(_GetBuildNumber
)
1235 MakefileName
= property(_GetMakefileName
)
1236 BsBaseAddress
= property(_GetBsBaseAddress
)
1237 RtBaseAddress
= property(_GetRtBaseAddress
)
1238 LoadFixAddress
= property(_GetLoadFixAddress
)
1239 RFCLanguages
= property(_GetRFCLanguages
)
1240 ISOLanguages
= property(_GetISOLanguages
)
1241 VpdToolGuid
= property(_GetVpdToolGuid
)
1242 SkuIds
= property(_GetSkuIds
)
1243 Modules
= property(_GetModules
)
1244 LibraryInstances
= property(_GetLibraryInstances
)
1245 LibraryClasses
= property(_GetLibraryClasses
)
1246 Pcds
= property(_GetPcds
)
1247 BuildOptions
= property(_GetBuildOptions
)
1249 ## Platform build information from DEC file
1251 # This class is used to retrieve information stored in database and convert them
1252 # into PackageBuildClassObject form for easier use for AutoGen.
1254 class DecBuildData(PackageBuildClassObject
):
1255 # dict used to convert PCD type in database to string used by build tool
1256 _PCD_TYPE_STRING_
= {
1257 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1258 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1259 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1260 MODEL_PCD_DYNAMIC
: "Dynamic",
1261 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1262 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1263 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1264 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1265 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1266 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1267 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1270 # dict used to convert part of [Defines] to members of DecBuildData directly
1275 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1276 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1277 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1278 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1282 ## Constructor of DecBuildData
1284 # Initialize object of DecBuildData
1286 # @param FilePath The path of package description file
1287 # @param RawData The raw data of DEC file
1288 # @param BuildDataBase Database used to retrieve module information
1289 # @param Arch The target architecture
1290 # @param Platform (not used for DecBuildData)
1291 # @param Macros Macros used for replacement in DSC file
1293 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1294 self
.MetaFile
= File
1295 self
._PackageDir
= File
.Dir
1296 self
._RawData
= RawData
1297 self
._Bdb
= BuildDataBase
1299 self
._Target
= Target
1300 self
._Toolchain
= Toolchain
1304 def __setitem__(self
, key
, value
):
1305 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1308 def __getitem__(self
, key
):
1309 return self
.__dict
__[self
._PROPERTY
_[key
]]
1311 ## "in" test support
1312 def __contains__(self
, key
):
1313 return key
in self
._PROPERTY
_
1315 ## Set all internal used members of DecBuildData to None
1318 self
._PackageName
= None
1320 self
._Version
= None
1321 self
._PkgUniFile
= None
1322 self
._Protocols
= None
1325 self
._Includes
= None
1326 self
._LibraryClasses
= None
1328 self
.__Macros
= None
1330 ## Get current effective macros
1331 def _GetMacros(self
):
1332 if self
.__Macros
== None:
1334 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1335 return self
.__Macros
1343 # Changing the default ARCH to another may affect all other information
1344 # because all information in a platform may be ARCH-related. That's
1345 # why we need to clear all internal used members, in order to cause all
1346 # information to be re-retrieved.
1348 # @param Value The value of ARCH
1350 def _SetArch(self
, Value
):
1351 if self
._Arch
== Value
:
1356 ## Retrieve all information in [Defines] section
1358 # (Retriving all [Defines] information in one-shot is just to save time.)
1360 def _GetHeaderInfo(self
):
1361 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1362 for Record
in RecordList
:
1365 self
[Name
] = Record
[2]
1366 self
._Header
= 'DUMMY'
1368 ## Retrieve package name
1369 def _GetPackageName(self
):
1370 if self
._PackageName
== None:
1371 if self
._Header
== None:
1372 self
._GetHeaderInfo
()
1373 if self
._PackageName
== None:
1374 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1375 return self
._PackageName
1377 ## Retrieve file guid
1378 def _GetFileGuid(self
):
1379 if self
._Guid
== None:
1380 if self
._Header
== None:
1381 self
._GetHeaderInfo
()
1382 if self
._Guid
== None:
1383 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1386 ## Retrieve package version
1387 def _GetVersion(self
):
1388 if self
._Version
== None:
1389 if self
._Header
== None:
1390 self
._GetHeaderInfo
()
1391 if self
._Version
== None:
1393 return self
._Version
1395 ## Retrieve protocol definitions (name/value pairs)
1396 def _GetProtocol(self
):
1397 if self
._Protocols
== None:
1399 # tdict is a special kind of dict, used for selecting correct
1400 # protocol defition for given ARCH
1402 ProtocolDict
= tdict(True)
1404 # find out all protocol definitions for specific and 'common' arch
1405 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1406 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1407 if Name
not in NameList
:
1408 NameList
.append(Name
)
1409 ProtocolDict
[Arch
, Name
] = Guid
1410 # use sdict to keep the order
1411 self
._Protocols
= sdict()
1412 for Name
in NameList
:
1414 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1415 # will automatically turn to 'common' ARCH for trying
1417 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1418 return self
._Protocols
1420 ## Retrieve PPI definitions (name/value pairs)
1422 if self
._Ppis
== None:
1424 # tdict is a special kind of dict, used for selecting correct
1425 # PPI defition for given ARCH
1427 PpiDict
= tdict(True)
1429 # find out all PPI definitions for specific arch and 'common' arch
1430 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1431 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1432 if Name
not in NameList
:
1433 NameList
.append(Name
)
1434 PpiDict
[Arch
, Name
] = Guid
1435 # use sdict to keep the order
1436 self
._Ppis
= sdict()
1437 for Name
in NameList
:
1439 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1440 # will automatically turn to 'common' ARCH for trying
1442 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1445 ## Retrieve GUID definitions (name/value pairs)
1447 if self
._Guids
== None:
1449 # tdict is a special kind of dict, used for selecting correct
1450 # GUID defition for given ARCH
1452 GuidDict
= tdict(True)
1454 # find out all protocol definitions for specific and 'common' arch
1455 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1456 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1457 if Name
not in NameList
:
1458 NameList
.append(Name
)
1459 GuidDict
[Arch
, Name
] = Guid
1460 # use sdict to keep the order
1461 self
._Guids
= sdict()
1462 for Name
in NameList
:
1464 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1465 # will automatically turn to 'common' ARCH for trying
1467 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1470 ## Retrieve public include paths declared in this package
1471 def _GetInclude(self
):
1472 if self
._Includes
== None:
1474 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1475 Macros
= self
._Macros
1476 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1477 for Record
in RecordList
:
1478 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1481 ErrorCode
, ErrorInfo
= File
.Validate()
1483 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1485 # avoid duplicate include path
1486 if File
not in self
._Includes
:
1487 self
._Includes
.append(File
)
1488 return self
._Includes
1490 ## Retrieve library class declarations (not used in build at present)
1491 def _GetLibraryClass(self
):
1492 if self
._LibraryClasses
== None:
1494 # tdict is a special kind of dict, used for selecting correct
1495 # library class declaration for given ARCH
1497 LibraryClassDict
= tdict(True)
1498 LibraryClassSet
= set()
1499 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1500 Macros
= self
._Macros
1501 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1502 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1503 # check the file validation
1504 ErrorCode
, ErrorInfo
= File
.Validate()
1506 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1507 LibraryClassSet
.add(LibraryClass
)
1508 LibraryClassDict
[Arch
, LibraryClass
] = File
1509 self
._LibraryClasses
= sdict()
1510 for LibraryClass
in LibraryClassSet
:
1511 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1512 return self
._LibraryClasses
1514 ## Retrieve PCD declarations
1516 if self
._Pcds
== None:
1517 self
._Pcds
= sdict()
1518 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1519 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1520 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1521 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1522 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1525 ## Retrieve PCD declarations for given type
1526 def _GetPcd(self
, Type
):
1529 # tdict is a special kind of dict, used for selecting correct
1530 # PCD declaration for given ARCH
1532 PcdDict
= tdict(True, 3)
1533 # for summarizing PCD
1535 # find out all PCDs of the 'type'
1536 RecordList
= self
._RawData
[Type
, self
._Arch
]
1537 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1538 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1539 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1541 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1543 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1544 # will automatically turn to 'common' ARCH and try again
1546 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1550 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1552 validateranges
, validlists
, expressions
= self
._RawData
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
1553 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1556 self
._PCD
_TYPE
_STRING
_[Type
],
1564 list(validateranges
),
1571 _Macros
= property(_GetMacros
)
1572 Arch
= property(_GetArch
, _SetArch
)
1573 PackageName
= property(_GetPackageName
)
1574 Guid
= property(_GetFileGuid
)
1575 Version
= property(_GetVersion
)
1577 Protocols
= property(_GetProtocol
)
1578 Ppis
= property(_GetPpi
)
1579 Guids
= property(_GetGuid
)
1580 Includes
= property(_GetInclude
)
1581 LibraryClasses
= property(_GetLibraryClass
)
1582 Pcds
= property(_GetPcds
)
1584 ## Module build information from INF file
1586 # This class is used to retrieve information stored in database and convert them
1587 # into ModuleBuildClassObject form for easier use for AutoGen.
1589 class InfBuildData(ModuleBuildClassObject
):
1590 # dict used to convert PCD type in database to string used by build tool
1591 _PCD_TYPE_STRING_
= {
1592 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1593 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1594 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1595 MODEL_PCD_DYNAMIC
: "Dynamic",
1596 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1597 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1598 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1599 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1600 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1601 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1602 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1605 # dict used to convert part of [Defines] to members of InfBuildData directly
1610 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1611 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1612 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1616 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1617 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1618 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1619 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1620 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1621 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1622 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1623 TAB_INF_DEFINES_VERSION
: "_Version",
1624 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1625 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1627 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1630 # dict used to convert Component type to Module type
1633 "SECURITY_CORE" : "SEC",
1634 "PEI_CORE" : "PEI_CORE",
1635 "COMBINED_PEIM_DRIVER" : "PEIM",
1636 "PIC_PEIM" : "PEIM",
1637 "RELOCATABLE_PEIM" : "PEIM",
1638 "PE32_PEIM" : "PEIM",
1639 "BS_DRIVER" : "DXE_DRIVER",
1640 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1641 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1642 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1643 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1644 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1645 # "BS_DRIVER" : "UEFI_DRIVER",
1646 "APPLICATION" : "UEFI_APPLICATION",
1650 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1651 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1652 # dict used to convert old tool name used in [nmake] section to new ones
1660 ## Constructor of DscBuildData
1662 # Initialize object of DscBuildData
1664 # @param FilePath The path of platform description file
1665 # @param RawData The raw data of DSC file
1666 # @param BuildDataBase Database used to retrieve module/package information
1667 # @param Arch The target architecture
1668 # @param Platform The name of platform employing this module
1669 # @param Macros Macros used for replacement in DSC file
1671 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1672 self
.MetaFile
= FilePath
1673 self
._ModuleDir
= FilePath
.Dir
1674 self
._RawData
= RawData
1675 self
._Bdb
= BuildDatabase
1677 self
._Target
= Target
1678 self
._Toolchain
= Toolchain
1679 self
._Platform
= 'COMMON'
1680 self
._SourceOverridePath
= None
1681 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1682 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1686 def __setitem__(self
, key
, value
):
1687 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1690 def __getitem__(self
, key
):
1691 return self
.__dict
__[self
._PROPERTY
_[key
]]
1693 ## "in" test support
1694 def __contains__(self
, key
):
1695 return key
in self
._PROPERTY
_
1697 ## Set all internal used members of InfBuildData to None
1699 self
._HeaderComments
= None
1700 self
._TailComments
= None
1701 self
._Header
_ = None
1702 self
._AutoGenVersion
= None
1703 self
._BaseName
= None
1704 self
._DxsFile
= None
1705 self
._ModuleType
= None
1706 self
._ComponentType
= None
1707 self
._BuildType
= None
1709 self
._Version
= None
1710 self
._PcdIsDriver
= None
1711 self
._BinaryModule
= None
1713 self
._MakefileName
= None
1714 self
._CustomMakefile
= None
1715 self
._Specification
= None
1716 self
._LibraryClass
= None
1717 self
._ModuleEntryPointList
= None
1718 self
._ModuleUnloadImageList
= None
1719 self
._ConstructorList
= None
1720 self
._DestructorList
= None
1722 self
._Binaries
= None
1723 self
._Sources
= None
1724 self
._LibraryClasses
= None
1725 self
._Libraries
= None
1726 self
._Protocols
= None
1727 self
._ProtocolComments
= None
1729 self
._PpiComments
= None
1731 self
._GuidsUsedByPcd
= sdict()
1732 self
._GuidComments
= None
1733 self
._Includes
= None
1734 self
._Packages
= None
1736 self
._PcdComments
= None
1737 self
._BuildOptions
= None
1739 self
._DepexExpression
= None
1740 self
.__Macros
= None
1742 ## Get current effective macros
1743 def _GetMacros(self
):
1744 if self
.__Macros
== None:
1746 # EDK_GLOBAL defined macros can be applied to EDK module
1747 if self
.AutoGenVersion
< 0x00010005:
1748 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1749 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1750 return self
.__Macros
1758 # Changing the default ARCH to another may affect all other information
1759 # because all information in a platform may be ARCH-related. That's
1760 # why we need to clear all internal used members, in order to cause all
1761 # information to be re-retrieved.
1763 # @param Value The value of ARCH
1765 def _SetArch(self
, Value
):
1766 if self
._Arch
== Value
:
1771 ## Return the name of platform employing this module
1772 def _GetPlatform(self
):
1773 return self
._Platform
1775 ## Change the name of platform employing this module
1777 # Changing the default name of platform to another may affect some information
1778 # because they may be PLATFORM-related. That's why we need to clear all internal
1779 # used members, in order to cause all information to be re-retrieved.
1781 def _SetPlatform(self
, Value
):
1782 if self
._Platform
== Value
:
1784 self
._Platform
= Value
1786 def _GetHeaderComments(self
):
1787 if not self
._HeaderComments
:
1788 self
._HeaderComments
= []
1789 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1790 for Record
in RecordList
:
1791 self
._HeaderComments
.append(Record
[0])
1792 return self
._HeaderComments
1793 def _GetTailComments(self
):
1794 if not self
._TailComments
:
1795 self
._TailComments
= []
1796 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1797 for Record
in RecordList
:
1798 self
._TailComments
.append(Record
[0])
1799 return self
._TailComments
1800 ## Retrieve all information in [Defines] section
1802 # (Retriving all [Defines] information in one-shot is just to save time.)
1804 def _GetHeaderInfo(self
):
1805 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1806 for Record
in RecordList
:
1807 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1808 # items defined _PROPERTY_ don't need additional processing
1811 if self
._Defs
== None:
1812 self
._Defs
= sdict()
1813 self
._Defs
[Name
] = Value
1814 # some special items in [Defines] section need special treatment
1815 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1816 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1817 Name
= 'UEFI_SPECIFICATION_VERSION'
1818 if self
._Specification
== None:
1819 self
._Specification
= sdict()
1820 self
._Specification
[Name
] = GetHexVerValue(Value
)
1821 if self
._Specification
[Name
] == None:
1822 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1823 "'%s' format is not supported for %s" % (Value
, Name
),
1824 File
=self
.MetaFile
, Line
=Record
[-1])
1825 elif Name
== 'LIBRARY_CLASS':
1826 if self
._LibraryClass
== None:
1827 self
._LibraryClass
= []
1828 ValueList
= GetSplitValueList(Value
)
1829 LibraryClass
= ValueList
[0]
1830 if len(ValueList
) > 1:
1831 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1833 SupModuleList
= SUP_MODULE_LIST
1834 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1835 elif Name
== 'ENTRY_POINT':
1836 if self
._ModuleEntryPointList
== None:
1837 self
._ModuleEntryPointList
= []
1838 self
._ModuleEntryPointList
.append(Value
)
1839 elif Name
== 'UNLOAD_IMAGE':
1840 if self
._ModuleUnloadImageList
== None:
1841 self
._ModuleUnloadImageList
= []
1844 self
._ModuleUnloadImageList
.append(Value
)
1845 elif Name
== 'CONSTRUCTOR':
1846 if self
._ConstructorList
== None:
1847 self
._ConstructorList
= []
1850 self
._ConstructorList
.append(Value
)
1851 elif Name
== 'DESTRUCTOR':
1852 if self
._DestructorList
== None:
1853 self
._DestructorList
= []
1856 self
._DestructorList
.append(Value
)
1857 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1858 TokenList
= GetSplitValueList(Value
)
1859 if self
._CustomMakefile
== None:
1860 self
._CustomMakefile
= {}
1861 if len(TokenList
) < 2:
1862 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1863 self
._CustomMakefile
['GCC'] = TokenList
[0]
1865 if TokenList
[0] not in ['MSFT', 'GCC']:
1866 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1867 "No supported family [%s]" % TokenList
[0],
1868 File
=self
.MetaFile
, Line
=Record
[-1])
1869 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1871 if self
._Defs
== None:
1872 self
._Defs
= sdict()
1873 self
._Defs
[Name
] = Value
1876 # Retrieve information in sections specific to Edk.x modules
1878 if self
.AutoGenVersion
>= 0x00010005:
1879 if not self
._ModuleType
:
1880 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1881 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1882 if self
._ModuleType
not in SUP_MODULE_LIST
:
1883 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1884 for Record
in RecordList
:
1886 if Name
== "MODULE_TYPE":
1889 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1890 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
, ' '.join(l
for l
in SUP_MODULE_LIST
)),
1891 File
=self
.MetaFile
, Line
=LineNo
)
1892 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1893 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1894 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
)
1895 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1896 and 'PCI_CLASS_CODE' in self
._Defs
:
1897 self
._BuildType
= 'UEFI_OPTIONROM'
1898 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1899 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1900 self
._BuildType
= 'UEFI_HII'
1902 self
._BuildType
= self
._ModuleType
.upper()
1905 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1906 # check the file validation
1907 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1909 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1910 File
=self
.MetaFile
, Line
=LineNo
)
1911 if self
.Sources
== None:
1913 self
._Sources
.append(File
)
1915 if not self
._ComponentType
:
1916 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1917 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1918 self
._BuildType
= self
._ComponentType
.upper()
1919 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1920 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1921 if self
._ComponentType
== 'LIBRARY':
1922 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1923 # make use some [nmake] section macros
1924 Macros
= self
._Macros
1925 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1926 Macros
['PROCESSOR'] = self
._Arch
1927 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1928 for Name
, Value
, Dummy
, Arch
, Platform
, ID
, LineNo
in RecordList
:
1929 Value
= ReplaceMacro(Value
, Macros
, True)
1930 if Name
== "IMAGE_ENTRY_POINT":
1931 if self
._ModuleEntryPointList
== None:
1932 self
._ModuleEntryPointList
= []
1933 self
._ModuleEntryPointList
.append(Value
)
1934 elif Name
== "DPX_SOURCE":
1935 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1936 # check the file validation
1937 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1939 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1940 File
=self
.MetaFile
, Line
=LineNo
)
1941 if self
.Sources
== None:
1943 self
._Sources
.append(File
)
1945 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1946 if len(ToolList
) == 0 or len(ToolList
) != 1:
1948 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1949 # File=self.MetaFile, Line=LineNo)
1951 if self
._BuildOptions
== None:
1952 self
._BuildOptions
= sdict()
1954 if ToolList
[0] in self
._TOOL
_CODE
_:
1955 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1958 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1959 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1960 #ignore not replaced macros in value
1961 ValueList
= GetSplitList(' ' + Value
, '/D')
1962 Dummy
= ValueList
[0]
1963 for Index
in range(1, len(ValueList
)):
1964 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1966 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1967 Value
= Dummy
.strip()
1968 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1969 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1971 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1972 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1973 # set _Header to non-None in order to avoid database re-querying
1974 self
._Header
_ = 'DUMMY'
1976 ## Retrieve file version
1977 def _GetInfVersion(self
):
1978 if self
._AutoGenVersion
== None:
1979 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1980 for Record
in RecordList
:
1981 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1982 if '.' in Record
[2]:
1983 ValueList
= Record
[2].split('.')
1984 Major
= '%04o' % int(ValueList
[0], 0)
1985 Minor
= '%04o' % int(ValueList
[1], 0)
1986 self
._AutoGenVersion
= int('0x' + Major
+ Minor
, 0)
1988 self
._AutoGenVersion
= int(Record
[2], 0)
1990 if self
._AutoGenVersion
== None:
1991 self
._AutoGenVersion
= 0x00010000
1992 return self
._AutoGenVersion
1994 ## Retrieve BASE_NAME
1995 def _GetBaseName(self
):
1996 if self
._BaseName
== None:
1997 if self
._Header
_ == None:
1998 self
._GetHeaderInfo
()
1999 if self
._BaseName
== None:
2000 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
2001 return self
._BaseName
2004 def _GetDxsFile(self
):
2005 if self
._DxsFile
== None:
2006 if self
._Header
_ == None:
2007 self
._GetHeaderInfo
()
2008 if self
._DxsFile
== None:
2010 return self
._DxsFile
2012 ## Retrieve MODULE_TYPE
2013 def _GetModuleType(self
):
2014 if self
._ModuleType
== None:
2015 if self
._Header
_ == None:
2016 self
._GetHeaderInfo
()
2017 if self
._ModuleType
== None:
2018 self
._ModuleType
= 'BASE'
2019 if self
._ModuleType
not in SUP_MODULE_LIST
:
2020 self
._ModuleType
= "USER_DEFINED"
2021 return self
._ModuleType
2023 ## Retrieve COMPONENT_TYPE
2024 def _GetComponentType(self
):
2025 if self
._ComponentType
== None:
2026 if self
._Header
_ == None:
2027 self
._GetHeaderInfo
()
2028 if self
._ComponentType
== None:
2029 self
._ComponentType
= 'USER_DEFINED'
2030 return self
._ComponentType
2032 ## Retrieve "BUILD_TYPE"
2033 def _GetBuildType(self
):
2034 if self
._BuildType
== None:
2035 if self
._Header
_ == None:
2036 self
._GetHeaderInfo
()
2037 if not self
._BuildType
:
2038 self
._BuildType
= "BASE"
2039 return self
._BuildType
2041 ## Retrieve file guid
2042 def _GetFileGuid(self
):
2043 if self
._Guid
== None:
2044 if self
._Header
_ == None:
2045 self
._GetHeaderInfo
()
2046 if self
._Guid
== None:
2047 self
._Guid
= '00000000-0000-0000-0000-000000000000'
2050 ## Retrieve module version
2051 def _GetVersion(self
):
2052 if self
._Version
== None:
2053 if self
._Header
_ == None:
2054 self
._GetHeaderInfo
()
2055 if self
._Version
== None:
2056 self
._Version
= '0.0'
2057 return self
._Version
2059 ## Retrieve PCD_IS_DRIVER
2060 def _GetPcdIsDriver(self
):
2061 if self
._PcdIsDriver
== None:
2062 if self
._Header
_ == None:
2063 self
._GetHeaderInfo
()
2064 if self
._PcdIsDriver
== None:
2065 self
._PcdIsDriver
= ''
2066 return self
._PcdIsDriver
2069 def _GetShadow(self
):
2070 if self
._Shadow
== None:
2071 if self
._Header
_ == None:
2072 self
._GetHeaderInfo
()
2073 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
2076 self
._Shadow
= False
2079 ## Retrieve CUSTOM_MAKEFILE
2080 def _GetMakefile(self
):
2081 if self
._CustomMakefile
== None:
2082 if self
._Header
_ == None:
2083 self
._GetHeaderInfo
()
2084 if self
._CustomMakefile
== None:
2085 self
._CustomMakefile
= {}
2086 return self
._CustomMakefile
2088 ## Retrieve EFI_SPECIFICATION_VERSION
2090 if self
._Specification
== None:
2091 if self
._Header
_ == None:
2092 self
._GetHeaderInfo
()
2093 if self
._Specification
== None:
2094 self
._Specification
= {}
2095 return self
._Specification
2097 ## Retrieve LIBRARY_CLASS
2098 def _GetLibraryClass(self
):
2099 if self
._LibraryClass
== None:
2100 if self
._Header
_ == None:
2101 self
._GetHeaderInfo
()
2102 if self
._LibraryClass
== None:
2103 self
._LibraryClass
= []
2104 return self
._LibraryClass
2106 ## Retrieve ENTRY_POINT
2107 def _GetEntryPoint(self
):
2108 if self
._ModuleEntryPointList
== None:
2109 if self
._Header
_ == None:
2110 self
._GetHeaderInfo
()
2111 if self
._ModuleEntryPointList
== None:
2112 self
._ModuleEntryPointList
= []
2113 return self
._ModuleEntryPointList
2115 ## Retrieve UNLOAD_IMAGE
2116 def _GetUnloadImage(self
):
2117 if self
._ModuleUnloadImageList
== None:
2118 if self
._Header
_ == None:
2119 self
._GetHeaderInfo
()
2120 if self
._ModuleUnloadImageList
== None:
2121 self
._ModuleUnloadImageList
= []
2122 return self
._ModuleUnloadImageList
2124 ## Retrieve CONSTRUCTOR
2125 def _GetConstructor(self
):
2126 if self
._ConstructorList
== None:
2127 if self
._Header
_ == None:
2128 self
._GetHeaderInfo
()
2129 if self
._ConstructorList
== None:
2130 self
._ConstructorList
= []
2131 return self
._ConstructorList
2133 ## Retrieve DESTRUCTOR
2134 def _GetDestructor(self
):
2135 if self
._DestructorList
== None:
2136 if self
._Header
_ == None:
2137 self
._GetHeaderInfo
()
2138 if self
._DestructorList
== None:
2139 self
._DestructorList
= []
2140 return self
._DestructorList
2142 ## Retrieve definies other than above ones
2143 def _GetDefines(self
):
2144 if self
._Defs
== None:
2145 if self
._Header
_ == None:
2146 self
._GetHeaderInfo
()
2147 if self
._Defs
== None:
2148 self
._Defs
= sdict()
2151 ## Retrieve binary files
2152 def _GetBinaries(self
):
2153 if self
._Binaries
== None:
2155 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2156 Macros
= self
._Macros
2157 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2158 Macros
['PROCESSOR'] = self
._Arch
2159 for Record
in RecordList
:
2160 FileType
= Record
[0]
2165 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2167 Target
= TokenList
[0]
2168 if len(TokenList
) > 1:
2169 FeatureFlag
= Record
[1:]
2171 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2172 # check the file validation
2173 ErrorCode
, ErrorInfo
= File
.Validate()
2175 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2176 self
._Binaries
.append(File
)
2177 return self
._Binaries
2179 ## Retrieve binary files with error check.
2180 def _GetBinaryFiles(self
):
2181 Binaries
= self
._GetBinaries
()
2182 if GlobalData
.gIgnoreSource
and Binaries
== []:
2183 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2184 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2187 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2188 def _IsSupportedArch(self
):
2189 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2193 ## Retrieve source files
2194 def _GetSourceFiles(self
):
2195 #Ignore all source files in a binary build mode
2196 if GlobalData
.gIgnoreSource
:
2198 return self
._Sources
2200 if self
._Sources
== None:
2202 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2203 Macros
= self
._Macros
2204 for Record
in RecordList
:
2206 ToolChainFamily
= Record
[1]
2208 ToolCode
= Record
[3]
2209 FeatureFlag
= Record
[4]
2210 if self
.AutoGenVersion
< 0x00010005:
2211 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2212 Macros
['PROCESSOR'] = self
._Arch
2213 SourceFile
= NormPath(Record
[0], Macros
)
2214 if SourceFile
[0] == os
.path
.sep
:
2215 SourceFile
= mws
.join(GlobalData
.gWorkspace
, SourceFile
[1:])
2216 # old module source files (Edk)
2217 File
= PathClass(SourceFile
, self
._ModuleDir
, self
._SourceOverridePath
,
2218 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2219 # check the file validation
2220 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2222 if File
.Ext
.lower() == '.h':
2223 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2224 File
=self
.MetaFile
, Line
=LineNo
)
2227 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2229 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2230 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2231 # check the file validation
2232 ErrorCode
, ErrorInfo
= File
.Validate()
2234 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2236 self
._Sources
.append(File
)
2237 return self
._Sources
2239 ## Retrieve library classes employed by this module
2240 def _GetLibraryClassUses(self
):
2241 if self
._LibraryClasses
== None:
2242 self
._LibraryClasses
= sdict()
2243 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2244 for Record
in RecordList
:
2246 Instance
= Record
[1]
2248 Instance
= NormPath(Instance
, self
._Macros
)
2249 self
._LibraryClasses
[Lib
] = Instance
2250 return self
._LibraryClasses
2252 ## Retrieve library names (for Edk.x style of modules)
2253 def _GetLibraryNames(self
):
2254 if self
._Libraries
== None:
2255 self
._Libraries
= []
2256 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2257 for Record
in RecordList
:
2258 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2259 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2260 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2261 if LibraryName
not in self
._Libraries
:
2262 self
._Libraries
.append(LibraryName
)
2263 return self
._Libraries
2265 def _GetProtocolComments(self
):
2266 self
._GetProtocols
()
2267 return self
._ProtocolComments
2268 ## Retrieve protocols consumed/produced by this module
2269 def _GetProtocols(self
):
2270 if self
._Protocols
== None:
2271 self
._Protocols
= sdict()
2272 self
._ProtocolComments
= sdict()
2273 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2274 for Record
in RecordList
:
2276 Value
= ProtocolValue(CName
, self
.Packages
)
2278 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2279 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2280 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2281 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2282 self
._Protocols
[CName
] = Value
2283 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2285 for CmtRec
in CommentRecords
:
2286 Comments
.append(CmtRec
[0])
2287 self
._ProtocolComments
[CName
] = Comments
2288 return self
._Protocols
2290 def _GetPpiComments(self
):
2292 return self
._PpiComments
2293 ## Retrieve PPIs consumed/produced by this module
2295 if self
._Ppis
== None:
2296 self
._Ppis
= sdict()
2297 self
._PpiComments
= sdict()
2298 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2299 for Record
in RecordList
:
2301 Value
= PpiValue(CName
, self
.Packages
)
2303 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2304 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2305 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2306 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2307 self
._Ppis
[CName
] = Value
2308 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2310 for CmtRec
in CommentRecords
:
2311 Comments
.append(CmtRec
[0])
2312 self
._PpiComments
[CName
] = Comments
2315 def _GetGuidComments(self
):
2317 return self
._GuidComments
2318 ## Retrieve GUIDs consumed/produced by this module
2319 def _GetGuids(self
):
2320 if self
._Guids
== None:
2321 self
._Guids
= sdict()
2322 self
._GuidComments
= sdict()
2323 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2324 for Record
in RecordList
:
2326 Value
= GuidValue(CName
, self
.Packages
)
2328 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2329 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2330 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2331 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2332 self
._Guids
[CName
] = Value
2333 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2335 for CmtRec
in CommentRecords
:
2336 Comments
.append(CmtRec
[0])
2337 self
._GuidComments
[CName
] = Comments
2340 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2341 def _GetIncludes(self
):
2342 if self
._Includes
== None:
2344 if self
._SourceOverridePath
:
2345 self
._Includes
.append(self
._SourceOverridePath
)
2347 Macros
= self
._Macros
2348 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2349 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2351 Macros
['PROCESSOR'] = self
._Arch
2352 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2353 for Record
in RecordList
:
2354 if Record
[0].find('EDK_SOURCE') > -1:
2355 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2356 File
= NormPath(Record
[0], self
._Macros
)
2358 File
= os
.path
.join(self
._ModuleDir
, File
)
2360 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2361 File
= RealPath(os
.path
.normpath(File
))
2363 self
._Includes
.append(File
)
2365 #TRICK: let compiler to choose correct header file
2366 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2367 File
= NormPath(Record
[0], self
._Macros
)
2369 File
= os
.path
.join(self
._ModuleDir
, File
)
2371 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2372 File
= RealPath(os
.path
.normpath(File
))
2374 self
._Includes
.append(File
)
2376 File
= NormPath(Record
[0], Macros
)
2378 File
= os
.path
.join(self
._ModuleDir
, File
)
2380 File
= mws
.join(GlobalData
.gWorkspace
, File
)
2381 File
= RealPath(os
.path
.normpath(File
))
2383 self
._Includes
.append(File
)
2384 if not File
and Record
[0].find('EFI_SOURCE') > -1:
2385 # tricky to regard WorkSpace as EFI_SOURCE
2386 Macros
['EFI_SOURCE'] = GlobalData
.gWorkspace
2387 File
= NormPath(Record
[0], Macros
)
2389 File
= os
.path
.join(self
._ModuleDir
, File
)
2391 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2392 File
= RealPath(os
.path
.normpath(File
))
2394 self
._Includes
.append(File
)
2395 return self
._Includes
2397 ## Retrieve packages this module depends on
2398 def _GetPackages(self
):
2399 if self
._Packages
== None:
2401 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2402 Macros
= self
._Macros
2403 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2404 for Record
in RecordList
:
2405 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2407 # check the file validation
2408 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2410 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2411 # parse this package now. we need it to get protocol/ppi/guid value
2412 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2413 self
._Packages
.append(Package
)
2414 return self
._Packages
2416 ## Retrieve PCD comments
2417 def _GetPcdComments(self
):
2419 return self
._PcdComments
2420 ## Retrieve PCDs used in this module
2422 if self
._Pcds
== None:
2423 self
._Pcds
= sdict()
2424 self
._PcdComments
= sdict()
2425 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2426 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2427 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2428 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2429 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2432 ## Retrieve build options specific to this module
2433 def _GetBuildOptions(self
):
2434 if self
._BuildOptions
== None:
2435 self
._BuildOptions
= sdict()
2436 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2437 for Record
in RecordList
:
2438 ToolChainFamily
= Record
[0]
2439 ToolChain
= Record
[1]
2441 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
or Option
.startswith('='):
2442 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2444 # concatenate the option string if they're for the same tool
2445 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2446 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2447 return self
._BuildOptions
2449 ## Retrieve dependency expression
2450 def _GetDepex(self
):
2451 if self
._Depex
== None:
2452 self
._Depex
= tdict(False, 2)
2453 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2455 # If the module has only Binaries and no Sources, then ignore [Depex]
2456 if self
.Sources
== None or self
.Sources
== []:
2457 if self
.Binaries
!= None and self
.Binaries
!= []:
2460 # PEIM and DXE drivers must have a valid [Depex] section
2461 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2462 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2463 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2464 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2465 % self
.ModuleType
, File
=self
.MetaFile
)
2467 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2468 for Record
in RecordList
:
2469 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2470 EdkLogger
.error('build', FORMAT_INVALID
,
2471 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2475 for Record
in RecordList
:
2476 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2478 ModuleType
= Record
[4]
2479 TokenList
= DepexStr
.split()
2480 if (Arch
, ModuleType
) not in Depex
:
2481 Depex
[Arch
, ModuleType
] = []
2482 DepexList
= Depex
[Arch
, ModuleType
]
2483 for Token
in TokenList
:
2484 if Token
in DEPEX_SUPPORTED_OPCODE
:
2485 DepexList
.append(Token
)
2486 elif Token
.endswith(".inf"): # module file name
2487 ModuleFile
= os
.path
.normpath(Token
)
2488 Module
= self
.BuildDatabase
[ModuleFile
]
2490 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2491 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2492 DepexList
.append(Module
.Guid
)
2494 # get the GUID value now
2495 Value
= ProtocolValue(Token
, self
.Packages
)
2497 Value
= PpiValue(Token
, self
.Packages
)
2499 Value
= GuidValue(Token
, self
.Packages
)
2501 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2502 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2503 "Value of [%s] is not found in" % Token
,
2504 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2505 DepexList
.append(Value
)
2506 for Arch
, ModuleType
in Depex
:
2507 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2510 ## Retrieve depedency expression
2511 def _GetDepexExpression(self
):
2512 if self
._DepexExpression
== None:
2513 self
._DepexExpression
= tdict(False, 2)
2514 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2515 DepexExpression
= sdict()
2516 for Record
in RecordList
:
2517 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2519 ModuleType
= Record
[4]
2520 TokenList
= DepexStr
.split()
2521 if (Arch
, ModuleType
) not in DepexExpression
:
2522 DepexExpression
[Arch
, ModuleType
] = ''
2523 for Token
in TokenList
:
2524 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2525 for Arch
, ModuleType
in DepexExpression
:
2526 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2527 return self
._DepexExpression
2529 def GetGuidsUsedByPcd(self
):
2530 return self
._GuidsUsedByPcd
2531 ## Retrieve PCD for given type
2532 def _GetPcd(self
, Type
):
2534 PcdDict
= tdict(True, 4)
2536 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2537 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2538 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2539 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2540 # get the guid value
2541 if TokenSpaceGuid
not in self
.Guids
:
2542 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2544 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2545 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2546 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2547 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2548 self
.Guids
[TokenSpaceGuid
] = Value
2549 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2550 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2552 for CmtRec
in CommentRecords
:
2553 Comments
.append(CmtRec
[0])
2554 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2556 # resolve PCD type, value, datum info, etc. by getting its definition from package
2557 for PcdCName
, TokenSpaceGuid
in PcdList
:
2558 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2561 ValueList
= AnalyzePcdData(Setting
)
2562 DefaultValue
= ValueList
[0]
2563 Pcd
= PcdClassObject(
2573 self
.Guids
[TokenSpaceGuid
]
2575 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2576 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2577 Pcd
.Offset
= ValueList
[1]
2579 # get necessary info from package declaring this PCD
2580 for Package
in self
.Packages
:
2582 # 'dynamic' in INF means its type is determined by platform;
2583 # if platform doesn't give its type, use 'lowest' one in the
2584 # following order, if any
2586 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2588 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2589 if Type
== MODEL_PCD_DYNAMIC
:
2591 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2592 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2598 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2599 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2601 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2604 # Check whether the token value exist or not.
2606 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2610 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2611 File
=self
.MetaFile
, Line
=LineNo
,
2615 # Check hexadecimal token value length and format.
2617 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2618 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2619 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2623 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2624 File
=self
.MetaFile
, Line
=LineNo
,
2629 # Check decimal token value length and format.
2633 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2634 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2638 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2639 File
=self
.MetaFile
, Line
=LineNo
,
2646 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2647 File
=self
.MetaFile
, Line
=LineNo
,
2651 Pcd
.DatumType
= PcdInPackage
.DatumType
2652 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2653 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2654 if Pcd
.DefaultValue
in [None, '']:
2655 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2661 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2662 File
=self
.MetaFile
, Line
=LineNo
,
2663 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2665 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2669 ## check whether current module is binary module
2670 def _IsBinaryModule(self
):
2671 if self
.Binaries
and not self
.Sources
:
2673 elif GlobalData
.gIgnoreSource
:
2678 _Macros
= property(_GetMacros
)
2679 Arch
= property(_GetArch
, _SetArch
)
2680 Platform
= property(_GetPlatform
, _SetPlatform
)
2682 HeaderComments
= property(_GetHeaderComments
)
2683 TailComments
= property(_GetTailComments
)
2684 AutoGenVersion
= property(_GetInfVersion
)
2685 BaseName
= property(_GetBaseName
)
2686 ModuleType
= property(_GetModuleType
)
2687 ComponentType
= property(_GetComponentType
)
2688 BuildType
= property(_GetBuildType
)
2689 Guid
= property(_GetFileGuid
)
2690 Version
= property(_GetVersion
)
2691 PcdIsDriver
= property(_GetPcdIsDriver
)
2692 Shadow
= property(_GetShadow
)
2693 CustomMakefile
= property(_GetMakefile
)
2694 Specification
= property(_GetSpec
)
2695 LibraryClass
= property(_GetLibraryClass
)
2696 ModuleEntryPointList
= property(_GetEntryPoint
)
2697 ModuleUnloadImageList
= property(_GetUnloadImage
)
2698 ConstructorList
= property(_GetConstructor
)
2699 DestructorList
= property(_GetDestructor
)
2700 Defines
= property(_GetDefines
)
2701 DxsFile
= property(_GetDxsFile
)
2703 Binaries
= property(_GetBinaryFiles
)
2704 Sources
= property(_GetSourceFiles
)
2705 LibraryClasses
= property(_GetLibraryClassUses
)
2706 Libraries
= property(_GetLibraryNames
)
2707 Protocols
= property(_GetProtocols
)
2708 ProtocolComments
= property(_GetProtocolComments
)
2709 Ppis
= property(_GetPpis
)
2710 PpiComments
= property(_GetPpiComments
)
2711 Guids
= property(_GetGuids
)
2712 GuidComments
= property(_GetGuidComments
)
2713 Includes
= property(_GetIncludes
)
2714 Packages
= property(_GetPackages
)
2715 Pcds
= property(_GetPcds
)
2716 PcdComments
= property(_GetPcdComments
)
2717 BuildOptions
= property(_GetBuildOptions
)
2718 Depex
= property(_GetDepex
)
2719 DepexExpression
= property(_GetDepexExpression
)
2720 IsBinaryModule
= property(_IsBinaryModule
)
2721 IsSupportedArch
= property(_IsSupportedArch
)
2725 # This class defined the build database for all modules, packages and platform.
2726 # It will call corresponding parser for the given file if it cannot find it in
2729 # @param DbPath Path of database file
2730 # @param GlobalMacros Global macros used for replacement during file parsing
2731 # @prarm RenewDb=False Create new database file if it's already there
2733 class WorkspaceDatabase(object):
2737 # internal class used for call corresponding file parser and caching the result
2738 # to avoid unnecessary re-parsing
2740 class BuildObjectFactory(object):
2743 ".inf" : MODEL_FILE_INF
,
2744 ".dec" : MODEL_FILE_DEC
,
2745 ".dsc" : MODEL_FILE_DSC
,
2750 MODEL_FILE_INF
: InfParser
,
2751 MODEL_FILE_DEC
: DecParser
,
2752 MODEL_FILE_DSC
: DscParser
,
2755 # convert to xxxBuildData object
2757 MODEL_FILE_INF
: InfBuildData
,
2758 MODEL_FILE_DEC
: DecBuildData
,
2759 MODEL_FILE_DSC
: DscBuildData
,
2762 _CACHE_
= {} # (FilePath, Arch) : <object>
2765 def __init__(self
, WorkspaceDb
):
2766 self
.WorkspaceDb
= WorkspaceDb
2768 # key = (FilePath, Arch=None)
2769 def __contains__(self
, Key
):
2775 return (FilePath
, Arch
) in self
._CACHE
_
2777 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2778 def __getitem__(self
, Key
):
2780 KeyLength
= len(Key
)
2794 # if it's generated before, just return the cached one
2795 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2796 if Key
in self
._CACHE
_:
2797 return self
._CACHE
_[Key
]
2801 if Ext
not in self
._FILE
_TYPE
_:
2803 FileType
= self
._FILE
_TYPE
_[Ext
]
2804 if FileType
not in self
._GENERATOR
_:
2807 # get the parser ready for this file
2808 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2811 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2813 # alwasy do post-process, in case of macros change
2814 MetaFile
.DoPostProcess()
2815 # object the build is based on
2816 BuildObject
= self
._GENERATOR
_[FileType
](
2824 self
._CACHE
_[Key
] = BuildObject
2827 # placeholder for file format conversion
2828 class TransformObjectFactory
:
2829 def __init__(self
, WorkspaceDb
):
2830 self
.WorkspaceDb
= WorkspaceDb
2832 # key = FilePath, Arch
2833 def __getitem__(self
, Key
):
2836 ## Constructor of WorkspaceDatabase
2838 # @param DbPath Path of database file
2839 # @param GlobalMacros Global macros used for replacement during file parsing
2840 # @prarm RenewDb=False Create new database file if it's already there
2842 def __init__(self
, DbPath
, RenewDb
=False):
2843 self
._DbClosedFlag
= False
2845 DbPath
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2847 # don't create necessary path for db in memory
2848 if DbPath
!= ':memory:':
2849 DbDir
= os
.path
.split(DbPath
)[0]
2850 if not os
.path
.exists(DbDir
):
2853 # remove db file in case inconsistency between db and file in file system
2854 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2857 # create db with optimized parameters
2858 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2859 self
.Conn
.execute("PRAGMA synchronous=OFF")
2860 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2861 self
.Conn
.execute("PRAGMA count_changes=OFF")
2862 self
.Conn
.execute("PRAGMA cache_size=8192")
2863 #self.Conn.execute("PRAGMA page_size=8192")
2865 # to avoid non-ascii character conversion issue
2866 self
.Conn
.text_factory
= str
2867 self
.Cur
= self
.Conn
.cursor()
2869 # create table for internal uses
2870 self
.TblDataModel
= TableDataModel(self
.Cur
)
2871 self
.TblFile
= TableFile(self
.Cur
)
2872 self
.Platform
= None
2874 # conversion object for build or file format conversion purpose
2875 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2876 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2878 ## Check whether workspace database need to be renew.
2879 # The renew reason maybe:
2880 # 1) If user force to renew;
2881 # 2) If user do not force renew, and
2882 # a) If the time of last modified python source is newer than database file;
2883 # b) If the time of last modified frozen executable file is newer than database file;
2885 # @param force User force renew database
2886 # @param DbPath The absolute path of workspace database file
2888 # @return Bool value for whether need renew workspace databse
2890 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2891 # if database does not exist, we need do nothing
2892 if not os
.path
.exists(DbPath
): return False
2894 # if user force to renew database, then not check whether database is out of date
2895 if force
: return True
2898 # Check the time of last modified source file or build.exe
2899 # if is newer than time of database, then database need to be re-created.
2901 timeOfToolModified
= 0
2902 if hasattr(sys
, "frozen"):
2903 exePath
= os
.path
.abspath(sys
.executable
)
2904 timeOfToolModified
= os
.stat(exePath
).st_mtime
2906 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2907 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2908 if rootPath
== "" or rootPath
== None:
2909 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2910 determine whether database file is out of date!\n")
2912 # walk the root path of source or build's binary to get the time last modified.
2914 for root
, dirs
, files
in os
.walk (rootPath
):
2916 # bypass source control folder
2917 if dir.lower() in [".svn", "_svn", "cvs"]:
2921 ext
= os
.path
.splitext(file)[1]
2922 if ext
.lower() == ".py": # only check .py files
2923 fd
= os
.stat(os
.path
.join(root
, file))
2924 if timeOfToolModified
< fd
.st_mtime
:
2925 timeOfToolModified
= fd
.st_mtime
2926 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2927 EdkLogger
.verbose("\nWorkspace database is out of data!")
2932 ## Initialize build database
2933 def InitDatabase(self
):
2934 EdkLogger
.verbose("\nInitialize build database started ...")
2939 self
.TblDataModel
.Create(False)
2940 self
.TblFile
.Create(False)
2943 # Initialize table DataModel
2945 self
.TblDataModel
.InitTable()
2946 EdkLogger
.verbose("Initialize build database ... DONE!")
2950 # @param Table: The instance of the table to be queried
2952 def QueryTable(self
, Table
):
2958 ## Close entire database
2961 # Close the connection and cursor
2964 if not self
._DbClosedFlag
:
2968 self
._DbClosedFlag
= True
2970 ## Summarize all packages in the database
2971 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2972 self
.Platform
= Platform
2974 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2976 # Get Package related to Modules
2978 for Module
in Pa
.Modules
:
2979 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2980 for Package
in ModuleObj
.Packages
:
2981 if Package
not in PackageList
:
2982 PackageList
.append(Package
)
2984 # Get Packages related to Libraries
2986 for Lib
in Pa
.LibraryInstances
:
2987 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2988 for Package
in LibObj
.Packages
:
2989 if Package
not in PackageList
:
2990 PackageList
.append(Package
)
2994 ## Summarize all platforms in the database
2995 def _GetPlatformList(self
):
2997 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2999 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
3002 if Platform
!= None:
3003 PlatformList
.append(Platform
)
3006 def _MapPlatform(self
, Dscfile
):
3008 Platform
= self
.BuildObject
[PathClass(Dscfile
), 'COMMON']
3013 PlatformList
= property(_GetPlatformList
)
3017 # This acts like the main() function for the script, unless it is 'import'ed into another
3020 if __name__
== '__main__':