2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 from Common
.DataType
import *
16 from Common
.Misc
import *
17 from Common
.caching
import cached_property
, cached_class_function
19 from .MetaFileParser
import *
20 from collections
import OrderedDict
21 from Workspace
.BuildClassObject
import ModuleBuildClassObject
, LibraryClassObject
, PcdClassObject
23 ## Module build information from INF file
25 # This class is used to retrieve information stored in database and convert them
26 # into ModuleBuildClassObject form for easier use for AutoGen.
28 class InfBuildData(ModuleBuildClassObject
):
29 # dict used to convert PCD type in database to string used by build tool
31 MODEL_PCD_FIXED_AT_BUILD
: TAB_PCDS_FIXED_AT_BUILD
,
32 MODEL_PCD_PATCHABLE_IN_MODULE
: TAB_PCDS_PATCHABLE_IN_MODULE
,
33 MODEL_PCD_FEATURE_FLAG
: TAB_PCDS_FEATURE_FLAG
,
34 MODEL_PCD_DYNAMIC
: TAB_PCDS_DYNAMIC
,
35 MODEL_PCD_DYNAMIC_DEFAULT
: TAB_PCDS_DYNAMIC
,
36 MODEL_PCD_DYNAMIC_HII
: TAB_PCDS_DYNAMIC_HII
,
37 MODEL_PCD_DYNAMIC_VPD
: TAB_PCDS_DYNAMIC_VPD
,
38 MODEL_PCD_DYNAMIC_EX
: TAB_PCDS_DYNAMIC_EX
,
39 MODEL_PCD_DYNAMIC_EX_DEFAULT
: TAB_PCDS_DYNAMIC_EX
,
40 MODEL_PCD_DYNAMIC_EX_HII
: TAB_PCDS_DYNAMIC_EX_HII
,
41 MODEL_PCD_DYNAMIC_EX_VPD
: TAB_PCDS_DYNAMIC_EX_VPD
,
44 # dict used to convert part of [Defines] to members of InfBuildData directly
49 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
50 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
51 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
55 # TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
56 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
57 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
58 # TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
59 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
60 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
61 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
62 TAB_INF_DEFINES_VERSION
: "_Version",
63 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
64 TAB_INF_DEFINES_SHADOW
: "_Shadow",
66 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
69 # regular expression for converting XXX_FLAGS in [nmake] section to new type
70 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
71 # dict used to convert old tool name used in [nmake] section to new ones
74 BINARY_FILE_TYPE_LIB
: "SLINK",
79 ## Constructor of InfBuildData
81 # Initialize object of InfBuildData
83 # @param FilePath The path of platform description file
84 # @param RawData The raw data of DSC file
85 # @param BuildDataBase Database used to retrieve module/package information
86 # @param Arch The target architecture
87 # @param Platform The name of platform employing this module
88 # @param Macros Macros used for replacement in DSC file
90 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
=TAB_ARCH_COMMON
, Target
=None, Toolchain
=None):
91 self
.MetaFile
= FilePath
92 self
._ModuleDir
= FilePath
.Dir
93 self
._RawData
= RawData
94 self
._Bdb
= BuildDatabase
97 self
._Toolchain
= Toolchain
98 self
._Platform
= TAB_COMMON
99 if FilePath
.Key
in GlobalData
.gOverrideDir
:
100 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
102 self
._SourceOverridePath
= None
103 self
._TailComments
= None
104 self
._BaseName
= None
106 self
._ModuleType
= None
107 self
._ComponentType
= None
108 self
._BuildType
= None
111 self
._PcdIsDriver
= None
112 self
._BinaryModule
= None
114 self
._MakefileName
= None
115 self
._CustomMakefile
= None
116 self
._Specification
= None
117 self
._LibraryClass
= None
118 self
._ModuleEntryPointList
= None
119 self
._ModuleUnloadImageList
= None
120 self
._ConstructorList
= None
121 self
._DestructorList
= None
122 self
._Defs
= OrderedDict()
123 self
._ProtocolComments
= None
124 self
._PpiComments
= None
125 self
._GuidsUsedByPcd
= OrderedDict()
126 self
._GuidComments
= None
127 self
._PcdComments
= None
128 self
._BuildOptions
= None
129 self
._DependencyFileList
= None
132 def __setitem__(self
, key
, value
):
133 self
.__dict
__[self
._PROPERTY
_[key
]] = value
136 def __getitem__(self
, key
):
137 return self
.__dict
__[self
._PROPERTY
_[key
]]
140 def __contains__(self
, key
):
141 return key
in self
._PROPERTY
_
143 ## Get current effective macros
147 # EDK_GLOBAL defined macros can be applied to EDK module
148 if self
.AutoGenVersion
< 0x00010005:
149 RetVal
.update(GlobalData
.gEdkGlobal
)
150 RetVal
.update(GlobalData
.gGlobalDefines
)
158 ## Return the name of platform employing this module
161 return self
._Platform
164 def HeaderComments(self
):
165 return [a
[0] for a
in self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]]
168 def TailComments(self
):
169 return [a
[0] for a
in self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]]
171 ## Retrieve all information in [Defines] section
173 # (Retriving all [Defines] information in one-shot is just to save time.)
175 @cached_class_function
176 def _GetHeaderInfo(self
):
177 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
178 for Record
in RecordList
:
179 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
180 # items defined _PROPERTY_ don't need additional processing
183 self
._Defs
[Name
] = Value
184 self
._Macros
[Name
] = Value
185 # some special items in [Defines] section need special treatment
186 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
187 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
188 Name
= 'UEFI_SPECIFICATION_VERSION'
189 if self
._Specification
is None:
190 self
._Specification
= OrderedDict()
191 self
._Specification
[Name
] = GetHexVerValue(Value
)
192 if self
._Specification
[Name
] is None:
193 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
194 "'%s' format is not supported for %s" % (Value
, Name
),
195 File
=self
.MetaFile
, Line
=Record
[-1])
196 elif Name
== 'LIBRARY_CLASS':
197 if self
._LibraryClass
is None:
198 self
._LibraryClass
= []
199 ValueList
= GetSplitValueList(Value
)
200 LibraryClass
= ValueList
[0]
201 if len(ValueList
) > 1:
202 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
204 SupModuleList
= SUP_MODULE_LIST
205 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
206 elif Name
== 'ENTRY_POINT':
207 if self
._ModuleEntryPointList
is None:
208 self
._ModuleEntryPointList
= []
209 self
._ModuleEntryPointList
.append(Value
)
210 elif Name
== 'UNLOAD_IMAGE':
211 if self
._ModuleUnloadImageList
is None:
212 self
._ModuleUnloadImageList
= []
215 self
._ModuleUnloadImageList
.append(Value
)
216 elif Name
== 'CONSTRUCTOR':
217 if self
._ConstructorList
is None:
218 self
._ConstructorList
= []
221 self
._ConstructorList
.append(Value
)
222 elif Name
== 'DESTRUCTOR':
223 if self
._DestructorList
is None:
224 self
._DestructorList
= []
227 self
._DestructorList
.append(Value
)
228 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
229 TokenList
= GetSplitValueList(Value
)
230 if self
._CustomMakefile
is None:
231 self
._CustomMakefile
= {}
232 if len(TokenList
) < 2:
233 self
._CustomMakefile
[TAB_COMPILER_MSFT
] = TokenList
[0]
234 self
._CustomMakefile
['GCC'] = TokenList
[0]
236 if TokenList
[0] not in [TAB_COMPILER_MSFT
, 'GCC']:
237 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
238 "No supported family [%s]" % TokenList
[0],
239 File
=self
.MetaFile
, Line
=Record
[-1])
240 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
242 self
._Defs
[Name
] = Value
243 self
._Macros
[Name
] = Value
246 # Retrieve information in sections specific to Edk.x modules
248 if self
.AutoGenVersion
>= 0x00010005:
249 if not self
._ModuleType
:
250 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
251 "MODULE_TYPE is not given", File
=self
.MetaFile
)
252 if self
._ModuleType
not in SUP_MODULE_LIST
:
253 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
254 for Record
in RecordList
:
256 if Name
== "MODULE_TYPE":
259 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
260 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
, ' '.join(l
for l
in SUP_MODULE_LIST
)),
261 File
=self
.MetaFile
, Line
=LineNo
)
262 if (self
._Specification
is None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
263 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
264 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
)
265 if (self
._Specification
is None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x00010032):
266 if self
._ModuleType
== SUP_MODULE_MM_CORE_STANDALONE
:
267 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File
=self
.MetaFile
)
268 if self
._ModuleType
== SUP_MODULE_MM_STANDALONE
:
269 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "MM_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File
=self
.MetaFile
)
270 if 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
271 and 'PCI_CLASS_CODE' in self
._Defs
and 'PCI_REVISION' in self
._Defs
:
272 self
._BuildType
= 'UEFI_OPTIONROM'
273 if 'PCI_COMPRESS' in self
._Defs
:
274 if self
._Defs
['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):
275 EdkLogger
.error("build", FORMAT_INVALID
, "Expected TRUE/FALSE for PCI_COMPRESS: %s" % self
.MetaFile
)
277 elif 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
278 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
279 self
._BuildType
= 'UEFI_HII'
281 self
._BuildType
= self
._ModuleType
.upper()
284 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
285 # check the file validation
286 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
288 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
289 File
=self
.MetaFile
, Line
=LineNo
)
290 if not self
._DependencyFileList
:
291 self
._DependencyFileList
= []
292 self
._DependencyFileList
.append(File
)
294 if not self
._ComponentType
:
295 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
296 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
297 self
._BuildType
= self
._ComponentType
.upper()
298 if self
._ComponentType
in COMPONENT_TO_MODULE_MAP_DICT
:
299 self
._ModuleType
= COMPONENT_TO_MODULE_MAP_DICT
[self
._ComponentType
]
300 if self
._ComponentType
== EDK_COMPONENT_TYPE_LIBRARY
:
301 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
302 # make use some [nmake] section macros
303 Macros
= self
._Macros
304 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
305 Macros
['PROCESSOR'] = self
._Arch
306 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
307 for Name
, Value
, Dummy
, Arch
, Platform
, ID
, LineNo
in RecordList
:
308 Value
= ReplaceMacro(Value
, Macros
, True)
309 if Name
== "IMAGE_ENTRY_POINT":
310 if self
._ModuleEntryPointList
is None:
311 self
._ModuleEntryPointList
= []
312 self
._ModuleEntryPointList
.append(Value
)
313 elif Name
== "DPX_SOURCE":
314 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
315 # check the file validation
316 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
318 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
319 File
=self
.MetaFile
, Line
=LineNo
)
320 if not self
._DependencyFileList
:
321 self
._DependencyFileList
= []
322 self
._DependencyFileList
.append(File
)
324 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
325 if len(ToolList
) == 1:
326 if self
._BuildOptions
is None:
327 self
._BuildOptions
= OrderedDict()
329 if ToolList
[0] in self
._TOOL
_CODE
_:
330 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
333 ToolChain
= "*_*_*_%s_FLAGS" % Tool
334 # Edk.x only support MSFT tool chain
335 # ignore not replaced macros in value
336 ValueList
= GetSplitList(' ' + Value
, '/D')
338 for Index
in range(1, len(ValueList
)):
339 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
341 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
342 Value
= Dummy
.strip()
343 if (TAB_COMPILER_MSFT
, ToolChain
) not in self
._BuildOptions
:
344 self
._BuildOptions
[TAB_COMPILER_MSFT
, ToolChain
] = Value
346 OptionString
= self
._BuildOptions
[TAB_COMPILER_MSFT
, ToolChain
]
347 self
._BuildOptions
[TAB_COMPILER_MSFT
, ToolChain
] = OptionString
+ " " + Value
349 ## Retrieve file version
351 def AutoGenVersion(self
):
353 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
354 for Record
in RecordList
:
355 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
357 ValueList
= Record
[2].split('.')
358 Major
= '%04o' % int(ValueList
[0], 0)
359 Minor
= '%04o' % int(ValueList
[1], 0)
360 RetVal
= int('0x' + Major
+ Minor
, 0)
362 RetVal
= int(Record
[2], 0)
366 ## Retrieve BASE_NAME
369 if self
._BaseName
is None:
370 self
._GetHeaderInfo
()
371 if self
._BaseName
is None:
372 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
373 return self
._BaseName
378 if self
._DxsFile
is None:
379 self
._GetHeaderInfo
()
380 if self
._DxsFile
is None:
384 ## Retrieve MODULE_TYPE
386 def ModuleType(self
):
387 if self
._ModuleType
is None:
388 self
._GetHeaderInfo
()
389 if self
._ModuleType
is None:
390 self
._ModuleType
= SUP_MODULE_BASE
391 if self
._ModuleType
not in SUP_MODULE_LIST
:
392 self
._ModuleType
= SUP_MODULE_USER_DEFINED
393 return self
._ModuleType
395 ## Retrieve COMPONENT_TYPE
397 def ComponentType(self
):
398 if self
._ComponentType
is None:
399 self
._GetHeaderInfo
()
400 if self
._ComponentType
is None:
401 self
._ComponentType
= SUP_MODULE_USER_DEFINED
402 return self
._ComponentType
404 ## Retrieve "BUILD_TYPE"
407 if self
._BuildType
is None:
408 self
._GetHeaderInfo
()
409 if not self
._BuildType
:
410 self
._BuildType
= SUP_MODULE_BASE
411 return self
._BuildType
413 ## Retrieve file guid
416 if self
._Guid
is None:
417 self
._GetHeaderInfo
()
418 if self
._Guid
is None:
419 self
._Guid
= '00000000-0000-0000-0000-000000000000'
422 ## Retrieve module version
425 if self
._Version
is None:
426 self
._GetHeaderInfo
()
427 if self
._Version
is None:
428 self
._Version
= '0.0'
431 ## Retrieve PCD_IS_DRIVER
433 def PcdIsDriver(self
):
434 if self
._PcdIsDriver
is None:
435 self
._GetHeaderInfo
()
436 if self
._PcdIsDriver
is None:
437 self
._PcdIsDriver
= ''
438 return self
._PcdIsDriver
443 if self
._Shadow
is None:
444 self
._GetHeaderInfo
()
445 if self
._Shadow
and self
._Shadow
.upper() == 'TRUE':
451 ## Retrieve CUSTOM_MAKEFILE
453 def CustomMakefile(self
):
454 if self
._CustomMakefile
is None:
455 self
._GetHeaderInfo
()
456 if self
._CustomMakefile
is None:
457 self
._CustomMakefile
= {}
458 return self
._CustomMakefile
460 ## Retrieve EFI_SPECIFICATION_VERSION
462 def Specification(self
):
463 if self
._Specification
is None:
464 self
._GetHeaderInfo
()
465 if self
._Specification
is None:
466 self
._Specification
= {}
467 return self
._Specification
469 ## Retrieve LIBRARY_CLASS
471 def LibraryClass(self
):
472 if self
._LibraryClass
is None:
473 self
._GetHeaderInfo
()
474 if self
._LibraryClass
is None:
475 self
._LibraryClass
= []
476 return self
._LibraryClass
478 ## Retrieve ENTRY_POINT
480 def ModuleEntryPointList(self
):
481 if self
._ModuleEntryPointList
is None:
482 self
._GetHeaderInfo
()
483 if self
._ModuleEntryPointList
is None:
484 self
._ModuleEntryPointList
= []
485 return self
._ModuleEntryPointList
487 ## Retrieve UNLOAD_IMAGE
489 def ModuleUnloadImageList(self
):
490 if self
._ModuleUnloadImageList
is None:
491 self
._GetHeaderInfo
()
492 if self
._ModuleUnloadImageList
is None:
493 self
._ModuleUnloadImageList
= []
494 return self
._ModuleUnloadImageList
496 ## Retrieve CONSTRUCTOR
498 def ConstructorList(self
):
499 if self
._ConstructorList
is None:
500 self
._GetHeaderInfo
()
501 if self
._ConstructorList
is None:
502 self
._ConstructorList
= []
503 return self
._ConstructorList
505 ## Retrieve DESTRUCTOR
507 def DestructorList(self
):
508 if self
._DestructorList
is None:
509 self
._GetHeaderInfo
()
510 if self
._DestructorList
is None:
511 self
._DestructorList
= []
512 return self
._DestructorList
514 ## Retrieve definies other than above ones
517 self
._GetHeaderInfo
()
520 ## Retrieve binary files
521 @cached_class_function
522 def _GetBinaries(self
):
524 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
525 Macros
= self
._Macros
526 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
527 Macros
['PROCESSOR'] = self
._Arch
528 for Record
in RecordList
:
534 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
536 Target
= TokenList
[0]
537 if len(TokenList
) > 1:
538 FeatureFlag
= Record
[1:]
540 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
541 # check the file validation
542 ErrorCode
, ErrorInfo
= File
.Validate()
544 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
548 ## Retrieve binary files with error check.
551 RetVal
= self
._GetBinaries
()
552 if GlobalData
.gIgnoreSource
and not RetVal
:
553 ErrorInfo
= "The INF file does not contain any RetVal to use in creating the image\n"
554 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
558 ## Retrieve source files
561 self
._GetHeaderInfo
()
562 # Ignore all source files in a binary build mode
563 if GlobalData
.gIgnoreSource
:
567 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
568 Macros
= self
._Macros
569 for Record
in RecordList
:
571 ToolChainFamily
= Record
[1]
574 if self
.AutoGenVersion
< 0x00010005:
575 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
576 Macros
['PROCESSOR'] = self
._Arch
577 SourceFile
= NormPath(Record
[0], Macros
)
578 if SourceFile
[0] == os
.path
.sep
:
579 SourceFile
= mws
.join(GlobalData
.gWorkspace
, SourceFile
[1:])
580 # old module source files (Edk)
581 File
= PathClass(SourceFile
, self
._ModuleDir
, self
._SourceOverridePath
,
582 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
583 # check the file validation
584 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
586 if File
.Ext
.lower() == '.h':
587 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
588 File
=self
.MetaFile
, Line
=LineNo
)
591 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
593 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
594 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
595 # check the file validation
596 ErrorCode
, ErrorInfo
= File
.Validate()
598 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
601 # add any previously found dependency files to the source list
602 if self
._DependencyFileList
:
603 RetVal
.extend(self
._DependencyFileList
)
606 ## Retrieve library classes employed by this module
608 def LibraryClasses(self
):
609 RetVal
= OrderedDict()
610 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
611 for Record
in RecordList
:
615 Instance
= NormPath(Instance
, self
._Macros
)
616 RetVal
[Lib
] = Instance
619 ## Retrieve library names (for Edk.x style of modules)
623 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
624 for Record
in RecordList
:
625 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
626 # in case of name with '.lib' extension, which is unusual in Edk.x inf
627 LibraryName
= os
.path
.splitext(LibraryName
)[0]
628 if LibraryName
not in RetVal
:
629 RetVal
.append(LibraryName
)
633 def ProtocolComments(self
):
635 return self
._ProtocolComments
637 ## Retrieve protocols consumed/produced by this module
640 RetVal
= OrderedDict()
641 self
._ProtocolComments
= OrderedDict()
642 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
643 for Record
in RecordList
:
645 Value
= ProtocolValue(CName
, self
.Packages
, self
.MetaFile
.Path
)
647 PackageList
= "\n\t".join(str(P
) for P
in self
.Packages
)
648 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
649 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
650 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
651 RetVal
[CName
] = Value
652 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
653 self
._ProtocolComments
[CName
] = [a
[0] for a
in CommentRecords
]
657 def PpiComments(self
):
659 return self
._PpiComments
661 ## Retrieve PPIs consumed/produced by this module
664 RetVal
= OrderedDict()
665 self
._PpiComments
= OrderedDict()
666 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
667 for Record
in RecordList
:
669 Value
= PpiValue(CName
, self
.Packages
, self
.MetaFile
.Path
)
671 PackageList
= "\n\t".join(str(P
) for P
in self
.Packages
)
672 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
673 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
674 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
675 RetVal
[CName
] = Value
676 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
677 self
._PpiComments
[CName
] = [a
[0] for a
in CommentRecords
]
681 def GuidComments(self
):
683 return self
._GuidComments
685 ## Retrieve GUIDs consumed/produced by this module
688 RetVal
= OrderedDict()
689 self
._GuidComments
= OrderedDict()
690 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
691 for Record
in RecordList
:
693 Value
= GuidValue(CName
, self
.Packages
, self
.MetaFile
.Path
)
695 PackageList
= "\n\t".join(str(P
) for P
in self
.Packages
)
696 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
697 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
698 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
699 RetVal
[CName
] = Value
700 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
701 self
._GuidComments
[CName
] = [a
[0] for a
in CommentRecords
]
704 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
708 if self
._SourceOverridePath
:
709 RetVal
.append(self
._SourceOverridePath
)
711 Macros
= self
._Macros
712 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
.get('PROCESSOR', self
._Arch
)
713 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
714 for Record
in RecordList
:
715 if Record
[0].find('EDK_SOURCE') > -1:
716 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
717 File
= NormPath(Record
[0], self
._Macros
)
719 File
= os
.path
.join(self
._ModuleDir
, File
)
721 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
722 File
= RealPath(os
.path
.normpath(File
))
726 # TRICK: let compiler to choose correct header file
727 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
728 File
= NormPath(Record
[0], self
._Macros
)
730 File
= os
.path
.join(self
._ModuleDir
, File
)
732 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
733 File
= RealPath(os
.path
.normpath(File
))
737 File
= NormPath(Record
[0], Macros
)
739 File
= os
.path
.join(self
._ModuleDir
, File
)
741 File
= mws
.join(GlobalData
.gWorkspace
, File
)
742 File
= RealPath(os
.path
.normpath(File
))
745 if not File
and Record
[0].find('EFI_SOURCE') > -1:
746 # tricky to regard WorkSpace as EFI_SOURCE
747 Macros
['EFI_SOURCE'] = GlobalData
.gWorkspace
748 File
= NormPath(Record
[0], Macros
)
750 File
= os
.path
.join(self
._ModuleDir
, File
)
752 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
753 File
= RealPath(os
.path
.normpath(File
))
758 ## Retrieve packages this module depends on
762 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
763 Macros
= self
._Macros
764 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
765 for Record
in RecordList
:
766 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
767 # check the file validation
768 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
771 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
772 # parse this package now. we need it to get protocol/ppi/guid value
773 RetVal
.append(self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
])
776 ## Retrieve PCD comments
778 def PcdComments(self
):
780 return self
._PcdComments
782 ## Retrieve PCDs used in this module
785 self
._PcdComments
= OrderedDict()
786 RetVal
= OrderedDict()
787 RetVal
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
788 RetVal
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
789 RetVal
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
790 RetVal
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
791 RetVal
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
794 ## Retrieve build options specific to this module
796 def BuildOptions(self
):
797 if self
._BuildOptions
is None:
798 self
._BuildOptions
= OrderedDict()
799 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
800 for Record
in RecordList
:
801 ToolChainFamily
= Record
[0]
802 ToolChain
= Record
[1]
804 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
or Option
.startswith('='):
805 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
807 # concatenate the option string if they're for the same tool
808 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
809 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
810 return self
._BuildOptions
812 ## Retrieve dependency expression
815 RetVal
= tdict(False, 2)
817 # If the module has only Binaries and no Sources, then ignore [Depex]
818 if not self
.Sources
and self
.Binaries
:
821 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
822 # PEIM and DXE drivers must have a valid [Depex] section
823 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
824 if self
.ModuleType
== SUP_MODULE_DXE_DRIVER
or self
.ModuleType
== SUP_MODULE_PEIM
or self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
or \
825 self
.ModuleType
== SUP_MODULE_DXE_SAL_DRIVER
or self
.ModuleType
== SUP_MODULE_DXE_RUNTIME_DRIVER
:
826 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
827 % self
.ModuleType
, File
=self
.MetaFile
)
829 if len(RecordList
) != 0 and self
.ModuleType
== SUP_MODULE_USER_DEFINED
:
830 for Record
in RecordList
:
831 if Record
[4] not in [SUP_MODULE_PEIM
, SUP_MODULE_DXE_DRIVER
, SUP_MODULE_DXE_SMM_DRIVER
]:
832 EdkLogger
.error('build', FORMAT_INVALID
,
833 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
836 TemporaryDictionary
= OrderedDict()
837 for Record
in RecordList
:
838 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
840 ModuleType
= Record
[4]
841 TokenList
= DepexStr
.split()
842 if (Arch
, ModuleType
) not in TemporaryDictionary
:
843 TemporaryDictionary
[Arch
, ModuleType
] = []
844 DepexList
= TemporaryDictionary
[Arch
, ModuleType
]
845 for Token
in TokenList
:
846 if Token
in DEPEX_SUPPORTED_OPCODE_SET
:
847 DepexList
.append(Token
)
848 elif Token
.endswith(".inf"): # module file name
849 ModuleFile
= os
.path
.normpath(Token
)
850 Module
= self
.BuildDatabase
[ModuleFile
]
852 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
853 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
854 DepexList
.append(Module
.Guid
)
856 # it use the Fixed PCD format
858 if tuple(Token
.split('.')[::-1]) not in self
.Pcds
:
859 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "PCD [{}] used in [Depex] section should be listed in module PCD section".format(Token
), File
=self
.MetaFile
, Line
=Record
[-1])
861 if self
.Pcds
[tuple(Token
.split('.')[::-1])].DatumType
!= TAB_VOID
:
862 EdkLogger
.error('build', FORMAT_INVALID
, "PCD [{}] used in [Depex] section should be VOID* datum type".format(Token
), File
=self
.MetaFile
, Line
=Record
[-1])
865 # get the GUID value now
866 Value
= ProtocolValue(Token
, self
.Packages
, self
.MetaFile
.Path
)
868 Value
= PpiValue(Token
, self
.Packages
, self
.MetaFile
.Path
)
870 Value
= GuidValue(Token
, self
.Packages
, self
.MetaFile
.Path
)
873 PackageList
= "\n\t".join(str(P
) for P
in self
.Packages
)
874 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
875 "Value of [%s] is not found in" % Token
,
876 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
877 DepexList
.append(Value
)
878 for Arch
, ModuleType
in TemporaryDictionary
:
879 RetVal
[Arch
, ModuleType
] = TemporaryDictionary
[Arch
, ModuleType
]
882 ## Retrieve depedency expression
884 def DepexExpression(self
):
885 RetVal
= tdict(False, 2)
886 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
887 TemporaryDictionary
= OrderedDict()
888 for Record
in RecordList
:
889 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
891 ModuleType
= Record
[4]
892 TokenList
= DepexStr
.split()
893 if (Arch
, ModuleType
) not in TemporaryDictionary
:
894 TemporaryDictionary
[Arch
, ModuleType
] = ''
895 for Token
in TokenList
:
896 TemporaryDictionary
[Arch
, ModuleType
] = TemporaryDictionary
[Arch
, ModuleType
] + Token
.strip() + ' '
897 for Arch
, ModuleType
in TemporaryDictionary
:
898 RetVal
[Arch
, ModuleType
] = TemporaryDictionary
[Arch
, ModuleType
]
901 @cached_class_function
902 def GetGuidsUsedByPcd(self
):
904 return self
._GuidsUsedByPcd
906 ## Retrieve PCD for given type
907 def _GetPcd(self
, Type
):
909 PcdDict
= tdict(True, 4)
911 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
912 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
913 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
914 PcdList
.append((PcdCName
, TokenSpaceGuid
))
916 if TokenSpaceGuid
not in self
.Guids
:
917 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
, self
.MetaFile
.Path
)
919 PackageList
= "\n\t".join(str(P
) for P
in self
.Packages
)
920 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
921 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
922 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
923 self
.Guids
[TokenSpaceGuid
] = Value
924 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
925 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
927 for CmtRec
in CommentRecords
:
928 Comments
.append(CmtRec
[0])
929 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
931 # resolve PCD type, value, datum info, etc. by getting its definition from package
932 _GuidDict
= self
.Guids
.copy()
933 for PcdCName
, TokenSpaceGuid
in PcdList
:
934 PcdRealName
= PcdCName
935 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
938 ValueList
= AnalyzePcdData(Setting
)
939 DefaultValue
= ValueList
[0]
940 Pcd
= PcdClassObject(
950 self
.Guids
[TokenSpaceGuid
]
952 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
953 # Patch PCD: TokenSpace.PcdCName|Value|Offset
954 Pcd
.Offset
= ValueList
[1]
956 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
957 for Package
in self
.Packages
:
958 for key
in Package
.Pcds
:
959 if (Package
.Pcds
[key
].TokenCName
, Package
.Pcds
[key
].TokenSpaceGuidCName
) == (PcdRealName
, TokenSpaceGuid
):
960 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
961 Pcd_Type
= item
[0].split('_')[-1]
962 if Pcd_Type
== Package
.Pcds
[key
].Type
:
963 Value
= Package
.Pcds
[key
]
964 Value
.TokenCName
= Package
.Pcds
[key
].TokenCName
+ '_' + Pcd_Type
966 newkey
= (Value
.TokenCName
, key
[1])
968 newkey
= (Value
.TokenCName
, key
[1], key
[2])
969 del Package
.Pcds
[key
]
970 Package
.Pcds
[newkey
] = Value
977 # get necessary info from package declaring this PCD
978 for Package
in self
.Packages
:
980 # 'dynamic' in INF means its type is determined by platform;
981 # if platform doesn't give its type, use 'lowest' one in the
982 # following order, if any
984 # TAB_PCDS_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE, TAB_PCDS_FEATURE_FLAG, TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_EX
986 _GuidDict
.update(Package
.Guids
)
987 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
988 if Type
== MODEL_PCD_DYNAMIC
:
990 for T
in PCD_TYPE_LIST
:
991 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
992 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
993 if str(item
[0]).endswith(T
) and (item
[0], item
[1], T
) in Package
.Pcds
:
1001 if (PcdRealName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
1007 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
1008 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
1009 Pcd_Type
= item
[0].split('_')[-1]
1010 if Pcd_Type
== PcdType
:
1018 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
1019 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
1021 Pcd
.TokenValue
= PcdInPackage
.TokenValue
1024 # Check whether the token value exist or not.
1026 if Pcd
.TokenValue
is None or Pcd
.TokenValue
== "":
1030 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdRealName
, str(Package
)),
1031 File
=self
.MetaFile
, Line
=LineNo
,
1035 # Check hexadecimal token value length and format.
1037 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
1038 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
1039 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) is None:
1043 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdRealName
, str(Package
)),
1044 File
=self
.MetaFile
, Line
=LineNo
,
1049 # Check decimal token value length and format.
1053 TokenValueInt
= int (Pcd
.TokenValue
, 10)
1054 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
1058 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdRealName
, str(Package
)),
1059 File
=self
.MetaFile
, Line
=LineNo
,
1066 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdRealName
, str(Package
)),
1067 File
=self
.MetaFile
, Line
=LineNo
,
1071 Pcd
.DatumType
= PcdInPackage
.DatumType
1072 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
1073 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
1074 if not Pcd
.DefaultValue
:
1075 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
1078 Pcd
.DefaultValue
= ValueExpressionEx(Pcd
.DefaultValue
, Pcd
.DatumType
, _GuidDict
)(True)
1079 except BadExpression
as Value
:
1080 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %(TokenSpaceGuid
, PcdRealName
, Pcd
.DefaultValue
, Value
),
1081 File
=self
.MetaFile
, Line
=LineNo
)
1087 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdRealName
, self
.MetaFile
),
1088 File
=self
.MetaFile
, Line
=LineNo
,
1089 ExtraData
="\t%s" % '\n\t'.join(str(P
) for P
in self
.Packages
)
1091 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
1095 ## check whether current module is binary module
1097 def IsBinaryModule(self
):
1098 if (self
.Binaries
and not self
.Sources
) or GlobalData
.gIgnoreSource
: