2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 import Common
.LongFilePathOs
as os
22 import Common
.EdkLogger
as EdkLogger
23 import Common
.GlobalData
as GlobalData
25 from Common
.String
import *
26 from Common
.DataType
import *
27 from Common
.Misc
import *
30 from CommonDataClass
.CommonClass
import SkuInfoClass
32 from MetaDataTable
import *
33 from MetaFileTable
import *
34 from MetaFileParser
import *
35 from BuildClassObject
import *
36 from WorkspaceCommon
import GetDeclaredPcd
37 from Common
.Misc
import AnalyzeDscPcd
38 from Common
.Misc
import ProcessDuplicatedInf
40 from Common
.Parsing
import IsValidWord
41 from Common
.VariableAttributes
import VariableAttributes
42 import Common
.GlobalData
as GlobalData
44 ## Platform build information from DSC file
46 # This class is used to retrieve information stored in database and convert them
47 # into PlatformBuildClassObject form for easier use for AutoGen.
49 class DscBuildData(PlatformBuildClassObject
):
50 # dict used to convert PCD type in database to string used by build tool
52 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
53 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
54 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
55 MODEL_PCD_DYNAMIC
: "Dynamic",
56 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
57 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
58 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
59 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
60 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
61 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
62 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
65 # dict used to convert part of [Defines] to members of DscBuildData directly
70 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
71 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
72 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
73 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
74 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
75 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
76 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
77 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
78 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
79 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
80 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
81 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
82 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
83 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
84 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
87 # used to compose dummy library class name for those forced library instances
88 _NullLibraryNumber
= 0
90 ## Constructor of DscBuildData
92 # Initialize object of DscBuildData
94 # @param FilePath The path of platform description file
95 # @param RawData The raw data of DSC file
96 # @param BuildDataBase Database used to retrieve module/package information
97 # @param Arch The target architecture
98 # @param Platform (not used for DscBuildData)
99 # @param Macros Macros used for replacement in DSC file
101 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
102 self
.MetaFile
= FilePath
103 self
._RawData
= RawData
104 self
._Bdb
= BuildDataBase
106 self
._Target
= Target
107 self
._Toolchain
= Toolchain
109 self
._HandleOverridePath
()
112 def __setitem__(self
, key
, value
):
113 self
.__dict
__[self
._PROPERTY
_[key
]] = value
116 def __getitem__(self
, key
):
117 return self
.__dict
__[self
._PROPERTY
_[key
]]
120 def __contains__(self
, key
):
121 return key
in self
._PROPERTY
_
123 ## Set all internal used members of DscBuildData to None
126 self
._PlatformName
= None
129 self
._DscSpecification
= None
130 self
._OutputDirectory
= None
131 self
._SupArchList
= None
132 self
._BuildTargets
= None
134 self
._SkuIdentifier
= None
135 self
._AvilableSkuIds
= None
136 self
._PcdInfoFlag
= None
137 self
._VarCheckFlag
= None
138 self
._FlashDefinition
= None
139 self
._BuildNumber
= None
140 self
._MakefileName
= None
141 self
._BsBaseAddress
= None
142 self
._RtBaseAddress
= None
145 self
._LibraryInstances
= None
146 self
._LibraryClasses
= None
149 self
._BuildOptions
= None
150 self
._ModuleTypeOptions
= None
151 self
._LoadFixAddress
= None
152 self
._RFCLanguages
= None
153 self
._ISOLanguages
= None
154 self
._VpdToolGuid
= None
158 ## handle Override Path of Module
159 def _HandleOverridePath(self
):
160 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
161 Macros
= self
._Macros
162 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
163 for Record
in RecordList
:
166 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
167 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
169 SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
171 # Check if the source override path exists
172 if not os
.path
.isdir(SourceOverridePath
):
173 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
175 #Add to GlobalData Variables
176 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
178 ## Get current effective macros
179 def _GetMacros(self
):
180 if self
.__Macros
== None:
182 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
183 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
184 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
193 # Changing the default ARCH to another may affect all other information
194 # because all information in a platform may be ARCH-related. That's
195 # why we need to clear all internal used members, in order to cause all
196 # information to be re-retrieved.
198 # @param Value The value of ARCH
200 def _SetArch(self
, Value
):
201 if self
._Arch
== Value
:
206 ## Retrieve all information in [Defines] section
208 # (Retriving all [Defines] information in one-shot is just to save time.)
210 def _GetHeaderInfo(self
):
211 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
212 for Record
in RecordList
:
214 # items defined _PROPERTY_ don't need additional processing
216 # some special items in [Defines] section need special treatment
217 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
218 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
219 if ' ' in self
._OutputDirectory
:
220 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
221 File
=self
.MetaFile
, Line
=Record
[-1],
222 ExtraData
=self
._OutputDirectory
)
223 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
224 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
225 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
227 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
229 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
230 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
231 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
232 self
._BuildTargets
= GetSplitValueList(Record
[2])
233 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
234 if self
._SkuName
== None:
235 self
._SkuName
= Record
[2]
236 self
._SkuIdentifier
= Record
[2]
237 self
._AvilableSkuIds
= Record
[2]
238 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
239 self
._PcdInfoFlag
= Record
[2]
240 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
241 self
._VarCheckFlag
= Record
[2]
242 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
244 self
._LoadFixAddress
= int (Record
[2], 0)
246 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
247 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
248 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
249 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"',
250 File
=self
.MetaFile
, Line
=Record
[-1])
251 LanguageCodes
= Record
[2][1:-1]
252 if not LanguageCodes
:
253 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
254 File
=self
.MetaFile
, Line
=Record
[-1])
255 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
256 # check whether there is empty entries in the list
257 if None in LanguageList
:
258 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
259 File
=self
.MetaFile
, Line
=Record
[-1])
260 self
._RFCLanguages
= LanguageList
261 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
262 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
263 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
264 File
=self
.MetaFile
, Line
=Record
[-1])
265 LanguageCodes
= Record
[2][1:-1]
266 if not LanguageCodes
:
267 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
268 File
=self
.MetaFile
, Line
=Record
[-1])
269 if len(LanguageCodes
)%3:
270 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
271 File
=self
.MetaFile
, Line
=Record
[-1])
273 for i
in range(0, len(LanguageCodes
), 3):
274 LanguageList
.append(LanguageCodes
[i
:i
+3])
275 self
._ISOLanguages
= LanguageList
276 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
278 # try to convert GUID to a real UUID value to see whether the GUID is format
279 # for VPD_TOOL_GUID is correct.
284 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
285 self
._VpdToolGuid
= Record
[2]
287 self
[Name
] = Record
[2]
288 # set _Header to non-None in order to avoid database re-querying
289 self
._Header
= 'DUMMY'
291 ## Retrieve platform name
292 def _GetPlatformName(self
):
293 if self
._PlatformName
== None:
294 if self
._Header
== None:
295 self
._GetHeaderInfo
()
296 if self
._PlatformName
== None:
297 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
298 return self
._PlatformName
300 ## Retrieve file guid
301 def _GetFileGuid(self
):
302 if self
._Guid
== None:
303 if self
._Header
== None:
304 self
._GetHeaderInfo
()
305 if self
._Guid
== None:
306 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
309 ## Retrieve platform version
310 def _GetVersion(self
):
311 if self
._Version
== None:
312 if self
._Header
== None:
313 self
._GetHeaderInfo
()
314 if self
._Version
== None:
315 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
318 ## Retrieve platform description file version
319 def _GetDscSpec(self
):
320 if self
._DscSpecification
== None:
321 if self
._Header
== None:
322 self
._GetHeaderInfo
()
323 if self
._DscSpecification
== None:
324 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
325 return self
._DscSpecification
327 ## Retrieve OUTPUT_DIRECTORY
328 def _GetOutpuDir(self
):
329 if self
._OutputDirectory
== None:
330 if self
._Header
== None:
331 self
._GetHeaderInfo
()
332 if self
._OutputDirectory
== None:
333 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
334 return self
._OutputDirectory
336 ## Retrieve SUPPORTED_ARCHITECTURES
337 def _GetSupArch(self
):
338 if self
._SupArchList
== None:
339 if self
._Header
== None:
340 self
._GetHeaderInfo
()
341 if self
._SupArchList
== None:
342 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
343 return self
._SupArchList
345 ## Retrieve BUILD_TARGETS
346 def _GetBuildTarget(self
):
347 if self
._BuildTargets
== None:
348 if self
._Header
== None:
349 self
._GetHeaderInfo
()
350 if self
._BuildTargets
== None:
351 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
352 return self
._BuildTargets
354 def _GetPcdInfoFlag(self
):
355 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
357 elif self
._PcdInfoFlag
.upper() == 'TRUE':
361 def _GetVarCheckFlag(self
):
362 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
364 elif self
._VarCheckFlag
.upper() == 'TRUE':
368 def _GetAviableSkuIds(self
):
369 if self
._AvilableSkuIds
:
370 return self
._AvilableSkuIds
371 return self
.SkuIdentifier
372 def _GetSkuIdentifier(self
):
375 if self
._SkuIdentifier
== None:
376 if self
._Header
== None:
377 self
._GetHeaderInfo
()
378 return self
._SkuIdentifier
379 ## Retrieve SKUID_IDENTIFIER
380 def _GetSkuName(self
):
381 if self
._SkuName
== None:
382 if self
._Header
== None:
383 self
._GetHeaderInfo
()
384 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
385 self
._SkuName
= 'DEFAULT'
388 ## Override SKUID_IDENTIFIER
389 def _SetSkuName(self
, Value
):
390 self
._SkuName
= Value
393 def _GetFdfFile(self
):
394 if self
._FlashDefinition
== None:
395 if self
._Header
== None:
396 self
._GetHeaderInfo
()
397 if self
._FlashDefinition
== None:
398 self
._FlashDefinition
= ''
399 return self
._FlashDefinition
401 ## Retrieve FLASH_DEFINITION
402 def _GetBuildNumber(self
):
403 if self
._BuildNumber
== None:
404 if self
._Header
== None:
405 self
._GetHeaderInfo
()
406 if self
._BuildNumber
== None:
407 self
._BuildNumber
= ''
408 return self
._BuildNumber
410 ## Retrieve MAKEFILE_NAME
411 def _GetMakefileName(self
):
412 if self
._MakefileName
== None:
413 if self
._Header
== None:
414 self
._GetHeaderInfo
()
415 if self
._MakefileName
== None:
416 self
._MakefileName
= ''
417 return self
._MakefileName
419 ## Retrieve BsBaseAddress
420 def _GetBsBaseAddress(self
):
421 if self
._BsBaseAddress
== None:
422 if self
._Header
== None:
423 self
._GetHeaderInfo
()
424 if self
._BsBaseAddress
== None:
425 self
._BsBaseAddress
= ''
426 return self
._BsBaseAddress
428 ## Retrieve RtBaseAddress
429 def _GetRtBaseAddress(self
):
430 if self
._RtBaseAddress
== None:
431 if self
._Header
== None:
432 self
._GetHeaderInfo
()
433 if self
._RtBaseAddress
== None:
434 self
._RtBaseAddress
= ''
435 return self
._RtBaseAddress
437 ## Retrieve the top address for the load fix address
438 def _GetLoadFixAddress(self
):
439 if self
._LoadFixAddress
== None:
440 if self
._Header
== None:
441 self
._GetHeaderInfo
()
443 if self
._LoadFixAddress
== None:
444 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
447 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
449 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
452 # If command line defined, should override the value in DSC file.
454 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
456 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
458 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']))
460 if self
._LoadFixAddress
< 0:
461 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
462 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
463 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
465 return self
._LoadFixAddress
467 ## Retrieve RFCLanguage filter
468 def _GetRFCLanguages(self
):
469 if self
._RFCLanguages
== None:
470 if self
._Header
== None:
471 self
._GetHeaderInfo
()
472 if self
._RFCLanguages
== None:
473 self
._RFCLanguages
= []
474 return self
._RFCLanguages
476 ## Retrieve ISOLanguage filter
477 def _GetISOLanguages(self
):
478 if self
._ISOLanguages
== None:
479 if self
._Header
== None:
480 self
._GetHeaderInfo
()
481 if self
._ISOLanguages
== None:
482 self
._ISOLanguages
= []
483 return self
._ISOLanguages
484 ## Retrieve the GUID string for VPD tool
485 def _GetVpdToolGuid(self
):
486 if self
._VpdToolGuid
== None:
487 if self
._Header
== None:
488 self
._GetHeaderInfo
()
489 if self
._VpdToolGuid
== None:
490 self
._VpdToolGuid
= ''
491 return self
._VpdToolGuid
493 ## Retrieve [SkuIds] section information
494 def _GetSkuIds(self
):
495 if self
._SkuIds
== None:
496 self
._SkuIds
= sdict()
497 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
498 for Record
in RecordList
:
499 if Record
[0] in [None, '']:
500 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
501 File
=self
.MetaFile
, Line
=Record
[-1])
502 if Record
[1] in [None, '']:
503 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
504 File
=self
.MetaFile
, Line
=Record
[-1])
505 self
._SkuIds
[Record
[1]] = Record
[0]
506 if 'DEFAULT' not in self
._SkuIds
:
507 self
._SkuIds
['DEFAULT'] = '0'
508 if 'COMMON' not in self
._SkuIds
:
509 self
._SkuIds
['COMMON'] = '0'
512 ## Retrieve [Components] section information
513 def _GetModules(self
):
514 if self
._Modules
!= None:
517 self
._Modules
= sdict()
518 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
519 Macros
= self
._Macros
520 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
521 for Record
in RecordList
:
522 DuplicatedFile
= False
523 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
527 # check the file validation
528 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
530 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
533 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
534 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
535 DuplicatedFile
= True
537 Module
= ModuleBuildClassObject()
538 Module
.MetaFile
= ModuleFile
540 # get module private library instance
541 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
542 for Record
in RecordList
:
543 LibraryClass
= Record
[0]
544 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
547 # check the file validation
548 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
550 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
553 if LibraryClass
== '' or LibraryClass
== 'NULL':
554 self
._NullLibraryNumber
+= 1
555 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
556 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
557 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
558 if LibraryPath
not in self
.LibraryInstances
:
559 self
.LibraryInstances
.append(LibraryPath
)
561 # get module private PCD setting
562 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
563 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
564 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
565 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
566 TokenList
= GetSplitValueList(Setting
)
567 DefaultValue
= TokenList
[0]
568 if len(TokenList
) > 1:
569 MaxDatumSize
= TokenList
[1]
572 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
573 Pcd
= PcdClassObject(
585 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
587 # get module private build options
588 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
589 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
590 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
591 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
593 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
594 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
596 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
597 if DuplicatedFile
and not RecordList
:
598 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
600 if len(RecordList
) != 1:
601 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
602 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
603 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
604 ModuleFile
.Arch
= self
._Arch
606 self
._Modules
[ModuleFile
] = Module
609 ## Retrieve all possible library instances used in this platform
610 def _GetLibraryInstances(self
):
611 if self
._LibraryInstances
== None:
612 self
._GetLibraryClasses
()
613 return self
._LibraryInstances
615 ## Retrieve [LibraryClasses] information
616 def _GetLibraryClasses(self
):
617 if self
._LibraryClasses
== None:
618 self
._LibraryInstances
= []
620 # tdict is a special dict kind of type, used for selecting correct
621 # library instance for given library class and module type
623 LibraryClassDict
= tdict(True, 3)
624 # track all library class names
625 LibraryClassSet
= set()
626 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
627 Macros
= self
._Macros
628 for Record
in RecordList
:
629 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
630 if LibraryClass
== '' or LibraryClass
== 'NULL':
631 self
._NullLibraryNumber
+= 1
632 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
633 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
634 LibraryClassSet
.add(LibraryClass
)
635 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
636 # check the file validation
637 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
639 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
642 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
643 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
644 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
645 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
646 if LibraryInstance
not in self
._LibraryInstances
:
647 self
._LibraryInstances
.append(LibraryInstance
)
649 # resolve the specific library instance for each class and each module type
650 self
._LibraryClasses
= tdict(True)
651 for LibraryClass
in LibraryClassSet
:
652 # try all possible module types
653 for ModuleType
in SUP_MODULE_LIST
:
654 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
655 if LibraryInstance
== None:
657 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
659 # for Edk style library instances, which are listed in different section
660 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
661 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
662 for Record
in RecordList
:
663 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
665 # check the file validation
666 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
668 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
670 if File
not in self
._LibraryInstances
:
671 self
._LibraryInstances
.append(File
)
673 # we need the module name as the library class name, so we have
674 # to parse it here. (self._Bdb[] will trigger a file parse if it
675 # hasn't been parsed)
677 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
678 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
679 return self
._LibraryClasses
681 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
682 if self
._DecPcds
== None:
683 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
685 if GlobalData
.gFdfParser
:
686 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
689 for Inf
in FdfInfList
:
690 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
691 if ModuleFile
in self
._Modules
:
693 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
694 PkgSet
.update(ModuleData
.Packages
)
698 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
699 self
._DecPcds
.update(DecPcds
)
701 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
702 EdkLogger
.error('build', PARSER_ERROR
,
703 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
704 File
=self
.MetaFile
, Line
=LineNo
)
705 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
706 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
707 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
708 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
709 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
711 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
712 except WrnExpression
, Value
:
713 ValueList
[Index
] = Value
.result
714 except EvaluationException
, Excpt
:
715 if hasattr(Excpt
, 'Pcd'):
716 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
717 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
718 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
719 " of the DSC file" % Excpt
.Pcd
,
720 File
=self
.MetaFile
, Line
=LineNo
)
722 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
723 File
=self
.MetaFile
, Line
=LineNo
)
725 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
726 File
=self
.MetaFile
, Line
=LineNo
)
727 if ValueList
[Index
] == 'True':
728 ValueList
[Index
] = '1'
729 elif ValueList
[Index
] == 'False':
730 ValueList
[Index
] = '0'
732 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
734 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
735 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
738 ## Retrieve all PCD settings in platform
740 if self
._Pcds
== None:
742 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
743 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
744 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
745 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
746 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
747 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
748 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
749 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
750 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
753 ## Retrieve [BuildOptions]
754 def _GetBuildOptions(self
):
755 if self
._BuildOptions
== None:
756 self
._BuildOptions
= sdict()
758 # Retrieve build option for EDKII style module
760 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
761 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
762 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
764 # Retrieve build option for EDK style module
766 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
767 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
768 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
769 return self
._BuildOptions
771 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
772 if self
._ModuleTypeOptions
== None:
773 self
._ModuleTypeOptions
= sdict()
774 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
776 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
777 DriverType
= '%s.%s' % (Edk
, ModuleType
)
778 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, DriverType
]
779 for ToolChainFamily
, ToolChain
, Option
, Arch
, Type
, Dummy3
, Dummy4
in RecordList
:
780 if Arch
== self
._Arch
and Type
== DriverType
:
781 options
[ToolChainFamily
, ToolChain
, Edk
] = Option
782 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
784 ## Retrieve non-dynamic PCD settings
786 # @param Type PCD type
788 # @retval a dict object contains settings of given PCD type
790 def _GetPcd(self
, Type
):
793 # tdict is a special dict kind of type, used for selecting correct
794 # PCD settings for certain ARCH
797 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
799 PcdDict
= tdict(True, 3)
801 # Find out all possible PCD candidates for self._Arch
802 RecordList
= self
._RawData
[Type
, self
._Arch
]
803 PcdValueDict
= sdict()
804 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
805 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
806 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
807 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
809 #handle pcd value override
810 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
811 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
814 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
815 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
816 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
818 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
820 PcdsKeys
= PcdValueDict
.keys()
821 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
823 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
827 if 'COMMON' in PcdSetting
:
828 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
829 if 'DEFAULT' in PcdSetting
:
830 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
831 if SkuObj
.SystemSkuId
in PcdSetting
:
832 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
834 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
837 self
._PCD
_TYPE
_STRING
_[Type
],
848 ## Retrieve dynamic PCD settings
850 # @param Type PCD type
852 # @retval a dict object contains settings of given PCD type
854 def _GetDynamicPcd(self
, Type
):
856 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
860 # tdict is a special dict kind of type, used for selecting correct
861 # PCD settings for certain ARCH and SKU
863 PcdDict
= tdict(True, 4)
865 # Find out all possible PCD candidates for self._Arch
866 RecordList
= self
._RawData
[Type
, self
._Arch
]
867 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
869 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
870 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
871 if SkuName
not in AvailableSkuIdSet
:
874 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
875 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
876 # Remove redundant PCD candidates, per the ARCH and SKU
877 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
879 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
883 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
884 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
885 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
886 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
887 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
888 if MaxDatumSize
.strip():
889 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
892 if pcdObject
.MaxDatumSize
:
893 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
896 if CurrentMaxSize
> PcdMaxSize
:
897 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
899 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
902 self
._PCD
_TYPE
_STRING
_[Type
],
912 for pcd
in Pcds
.values():
913 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
914 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
915 valuefromDec
= pcdDecObject
.DefaultValue
916 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
917 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
918 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
919 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
920 del(pcd
.SkuInfoList
['COMMON'])
921 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
922 del(pcd
.SkuInfoList
['COMMON'])
923 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
924 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
925 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
926 del(pcd
.SkuInfoList
['DEFAULT'])
930 def CompareVarAttr(self
, Attr1
, Attr2
):
931 if not Attr1
or not Attr2
: # for empty string
933 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
934 Attr1Set
= set(Attr1s
)
935 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
936 Attr2Set
= set(Attr2s
)
937 if Attr2Set
== Attr1Set
:
941 ## Retrieve dynamic HII PCD settings
943 # @param Type PCD type
945 # @retval a dict object contains settings of given PCD type
947 def _GetDynamicHiiPcd(self
, Type
):
949 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
954 # tdict is a special dict kind of type, used for selecting correct
955 # PCD settings for certain ARCH and SKU
957 PcdDict
= tdict(True, 4)
959 RecordList
= self
._RawData
[Type
, self
._Arch
]
960 # Find out all possible PCD candidates for self._Arch
961 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
963 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
964 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
965 if SkuName
not in AvailableSkuIdSet
:
967 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
968 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
969 # Remove redundant PCD candidates, per the ARCH and SKU
970 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
972 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
975 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
977 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
979 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
980 ExtraData
= "[%s]" % VarAttribute
)
983 if VariableOffset
.isdigit():
984 if int(VariableOffset
,10) > 0xFFFF:
986 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
987 if int(VariableOffset
,16) > 0xFFFF:
989 # For Offset written in "A.B"
990 elif VariableOffset
.find('.') > -1:
991 VariableOffsetList
= VariableOffset
.split(".")
992 if not (len(VariableOffsetList
) == 2
993 and IsValidWord(VariableOffsetList
[0])
994 and IsValidWord(VariableOffsetList
[1])):
995 FormatCorrect
= False
997 FormatCorrect
= False
998 if not FormatCorrect
:
999 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1002 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1003 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1004 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1006 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1007 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
)]))
1009 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
= VarAttribute
)
1010 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1011 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1012 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1013 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1015 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1018 self
._PCD
_TYPE
_STRING
_[Type
],
1023 {SkuName
: SkuInfo
},
1026 pcdDecObject
.validateranges
,
1027 pcdDecObject
.validlists
,
1028 pcdDecObject
.expressions
1032 for pcd
in Pcds
.values():
1033 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1034 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1035 # Only fix the value while no value provided in DSC file.
1036 for sku
in pcd
.SkuInfoList
.values():
1037 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
1038 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1039 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1040 valuefromDec
= pcdDecObject
.DefaultValue
1041 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
1042 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1043 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1044 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1045 del(pcd
.SkuInfoList
['COMMON'])
1046 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1047 del(pcd
.SkuInfoList
['COMMON'])
1049 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1050 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1051 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1052 del(pcd
.SkuInfoList
['DEFAULT'])
1055 if pcd
.MaxDatumSize
.strip():
1056 MaxSize
= int(pcd
.MaxDatumSize
,0)
1059 if pcdDecObject
.DatumType
== 'VOID*':
1060 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1062 if skuobj
.HiiDefaultValue
.startswith("L"):
1063 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
1064 elif skuobj
.HiiDefaultValue
.startswith("{"):
1065 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1067 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
1070 pcd
.MaxDatumSize
= str(MaxSize
)
1073 ## Retrieve dynamic VPD PCD settings
1075 # @param Type PCD type
1077 # @retval a dict object contains settings of given PCD type
1079 def _GetDynamicVpdPcd(self
, Type
):
1081 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
1085 # tdict is a special dict kind of type, used for selecting correct
1086 # PCD settings for certain ARCH and SKU
1088 PcdDict
= tdict(True, 4)
1090 # Find out all possible PCD candidates for self._Arch
1091 RecordList
= self
._RawData
[Type
, self
._Arch
]
1092 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1094 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1095 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1096 if SkuName
not in AvailableSkuIdSet
:
1099 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1100 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1101 # Remove redundant PCD candidates, per the ARCH and SKU
1102 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1103 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1107 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1108 # For the Integer & Boolean type, the optional data can only be InitialValue.
1109 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1110 # until the DEC parser has been called.
1112 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1113 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1114 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1115 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1116 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1117 if MaxDatumSize
.strip():
1118 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1121 if pcdObject
.MaxDatumSize
:
1122 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1125 if CurrentMaxSize
> PcdMaxSize
:
1126 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1128 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1131 self
._PCD
_TYPE
_STRING
_[Type
],
1136 {SkuName
: SkuInfo
},
1140 for pcd
in Pcds
.values():
1141 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1142 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1143 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1144 valuefromDec
= pcdDecObject
.DefaultValue
1145 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1146 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1147 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1148 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1149 del(pcd
.SkuInfoList
['COMMON'])
1150 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1151 del(pcd
.SkuInfoList
['COMMON'])
1152 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1153 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1154 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1155 del(pcd
.SkuInfoList
['DEFAULT'])
1159 ## Add external modules
1161 # The external modules are mostly those listed in FDF file, which don't
1164 # @param FilePath The path of module description file
1166 def AddModule(self
, FilePath
):
1167 FilePath
= NormPath(FilePath
)
1168 if FilePath
not in self
.Modules
:
1169 Module
= ModuleBuildClassObject()
1170 Module
.MetaFile
= FilePath
1171 self
.Modules
.append(Module
)
1173 ## Add external PCDs
1175 # The external PCDs are mostly those listed in FDF file to specify address
1176 # or offset information.
1178 # @param Name Name of the PCD
1179 # @param Guid Token space guid of the PCD
1180 # @param Value Value of the PCD
1182 def AddPcd(self
, Name
, Guid
, Value
):
1183 if (Name
, Guid
) not in self
.Pcds
:
1184 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1185 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1187 _Macros
= property(_GetMacros
)
1188 Arch
= property(_GetArch
, _SetArch
)
1189 Platform
= property(_GetPlatformName
)
1190 PlatformName
= property(_GetPlatformName
)
1191 Guid
= property(_GetFileGuid
)
1192 Version
= property(_GetVersion
)
1193 DscSpecification
= property(_GetDscSpec
)
1194 OutputDirectory
= property(_GetOutpuDir
)
1195 SupArchList
= property(_GetSupArch
)
1196 BuildTargets
= property(_GetBuildTarget
)
1197 SkuName
= property(_GetSkuName
, _SetSkuName
)
1198 SkuIdentifier
= property(_GetSkuIdentifier
)
1199 AvilableSkuIds
= property(_GetAviableSkuIds
)
1200 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1201 VarCheckFlag
= property(_GetVarCheckFlag
)
1202 FlashDefinition
= property(_GetFdfFile
)
1203 BuildNumber
= property(_GetBuildNumber
)
1204 MakefileName
= property(_GetMakefileName
)
1205 BsBaseAddress
= property(_GetBsBaseAddress
)
1206 RtBaseAddress
= property(_GetRtBaseAddress
)
1207 LoadFixAddress
= property(_GetLoadFixAddress
)
1208 RFCLanguages
= property(_GetRFCLanguages
)
1209 ISOLanguages
= property(_GetISOLanguages
)
1210 VpdToolGuid
= property(_GetVpdToolGuid
)
1211 SkuIds
= property(_GetSkuIds
)
1212 Modules
= property(_GetModules
)
1213 LibraryInstances
= property(_GetLibraryInstances
)
1214 LibraryClasses
= property(_GetLibraryClasses
)
1215 Pcds
= property(_GetPcds
)
1216 BuildOptions
= property(_GetBuildOptions
)
1218 ## Platform build information from DEC file
1220 # This class is used to retrieve information stored in database and convert them
1221 # into PackageBuildClassObject form for easier use for AutoGen.
1223 class DecBuildData(PackageBuildClassObject
):
1224 # dict used to convert PCD type in database to string used by build tool
1225 _PCD_TYPE_STRING_
= {
1226 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1227 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1228 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1229 MODEL_PCD_DYNAMIC
: "Dynamic",
1230 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1231 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1232 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1233 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1234 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1235 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1236 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1239 # dict used to convert part of [Defines] to members of DecBuildData directly
1244 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1245 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1246 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1247 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1251 ## Constructor of DecBuildData
1253 # Initialize object of DecBuildData
1255 # @param FilePath The path of package description file
1256 # @param RawData The raw data of DEC file
1257 # @param BuildDataBase Database used to retrieve module information
1258 # @param Arch The target architecture
1259 # @param Platform (not used for DecBuildData)
1260 # @param Macros Macros used for replacement in DSC file
1262 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1263 self
.MetaFile
= File
1264 self
._PackageDir
= File
.Dir
1265 self
._RawData
= RawData
1266 self
._Bdb
= BuildDataBase
1268 self
._Target
= Target
1269 self
._Toolchain
= Toolchain
1273 def __setitem__(self
, key
, value
):
1274 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1277 def __getitem__(self
, key
):
1278 return self
.__dict
__[self
._PROPERTY
_[key
]]
1280 ## "in" test support
1281 def __contains__(self
, key
):
1282 return key
in self
._PROPERTY
_
1284 ## Set all internal used members of DecBuildData to None
1287 self
._PackageName
= None
1289 self
._Version
= None
1290 self
._PkgUniFile
= None
1291 self
._Protocols
= None
1294 self
._Includes
= None
1295 self
._LibraryClasses
= None
1297 self
.__Macros
= None
1299 ## Get current effective macros
1300 def _GetMacros(self
):
1301 if self
.__Macros
== None:
1303 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1304 return self
.__Macros
1312 # Changing the default ARCH to another may affect all other information
1313 # because all information in a platform may be ARCH-related. That's
1314 # why we need to clear all internal used members, in order to cause all
1315 # information to be re-retrieved.
1317 # @param Value The value of ARCH
1319 def _SetArch(self
, Value
):
1320 if self
._Arch
== Value
:
1325 ## Retrieve all information in [Defines] section
1327 # (Retriving all [Defines] information in one-shot is just to save time.)
1329 def _GetHeaderInfo(self
):
1330 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1331 for Record
in RecordList
:
1334 self
[Name
] = Record
[2]
1335 self
._Header
= 'DUMMY'
1337 ## Retrieve package name
1338 def _GetPackageName(self
):
1339 if self
._PackageName
== None:
1340 if self
._Header
== None:
1341 self
._GetHeaderInfo
()
1342 if self
._PackageName
== None:
1343 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1344 return self
._PackageName
1346 ## Retrieve file guid
1347 def _GetFileGuid(self
):
1348 if self
._Guid
== None:
1349 if self
._Header
== None:
1350 self
._GetHeaderInfo
()
1351 if self
._Guid
== None:
1352 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1355 ## Retrieve package version
1356 def _GetVersion(self
):
1357 if self
._Version
== None:
1358 if self
._Header
== None:
1359 self
._GetHeaderInfo
()
1360 if self
._Version
== None:
1362 return self
._Version
1364 ## Retrieve protocol definitions (name/value pairs)
1365 def _GetProtocol(self
):
1366 if self
._Protocols
== None:
1368 # tdict is a special kind of dict, used for selecting correct
1369 # protocol defition for given ARCH
1371 ProtocolDict
= tdict(True)
1373 # find out all protocol definitions for specific and 'common' arch
1374 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1375 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1376 if Name
not in NameList
:
1377 NameList
.append(Name
)
1378 ProtocolDict
[Arch
, Name
] = Guid
1379 # use sdict to keep the order
1380 self
._Protocols
= sdict()
1381 for Name
in NameList
:
1383 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1384 # will automatically turn to 'common' ARCH for trying
1386 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1387 return self
._Protocols
1389 ## Retrieve PPI definitions (name/value pairs)
1391 if self
._Ppis
== None:
1393 # tdict is a special kind of dict, used for selecting correct
1394 # PPI defition for given ARCH
1396 PpiDict
= tdict(True)
1398 # find out all PPI definitions for specific arch and 'common' arch
1399 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1400 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1401 if Name
not in NameList
:
1402 NameList
.append(Name
)
1403 PpiDict
[Arch
, Name
] = Guid
1404 # use sdict to keep the order
1405 self
._Ppis
= sdict()
1406 for Name
in NameList
:
1408 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1409 # will automatically turn to 'common' ARCH for trying
1411 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1414 ## Retrieve GUID definitions (name/value pairs)
1416 if self
._Guids
== None:
1418 # tdict is a special kind of dict, used for selecting correct
1419 # GUID defition for given ARCH
1421 GuidDict
= tdict(True)
1423 # find out all protocol definitions for specific and 'common' arch
1424 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1425 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1426 if Name
not in NameList
:
1427 NameList
.append(Name
)
1428 GuidDict
[Arch
, Name
] = Guid
1429 # use sdict to keep the order
1430 self
._Guids
= sdict()
1431 for Name
in NameList
:
1433 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1434 # will automatically turn to 'common' ARCH for trying
1436 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1439 ## Retrieve public include paths declared in this package
1440 def _GetInclude(self
):
1441 if self
._Includes
== None:
1443 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1444 Macros
= self
._Macros
1445 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1446 for Record
in RecordList
:
1447 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1450 ErrorCode
, ErrorInfo
= File
.Validate()
1452 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1454 # avoid duplicate include path
1455 if File
not in self
._Includes
:
1456 self
._Includes
.append(File
)
1457 return self
._Includes
1459 ## Retrieve library class declarations (not used in build at present)
1460 def _GetLibraryClass(self
):
1461 if self
._LibraryClasses
== None:
1463 # tdict is a special kind of dict, used for selecting correct
1464 # library class declaration for given ARCH
1466 LibraryClassDict
= tdict(True)
1467 LibraryClassSet
= set()
1468 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1469 Macros
= self
._Macros
1470 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1471 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1472 # check the file validation
1473 ErrorCode
, ErrorInfo
= File
.Validate()
1475 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1476 LibraryClassSet
.add(LibraryClass
)
1477 LibraryClassDict
[Arch
, LibraryClass
] = File
1478 self
._LibraryClasses
= sdict()
1479 for LibraryClass
in LibraryClassSet
:
1480 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1481 return self
._LibraryClasses
1483 ## Retrieve PCD declarations
1485 if self
._Pcds
== None:
1486 self
._Pcds
= sdict()
1487 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1488 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1489 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1490 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1491 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1494 ## Retrieve PCD declarations for given type
1495 def _GetPcd(self
, Type
):
1498 # tdict is a special kind of dict, used for selecting correct
1499 # PCD declaration for given ARCH
1501 PcdDict
= tdict(True, 3)
1502 # for summarizing PCD
1504 # find out all PCDs of the 'type'
1505 RecordList
= self
._RawData
[Type
, self
._Arch
]
1506 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1507 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1508 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1510 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1512 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1513 # will automatically turn to 'common' ARCH and try again
1515 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1519 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1521 validateranges
, validlists
, expressions
= self
._RawData
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
1522 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1525 self
._PCD
_TYPE
_STRING
_[Type
],
1533 list(validateranges
),
1540 _Macros
= property(_GetMacros
)
1541 Arch
= property(_GetArch
, _SetArch
)
1542 PackageName
= property(_GetPackageName
)
1543 Guid
= property(_GetFileGuid
)
1544 Version
= property(_GetVersion
)
1546 Protocols
= property(_GetProtocol
)
1547 Ppis
= property(_GetPpi
)
1548 Guids
= property(_GetGuid
)
1549 Includes
= property(_GetInclude
)
1550 LibraryClasses
= property(_GetLibraryClass
)
1551 Pcds
= property(_GetPcds
)
1553 ## Module build information from INF file
1555 # This class is used to retrieve information stored in database and convert them
1556 # into ModuleBuildClassObject form for easier use for AutoGen.
1558 class InfBuildData(ModuleBuildClassObject
):
1559 # dict used to convert PCD type in database to string used by build tool
1560 _PCD_TYPE_STRING_
= {
1561 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1562 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1563 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1564 MODEL_PCD_DYNAMIC
: "Dynamic",
1565 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1566 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1567 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1568 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1569 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1570 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1571 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1574 # dict used to convert part of [Defines] to members of InfBuildData directly
1579 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1580 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1581 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1585 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1586 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1587 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1588 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1589 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1590 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1591 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1592 TAB_INF_DEFINES_VERSION
: "_Version",
1593 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1594 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1596 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1599 # dict used to convert Component type to Module type
1602 "SECURITY_CORE" : "SEC",
1603 "PEI_CORE" : "PEI_CORE",
1604 "COMBINED_PEIM_DRIVER" : "PEIM",
1605 "PIC_PEIM" : "PEIM",
1606 "RELOCATABLE_PEIM" : "PEIM",
1607 "PE32_PEIM" : "PEIM",
1608 "BS_DRIVER" : "DXE_DRIVER",
1609 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1610 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1611 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1612 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1613 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1614 # "BS_DRIVER" : "UEFI_DRIVER",
1615 "APPLICATION" : "UEFI_APPLICATION",
1619 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1620 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1621 # dict used to convert old tool name used in [nmake] section to new ones
1629 ## Constructor of DscBuildData
1631 # Initialize object of DscBuildData
1633 # @param FilePath The path of platform description file
1634 # @param RawData The raw data of DSC file
1635 # @param BuildDataBase Database used to retrieve module/package information
1636 # @param Arch The target architecture
1637 # @param Platform The name of platform employing this module
1638 # @param Macros Macros used for replacement in DSC file
1640 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1641 self
.MetaFile
= FilePath
1642 self
._ModuleDir
= FilePath
.Dir
1643 self
._RawData
= RawData
1644 self
._Bdb
= BuildDatabase
1646 self
._Target
= Target
1647 self
._Toolchain
= Toolchain
1648 self
._Platform
= 'COMMON'
1649 self
._SourceOverridePath
= None
1650 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1651 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1655 def __setitem__(self
, key
, value
):
1656 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1659 def __getitem__(self
, key
):
1660 return self
.__dict
__[self
._PROPERTY
_[key
]]
1662 ## "in" test support
1663 def __contains__(self
, key
):
1664 return key
in self
._PROPERTY
_
1666 ## Set all internal used members of InfBuildData to None
1668 self
._HeaderComments
= None
1669 self
._TailComments
= None
1670 self
._Header
_ = None
1671 self
._AutoGenVersion
= None
1672 self
._BaseName
= None
1673 self
._DxsFile
= None
1674 self
._ModuleType
= None
1675 self
._ComponentType
= None
1676 self
._BuildType
= None
1678 self
._Version
= None
1679 self
._PcdIsDriver
= None
1680 self
._BinaryModule
= None
1682 self
._MakefileName
= None
1683 self
._CustomMakefile
= None
1684 self
._Specification
= None
1685 self
._LibraryClass
= None
1686 self
._ModuleEntryPointList
= None
1687 self
._ModuleUnloadImageList
= None
1688 self
._ConstructorList
= None
1689 self
._DestructorList
= None
1691 self
._Binaries
= None
1692 self
._Sources
= None
1693 self
._LibraryClasses
= None
1694 self
._Libraries
= None
1695 self
._Protocols
= None
1696 self
._ProtocolComments
= None
1698 self
._PpiComments
= None
1700 self
._GuidsUsedByPcd
= sdict()
1701 self
._GuidComments
= None
1702 self
._Includes
= None
1703 self
._Packages
= None
1705 self
._PcdComments
= None
1706 self
._BuildOptions
= None
1708 self
._DepexExpression
= None
1709 self
.__Macros
= None
1711 ## Get current effective macros
1712 def _GetMacros(self
):
1713 if self
.__Macros
== None:
1715 # EDK_GLOBAL defined macros can be applied to EDK module
1716 if self
.AutoGenVersion
< 0x00010005:
1717 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1718 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1719 return self
.__Macros
1727 # Changing the default ARCH to another may affect all other information
1728 # because all information in a platform may be ARCH-related. That's
1729 # why we need to clear all internal used members, in order to cause all
1730 # information to be re-retrieved.
1732 # @param Value The value of ARCH
1734 def _SetArch(self
, Value
):
1735 if self
._Arch
== Value
:
1740 ## Return the name of platform employing this module
1741 def _GetPlatform(self
):
1742 return self
._Platform
1744 ## Change the name of platform employing this module
1746 # Changing the default name of platform to another may affect some information
1747 # because they may be PLATFORM-related. That's why we need to clear all internal
1748 # used members, in order to cause all information to be re-retrieved.
1750 def _SetPlatform(self
, Value
):
1751 if self
._Platform
== Value
:
1753 self
._Platform
= Value
1755 def _GetHeaderComments(self
):
1756 if not self
._HeaderComments
:
1757 self
._HeaderComments
= []
1758 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1759 for Record
in RecordList
:
1760 self
._HeaderComments
.append(Record
[0])
1761 return self
._HeaderComments
1762 def _GetTailComments(self
):
1763 if not self
._TailComments
:
1764 self
._TailComments
= []
1765 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1766 for Record
in RecordList
:
1767 self
._TailComments
.append(Record
[0])
1768 return self
._TailComments
1769 ## Retrieve all information in [Defines] section
1771 # (Retriving all [Defines] information in one-shot is just to save time.)
1773 def _GetHeaderInfo(self
):
1774 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1775 for Record
in RecordList
:
1776 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1777 # items defined _PROPERTY_ don't need additional processing
1780 if self
._Defs
== None:
1781 self
._Defs
= sdict()
1782 self
._Defs
[Name
] = Value
1783 # some special items in [Defines] section need special treatment
1784 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1785 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1786 Name
= 'UEFI_SPECIFICATION_VERSION'
1787 if self
._Specification
== None:
1788 self
._Specification
= sdict()
1789 self
._Specification
[Name
] = GetHexVerValue(Value
)
1790 if self
._Specification
[Name
] == None:
1791 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1792 "'%s' format is not supported for %s" % (Value
, Name
),
1793 File
=self
.MetaFile
, Line
=Record
[-1])
1794 elif Name
== 'LIBRARY_CLASS':
1795 if self
._LibraryClass
== None:
1796 self
._LibraryClass
= []
1797 ValueList
= GetSplitValueList(Value
)
1798 LibraryClass
= ValueList
[0]
1799 if len(ValueList
) > 1:
1800 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1802 SupModuleList
= SUP_MODULE_LIST
1803 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1804 elif Name
== 'ENTRY_POINT':
1805 if self
._ModuleEntryPointList
== None:
1806 self
._ModuleEntryPointList
= []
1807 self
._ModuleEntryPointList
.append(Value
)
1808 elif Name
== 'UNLOAD_IMAGE':
1809 if self
._ModuleUnloadImageList
== None:
1810 self
._ModuleUnloadImageList
= []
1813 self
._ModuleUnloadImageList
.append(Value
)
1814 elif Name
== 'CONSTRUCTOR':
1815 if self
._ConstructorList
== None:
1816 self
._ConstructorList
= []
1819 self
._ConstructorList
.append(Value
)
1820 elif Name
== 'DESTRUCTOR':
1821 if self
._DestructorList
== None:
1822 self
._DestructorList
= []
1825 self
._DestructorList
.append(Value
)
1826 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1827 TokenList
= GetSplitValueList(Value
)
1828 if self
._CustomMakefile
== None:
1829 self
._CustomMakefile
= {}
1830 if len(TokenList
) < 2:
1831 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1832 self
._CustomMakefile
['GCC'] = TokenList
[0]
1834 if TokenList
[0] not in ['MSFT', 'GCC']:
1835 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1836 "No supported family [%s]" % TokenList
[0],
1837 File
=self
.MetaFile
, Line
=Record
[-1])
1838 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1840 if self
._Defs
== None:
1841 self
._Defs
= sdict()
1842 self
._Defs
[Name
] = Value
1845 # Retrieve information in sections specific to Edk.x modules
1847 if self
.AutoGenVersion
>= 0x00010005:
1848 if not self
._ModuleType
:
1849 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1850 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1851 if self
._ModuleType
not in SUP_MODULE_LIST
:
1852 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1853 for Record
in RecordList
:
1855 if Name
== "MODULE_TYPE":
1858 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1859 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1860 File
=self
.MetaFile
, Line
=LineNo
)
1861 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1862 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1863 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
)
1864 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1865 and 'PCI_CLASS_CODE' in self
._Defs
:
1866 self
._BuildType
= 'UEFI_OPTIONROM'
1867 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1868 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1869 self
._BuildType
= 'UEFI_HII'
1871 self
._BuildType
= self
._ModuleType
.upper()
1874 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1875 # check the file validation
1876 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1878 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1879 File
=self
.MetaFile
, Line
=LineNo
)
1880 if self
.Sources
== None:
1882 self
._Sources
.append(File
)
1884 if not self
._ComponentType
:
1885 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1886 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1887 self
._BuildType
= self
._ComponentType
.upper()
1888 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1889 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1890 if self
._ComponentType
== 'LIBRARY':
1891 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1892 # make use some [nmake] section macros
1893 Macros
= self
._Macros
1894 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1895 Macros
['PROCESSOR'] = self
._Arch
1896 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1897 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1898 Value
= ReplaceMacro(Value
, Macros
, True)
1899 if Name
== "IMAGE_ENTRY_POINT":
1900 if self
._ModuleEntryPointList
== None:
1901 self
._ModuleEntryPointList
= []
1902 self
._ModuleEntryPointList
.append(Value
)
1903 elif Name
== "DPX_SOURCE":
1904 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1905 # check the file validation
1906 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1908 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1909 File
=self
.MetaFile
, Line
=LineNo
)
1910 if self
.Sources
== None:
1912 self
._Sources
.append(File
)
1914 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1915 if len(ToolList
) == 0 or len(ToolList
) != 1:
1917 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1918 # File=self.MetaFile, Line=LineNo)
1920 if self
._BuildOptions
== None:
1921 self
._BuildOptions
= sdict()
1923 if ToolList
[0] in self
._TOOL
_CODE
_:
1924 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1927 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1928 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1929 #ignore not replaced macros in value
1930 ValueList
= GetSplitList(' ' + Value
, '/D')
1931 Dummy
= ValueList
[0]
1932 for Index
in range(1, len(ValueList
)):
1933 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1935 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1936 Value
= Dummy
.strip()
1937 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1938 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1940 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1941 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1942 # set _Header to non-None in order to avoid database re-querying
1943 self
._Header
_ = 'DUMMY'
1945 ## Retrieve file version
1946 def _GetInfVersion(self
):
1947 if self
._AutoGenVersion
== None:
1948 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1949 for Record
in RecordList
:
1950 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1951 self
._AutoGenVersion
= int(Record
[2], 0)
1953 if self
._AutoGenVersion
== None:
1954 self
._AutoGenVersion
= 0x00010000
1955 return self
._AutoGenVersion
1957 ## Retrieve BASE_NAME
1958 def _GetBaseName(self
):
1959 if self
._BaseName
== None:
1960 if self
._Header
_ == None:
1961 self
._GetHeaderInfo
()
1962 if self
._BaseName
== None:
1963 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1964 return self
._BaseName
1967 def _GetDxsFile(self
):
1968 if self
._DxsFile
== None:
1969 if self
._Header
_ == None:
1970 self
._GetHeaderInfo
()
1971 if self
._DxsFile
== None:
1973 return self
._DxsFile
1975 ## Retrieve MODULE_TYPE
1976 def _GetModuleType(self
):
1977 if self
._ModuleType
== None:
1978 if self
._Header
_ == None:
1979 self
._GetHeaderInfo
()
1980 if self
._ModuleType
== None:
1981 self
._ModuleType
= 'BASE'
1982 if self
._ModuleType
not in SUP_MODULE_LIST
:
1983 self
._ModuleType
= "USER_DEFINED"
1984 return self
._ModuleType
1986 ## Retrieve COMPONENT_TYPE
1987 def _GetComponentType(self
):
1988 if self
._ComponentType
== None:
1989 if self
._Header
_ == None:
1990 self
._GetHeaderInfo
()
1991 if self
._ComponentType
== None:
1992 self
._ComponentType
= 'USER_DEFINED'
1993 return self
._ComponentType
1995 ## Retrieve "BUILD_TYPE"
1996 def _GetBuildType(self
):
1997 if self
._BuildType
== None:
1998 if self
._Header
_ == None:
1999 self
._GetHeaderInfo
()
2000 if not self
._BuildType
:
2001 self
._BuildType
= "BASE"
2002 return self
._BuildType
2004 ## Retrieve file guid
2005 def _GetFileGuid(self
):
2006 if self
._Guid
== None:
2007 if self
._Header
_ == None:
2008 self
._GetHeaderInfo
()
2009 if self
._Guid
== None:
2010 self
._Guid
= '00000000-0000-0000-000000000000'
2013 ## Retrieve module version
2014 def _GetVersion(self
):
2015 if self
._Version
== None:
2016 if self
._Header
_ == None:
2017 self
._GetHeaderInfo
()
2018 if self
._Version
== None:
2019 self
._Version
= '0.0'
2020 return self
._Version
2022 ## Retrieve PCD_IS_DRIVER
2023 def _GetPcdIsDriver(self
):
2024 if self
._PcdIsDriver
== None:
2025 if self
._Header
_ == None:
2026 self
._GetHeaderInfo
()
2027 if self
._PcdIsDriver
== None:
2028 self
._PcdIsDriver
= ''
2029 return self
._PcdIsDriver
2032 def _GetShadow(self
):
2033 if self
._Shadow
== None:
2034 if self
._Header
_ == None:
2035 self
._GetHeaderInfo
()
2036 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
2039 self
._Shadow
= False
2042 ## Retrieve CUSTOM_MAKEFILE
2043 def _GetMakefile(self
):
2044 if self
._CustomMakefile
== None:
2045 if self
._Header
_ == None:
2046 self
._GetHeaderInfo
()
2047 if self
._CustomMakefile
== None:
2048 self
._CustomMakefile
= {}
2049 return self
._CustomMakefile
2051 ## Retrieve EFI_SPECIFICATION_VERSION
2053 if self
._Specification
== None:
2054 if self
._Header
_ == None:
2055 self
._GetHeaderInfo
()
2056 if self
._Specification
== None:
2057 self
._Specification
= {}
2058 return self
._Specification
2060 ## Retrieve LIBRARY_CLASS
2061 def _GetLibraryClass(self
):
2062 if self
._LibraryClass
== None:
2063 if self
._Header
_ == None:
2064 self
._GetHeaderInfo
()
2065 if self
._LibraryClass
== None:
2066 self
._LibraryClass
= []
2067 return self
._LibraryClass
2069 ## Retrieve ENTRY_POINT
2070 def _GetEntryPoint(self
):
2071 if self
._ModuleEntryPointList
== None:
2072 if self
._Header
_ == None:
2073 self
._GetHeaderInfo
()
2074 if self
._ModuleEntryPointList
== None:
2075 self
._ModuleEntryPointList
= []
2076 return self
._ModuleEntryPointList
2078 ## Retrieve UNLOAD_IMAGE
2079 def _GetUnloadImage(self
):
2080 if self
._ModuleUnloadImageList
== None:
2081 if self
._Header
_ == None:
2082 self
._GetHeaderInfo
()
2083 if self
._ModuleUnloadImageList
== None:
2084 self
._ModuleUnloadImageList
= []
2085 return self
._ModuleUnloadImageList
2087 ## Retrieve CONSTRUCTOR
2088 def _GetConstructor(self
):
2089 if self
._ConstructorList
== None:
2090 if self
._Header
_ == None:
2091 self
._GetHeaderInfo
()
2092 if self
._ConstructorList
== None:
2093 self
._ConstructorList
= []
2094 return self
._ConstructorList
2096 ## Retrieve DESTRUCTOR
2097 def _GetDestructor(self
):
2098 if self
._DestructorList
== None:
2099 if self
._Header
_ == None:
2100 self
._GetHeaderInfo
()
2101 if self
._DestructorList
== None:
2102 self
._DestructorList
= []
2103 return self
._DestructorList
2105 ## Retrieve definies other than above ones
2106 def _GetDefines(self
):
2107 if self
._Defs
== None:
2108 if self
._Header
_ == None:
2109 self
._GetHeaderInfo
()
2110 if self
._Defs
== None:
2111 self
._Defs
= sdict()
2114 ## Retrieve binary files
2115 def _GetBinaries(self
):
2116 if self
._Binaries
== None:
2118 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2119 Macros
= self
._Macros
2120 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2121 Macros
['PROCESSOR'] = self
._Arch
2122 for Record
in RecordList
:
2123 FileType
= Record
[0]
2128 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2130 Target
= TokenList
[0]
2131 if len(TokenList
) > 1:
2132 FeatureFlag
= Record
[1:]
2134 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2135 # check the file validation
2136 ErrorCode
, ErrorInfo
= File
.Validate()
2138 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2139 self
._Binaries
.append(File
)
2140 return self
._Binaries
2142 ## Retrieve binary files with error check.
2143 def _GetBinaryFiles(self
):
2144 Binaries
= self
._GetBinaries
()
2145 if GlobalData
.gIgnoreSource
and Binaries
== []:
2146 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2147 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2150 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2151 def _IsSupportedArch(self
):
2152 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2156 ## Retrieve source files
2157 def _GetSourceFiles(self
):
2158 #Ignore all source files in a binary build mode
2159 if GlobalData
.gIgnoreSource
:
2161 return self
._Sources
2163 if self
._Sources
== None:
2165 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2166 Macros
= self
._Macros
2167 for Record
in RecordList
:
2169 ToolChainFamily
= Record
[1]
2171 ToolCode
= Record
[3]
2172 FeatureFlag
= Record
[4]
2173 if self
.AutoGenVersion
< 0x00010005:
2174 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2175 Macros
['PROCESSOR'] = self
._Arch
2176 # old module source files (Edk)
2177 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
2178 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2179 # check the file validation
2180 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2182 if File
.Ext
.lower() == '.h':
2183 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2184 File
=self
.MetaFile
, Line
=LineNo
)
2187 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2189 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2190 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2191 # check the file validation
2192 ErrorCode
, ErrorInfo
= File
.Validate()
2194 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2196 self
._Sources
.append(File
)
2197 return self
._Sources
2199 ## Retrieve library classes employed by this module
2200 def _GetLibraryClassUses(self
):
2201 if self
._LibraryClasses
== None:
2202 self
._LibraryClasses
= sdict()
2203 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2204 for Record
in RecordList
:
2206 Instance
= Record
[1]
2208 Instance
= NormPath(Instance
, self
._Macros
)
2209 self
._LibraryClasses
[Lib
] = Instance
2210 return self
._LibraryClasses
2212 ## Retrieve library names (for Edk.x style of modules)
2213 def _GetLibraryNames(self
):
2214 if self
._Libraries
== None:
2215 self
._Libraries
= []
2216 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2217 for Record
in RecordList
:
2218 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2219 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2220 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2221 if LibraryName
not in self
._Libraries
:
2222 self
._Libraries
.append(LibraryName
)
2223 return self
._Libraries
2225 def _GetProtocolComments(self
):
2226 self
._GetProtocols
()
2227 return self
._ProtocolComments
2228 ## Retrieve protocols consumed/produced by this module
2229 def _GetProtocols(self
):
2230 if self
._Protocols
== None:
2231 self
._Protocols
= sdict()
2232 self
._ProtocolComments
= sdict()
2233 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2234 for Record
in RecordList
:
2236 Value
= ProtocolValue(CName
, self
.Packages
)
2238 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2239 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2240 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2241 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2242 self
._Protocols
[CName
] = Value
2243 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2245 for CmtRec
in CommentRecords
:
2246 Comments
.append(CmtRec
[0])
2247 self
._ProtocolComments
[CName
] = Comments
2248 return self
._Protocols
2250 def _GetPpiComments(self
):
2252 return self
._PpiComments
2253 ## Retrieve PPIs consumed/produced by this module
2255 if self
._Ppis
== None:
2256 self
._Ppis
= sdict()
2257 self
._PpiComments
= sdict()
2258 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2259 for Record
in RecordList
:
2261 Value
= PpiValue(CName
, self
.Packages
)
2263 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2264 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2265 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2266 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2267 self
._Ppis
[CName
] = Value
2268 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2270 for CmtRec
in CommentRecords
:
2271 Comments
.append(CmtRec
[0])
2272 self
._PpiComments
[CName
] = Comments
2275 def _GetGuidComments(self
):
2277 return self
._GuidComments
2278 ## Retrieve GUIDs consumed/produced by this module
2279 def _GetGuids(self
):
2280 if self
._Guids
== None:
2281 self
._Guids
= sdict()
2282 self
._GuidComments
= sdict()
2283 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2284 for Record
in RecordList
:
2286 Value
= GuidValue(CName
, self
.Packages
)
2288 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2289 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2290 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2291 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2292 self
._Guids
[CName
] = Value
2293 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2295 for CmtRec
in CommentRecords
:
2296 Comments
.append(CmtRec
[0])
2297 self
._GuidComments
[CName
] = Comments
2300 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2301 def _GetIncludes(self
):
2302 if self
._Includes
== None:
2304 if self
._SourceOverridePath
:
2305 self
._Includes
.append(self
._SourceOverridePath
)
2307 Macros
= self
._Macros
2308 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2309 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2311 Macros
['PROCESSOR'] = self
._Arch
2312 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2313 for Record
in RecordList
:
2314 if Record
[0].find('EDK_SOURCE') > -1:
2315 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2316 File
= NormPath(Record
[0], self
._Macros
)
2318 File
= os
.path
.join(self
._ModuleDir
, File
)
2320 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2321 File
= RealPath(os
.path
.normpath(File
))
2323 self
._Includes
.append(File
)
2325 #TRICK: let compiler to choose correct header file
2326 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2327 File
= NormPath(Record
[0], self
._Macros
)
2329 File
= os
.path
.join(self
._ModuleDir
, File
)
2331 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2332 File
= RealPath(os
.path
.normpath(File
))
2334 self
._Includes
.append(File
)
2336 File
= NormPath(Record
[0], Macros
)
2338 File
= os
.path
.join(self
._ModuleDir
, File
)
2340 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2341 File
= RealPath(os
.path
.normpath(File
))
2343 self
._Includes
.append(File
)
2344 return self
._Includes
2346 ## Retrieve packages this module depends on
2347 def _GetPackages(self
):
2348 if self
._Packages
== None:
2350 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2351 Macros
= self
._Macros
2352 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2353 for Record
in RecordList
:
2354 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2356 # check the file validation
2357 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2359 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2360 # parse this package now. we need it to get protocol/ppi/guid value
2361 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2362 self
._Packages
.append(Package
)
2363 return self
._Packages
2365 ## Retrieve PCD comments
2366 def _GetPcdComments(self
):
2368 return self
._PcdComments
2369 ## Retrieve PCDs used in this module
2371 if self
._Pcds
== None:
2372 self
._Pcds
= sdict()
2373 self
._PcdComments
= sdict()
2374 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2375 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2376 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2377 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2378 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2381 ## Retrieve build options specific to this module
2382 def _GetBuildOptions(self
):
2383 if self
._BuildOptions
== None:
2384 self
._BuildOptions
= sdict()
2385 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2386 for Record
in RecordList
:
2387 ToolChainFamily
= Record
[0]
2388 ToolChain
= Record
[1]
2390 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2391 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2393 # concatenate the option string if they're for the same tool
2394 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2395 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2396 return self
._BuildOptions
2398 ## Retrieve dependency expression
2399 def _GetDepex(self
):
2400 if self
._Depex
== None:
2401 self
._Depex
= tdict(False, 2)
2402 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2404 # If the module has only Binaries and no Sources, then ignore [Depex]
2405 if self
.Sources
== None or self
.Sources
== []:
2406 if self
.Binaries
!= None and self
.Binaries
!= []:
2409 # PEIM and DXE drivers must have a valid [Depex] section
2410 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2411 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2412 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2413 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2414 % self
.ModuleType
, File
=self
.MetaFile
)
2416 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2417 for Record
in RecordList
:
2418 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2419 EdkLogger
.error('build', FORMAT_INVALID
,
2420 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2424 for Record
in RecordList
:
2425 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2427 ModuleType
= Record
[4]
2428 TokenList
= DepexStr
.split()
2429 if (Arch
, ModuleType
) not in Depex
:
2430 Depex
[Arch
, ModuleType
] = []
2431 DepexList
= Depex
[Arch
, ModuleType
]
2432 for Token
in TokenList
:
2433 if Token
in DEPEX_SUPPORTED_OPCODE
:
2434 DepexList
.append(Token
)
2435 elif Token
.endswith(".inf"): # module file name
2436 ModuleFile
= os
.path
.normpath(Token
)
2437 Module
= self
.BuildDatabase
[ModuleFile
]
2439 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2440 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2441 DepexList
.append(Module
.Guid
)
2443 # get the GUID value now
2444 Value
= ProtocolValue(Token
, self
.Packages
)
2446 Value
= PpiValue(Token
, self
.Packages
)
2448 Value
= GuidValue(Token
, self
.Packages
)
2450 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2451 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2452 "Value of [%s] is not found in" % Token
,
2453 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2454 DepexList
.append(Value
)
2455 for Arch
, ModuleType
in Depex
:
2456 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2459 ## Retrieve depedency expression
2460 def _GetDepexExpression(self
):
2461 if self
._DepexExpression
== None:
2462 self
._DepexExpression
= tdict(False, 2)
2463 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2464 DepexExpression
= sdict()
2465 for Record
in RecordList
:
2466 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2468 ModuleType
= Record
[4]
2469 TokenList
= DepexStr
.split()
2470 if (Arch
, ModuleType
) not in DepexExpression
:
2471 DepexExpression
[Arch
, ModuleType
] = ''
2472 for Token
in TokenList
:
2473 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2474 for Arch
, ModuleType
in DepexExpression
:
2475 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2476 return self
._DepexExpression
2478 def GetGuidsUsedByPcd(self
):
2479 return self
._GuidsUsedByPcd
2480 ## Retrieve PCD for given type
2481 def _GetPcd(self
, Type
):
2483 PcdDict
= tdict(True, 4)
2485 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2486 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2487 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2488 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2489 # get the guid value
2490 if TokenSpaceGuid
not in self
.Guids
:
2491 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2493 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2494 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2495 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2496 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2497 self
.Guids
[TokenSpaceGuid
] = Value
2498 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2499 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2501 for CmtRec
in CommentRecords
:
2502 Comments
.append(CmtRec
[0])
2503 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2505 # resolve PCD type, value, datum info, etc. by getting its definition from package
2506 for PcdCName
, TokenSpaceGuid
in PcdList
:
2507 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2510 ValueList
= AnalyzePcdData(Setting
)
2511 DefaultValue
= ValueList
[0]
2512 Pcd
= PcdClassObject(
2522 self
.Guids
[TokenSpaceGuid
]
2524 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2525 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2526 Pcd
.Offset
= ValueList
[1]
2528 # get necessary info from package declaring this PCD
2529 for Package
in self
.Packages
:
2531 # 'dynamic' in INF means its type is determined by platform;
2532 # if platform doesn't give its type, use 'lowest' one in the
2533 # following order, if any
2535 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2537 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2538 if Type
== MODEL_PCD_DYNAMIC
:
2540 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2541 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2547 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2548 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2550 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2553 # Check whether the token value exist or not.
2555 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2559 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2560 File
=self
.MetaFile
, Line
=LineNo
,
2564 # Check hexadecimal token value length and format.
2566 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2567 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2568 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2572 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2573 File
=self
.MetaFile
, Line
=LineNo
,
2578 # Check decimal token value length and format.
2582 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2583 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2587 "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
)),
2588 File
=self
.MetaFile
, Line
=LineNo
,
2595 "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
)),
2596 File
=self
.MetaFile
, Line
=LineNo
,
2600 Pcd
.DatumType
= PcdInPackage
.DatumType
2601 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2602 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2603 if Pcd
.DefaultValue
in [None, '']:
2604 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2610 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2611 File
=self
.MetaFile
, Line
=LineNo
,
2612 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2614 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2618 ## check whether current module is binary module
2619 def _IsBinaryModule(self
):
2620 if self
.Binaries
and not self
.Sources
:
2622 elif GlobalData
.gIgnoreSource
:
2627 _Macros
= property(_GetMacros
)
2628 Arch
= property(_GetArch
, _SetArch
)
2629 Platform
= property(_GetPlatform
, _SetPlatform
)
2631 HeaderComments
= property(_GetHeaderComments
)
2632 TailComments
= property(_GetTailComments
)
2633 AutoGenVersion
= property(_GetInfVersion
)
2634 BaseName
= property(_GetBaseName
)
2635 ModuleType
= property(_GetModuleType
)
2636 ComponentType
= property(_GetComponentType
)
2637 BuildType
= property(_GetBuildType
)
2638 Guid
= property(_GetFileGuid
)
2639 Version
= property(_GetVersion
)
2640 PcdIsDriver
= property(_GetPcdIsDriver
)
2641 Shadow
= property(_GetShadow
)
2642 CustomMakefile
= property(_GetMakefile
)
2643 Specification
= property(_GetSpec
)
2644 LibraryClass
= property(_GetLibraryClass
)
2645 ModuleEntryPointList
= property(_GetEntryPoint
)
2646 ModuleUnloadImageList
= property(_GetUnloadImage
)
2647 ConstructorList
= property(_GetConstructor
)
2648 DestructorList
= property(_GetDestructor
)
2649 Defines
= property(_GetDefines
)
2650 DxsFile
= property(_GetDxsFile
)
2652 Binaries
= property(_GetBinaryFiles
)
2653 Sources
= property(_GetSourceFiles
)
2654 LibraryClasses
= property(_GetLibraryClassUses
)
2655 Libraries
= property(_GetLibraryNames
)
2656 Protocols
= property(_GetProtocols
)
2657 ProtocolComments
= property(_GetProtocolComments
)
2658 Ppis
= property(_GetPpis
)
2659 PpiComments
= property(_GetPpiComments
)
2660 Guids
= property(_GetGuids
)
2661 GuidComments
= property(_GetGuidComments
)
2662 Includes
= property(_GetIncludes
)
2663 Packages
= property(_GetPackages
)
2664 Pcds
= property(_GetPcds
)
2665 PcdComments
= property(_GetPcdComments
)
2666 BuildOptions
= property(_GetBuildOptions
)
2667 Depex
= property(_GetDepex
)
2668 DepexExpression
= property(_GetDepexExpression
)
2669 IsBinaryModule
= property(_IsBinaryModule
)
2670 IsSupportedArch
= property(_IsSupportedArch
)
2674 # This class defined the build database for all modules, packages and platform.
2675 # It will call corresponding parser for the given file if it cannot find it in
2678 # @param DbPath Path of database file
2679 # @param GlobalMacros Global macros used for replacement during file parsing
2680 # @prarm RenewDb=False Create new database file if it's already there
2682 class WorkspaceDatabase(object):
2686 # internal class used for call corresponding file parser and caching the result
2687 # to avoid unnecessary re-parsing
2689 class BuildObjectFactory(object):
2692 ".inf" : MODEL_FILE_INF
,
2693 ".dec" : MODEL_FILE_DEC
,
2694 ".dsc" : MODEL_FILE_DSC
,
2699 MODEL_FILE_INF
: InfParser
,
2700 MODEL_FILE_DEC
: DecParser
,
2701 MODEL_FILE_DSC
: DscParser
,
2704 # convert to xxxBuildData object
2706 MODEL_FILE_INF
: InfBuildData
,
2707 MODEL_FILE_DEC
: DecBuildData
,
2708 MODEL_FILE_DSC
: DscBuildData
,
2711 _CACHE_
= {} # (FilePath, Arch) : <object>
2714 def __init__(self
, WorkspaceDb
):
2715 self
.WorkspaceDb
= WorkspaceDb
2717 # key = (FilePath, Arch=None)
2718 def __contains__(self
, Key
):
2724 return (FilePath
, Arch
) in self
._CACHE
_
2726 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2727 def __getitem__(self
, Key
):
2729 KeyLength
= len(Key
)
2743 # if it's generated before, just return the cached one
2744 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2745 if Key
in self
._CACHE
_:
2746 return self
._CACHE
_[Key
]
2750 if Ext
not in self
._FILE
_TYPE
_:
2752 FileType
= self
._FILE
_TYPE
_[Ext
]
2753 if FileType
not in self
._GENERATOR
_:
2756 # get the parser ready for this file
2757 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2760 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2762 # alwasy do post-process, in case of macros change
2763 MetaFile
.DoPostProcess()
2764 # object the build is based on
2765 BuildObject
= self
._GENERATOR
_[FileType
](
2773 self
._CACHE
_[Key
] = BuildObject
2776 # placeholder for file format conversion
2777 class TransformObjectFactory
:
2778 def __init__(self
, WorkspaceDb
):
2779 self
.WorkspaceDb
= WorkspaceDb
2781 # key = FilePath, Arch
2782 def __getitem__(self
, Key
):
2785 ## Constructor of WorkspaceDatabase
2787 # @param DbPath Path of database file
2788 # @param GlobalMacros Global macros used for replacement during file parsing
2789 # @prarm RenewDb=False Create new database file if it's already there
2791 def __init__(self
, DbPath
, RenewDb
=False):
2792 self
._DbClosedFlag
= False
2794 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2796 # don't create necessary path for db in memory
2797 if DbPath
!= ':memory:':
2798 DbDir
= os
.path
.split(DbPath
)[0]
2799 if not os
.path
.exists(DbDir
):
2802 # remove db file in case inconsistency between db and file in file system
2803 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2806 # create db with optimized parameters
2807 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2808 self
.Conn
.execute("PRAGMA synchronous=OFF")
2809 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2810 self
.Conn
.execute("PRAGMA count_changes=OFF")
2811 self
.Conn
.execute("PRAGMA cache_size=8192")
2812 #self.Conn.execute("PRAGMA page_size=8192")
2814 # to avoid non-ascii character conversion issue
2815 self
.Conn
.text_factory
= str
2816 self
.Cur
= self
.Conn
.cursor()
2818 # create table for internal uses
2819 self
.TblDataModel
= TableDataModel(self
.Cur
)
2820 self
.TblFile
= TableFile(self
.Cur
)
2821 self
.Platform
= None
2823 # conversion object for build or file format conversion purpose
2824 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2825 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2827 ## Check whether workspace database need to be renew.
2828 # The renew reason maybe:
2829 # 1) If user force to renew;
2830 # 2) If user do not force renew, and
2831 # a) If the time of last modified python source is newer than database file;
2832 # b) If the time of last modified frozen executable file is newer than database file;
2834 # @param force User force renew database
2835 # @param DbPath The absolute path of workspace database file
2837 # @return Bool value for whether need renew workspace databse
2839 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2840 # if database does not exist, we need do nothing
2841 if not os
.path
.exists(DbPath
): return False
2843 # if user force to renew database, then not check whether database is out of date
2844 if force
: return True
2847 # Check the time of last modified source file or build.exe
2848 # if is newer than time of database, then database need to be re-created.
2850 timeOfToolModified
= 0
2851 if hasattr(sys
, "frozen"):
2852 exePath
= os
.path
.abspath(sys
.executable
)
2853 timeOfToolModified
= os
.stat(exePath
).st_mtime
2855 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2856 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2857 if rootPath
== "" or rootPath
== None:
2858 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2859 determine whether database file is out of date!\n")
2861 # walk the root path of source or build's binary to get the time last modified.
2863 for root
, dirs
, files
in os
.walk (rootPath
):
2865 # bypass source control folder
2866 if dir.lower() in [".svn", "_svn", "cvs"]:
2870 ext
= os
.path
.splitext(file)[1]
2871 if ext
.lower() == ".py": # only check .py files
2872 fd
= os
.stat(os
.path
.join(root
, file))
2873 if timeOfToolModified
< fd
.st_mtime
:
2874 timeOfToolModified
= fd
.st_mtime
2875 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2876 EdkLogger
.verbose("\nWorkspace database is out of data!")
2881 ## Initialize build database
2882 def InitDatabase(self
):
2883 EdkLogger
.verbose("\nInitialize build database started ...")
2888 self
.TblDataModel
.Create(False)
2889 self
.TblFile
.Create(False)
2892 # Initialize table DataModel
2894 self
.TblDataModel
.InitTable()
2895 EdkLogger
.verbose("Initialize build database ... DONE!")
2899 # @param Table: The instance of the table to be queried
2901 def QueryTable(self
, Table
):
2907 ## Close entire database
2910 # Close the connection and cursor
2913 if not self
._DbClosedFlag
:
2917 self
._DbClosedFlag
= True
2919 ## Summarize all packages in the database
2920 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2921 self
.Platform
= Platform
2923 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2925 # Get Package related to Modules
2927 for Module
in Pa
.Modules
:
2928 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2929 for Package
in ModuleObj
.Packages
:
2930 if Package
not in PackageList
:
2931 PackageList
.append(Package
)
2933 # Get Packages related to Libraries
2935 for Lib
in Pa
.LibraryInstances
:
2936 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2937 for Package
in LibObj
.Packages
:
2938 if Package
not in PackageList
:
2939 PackageList
.append(Package
)
2943 ## Summarize all platforms in the database
2944 def _GetPlatformList(self
):
2946 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2948 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2951 if Platform
!= None:
2952 PlatformList
.append(Platform
)
2955 PlatformList
= property(_GetPlatformList
)
2959 # This acts like the main() function for the script, unless it is 'import'ed into another
2962 if __name__
== '__main__':