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:
757 self
._BuildOptions
= sdict()
759 # Retrieve build option for EDKII and EDK style module
761 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
762 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
763 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
764 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
765 if Option
.startswith('='):
766 OverrideTool
.add(CurKey
)
768 # Only flags can be appended
770 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or CurKey
in OverrideTool
:
771 self
._BuildOptions
[CurKey
] = Option
773 self
._BuildOptions
[CurKey
] += ' ' + Option
774 return self
._BuildOptions
776 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
777 if self
._ModuleTypeOptions
== None:
778 self
._ModuleTypeOptions
= sdict()
779 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
782 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
783 DriverType
= '%s.%s' % (Edk
, ModuleType
)
784 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, DriverType
]
785 for ToolChainFamily
, ToolChain
, Option
, Arch
, Type
, Dummy3
, Dummy4
in RecordList
:
786 if Arch
== self
._Arch
and Type
== DriverType
:
787 Key
= (ToolChainFamily
, ToolChain
, Edk
)
788 if Option
.startswith('='):
789 OverrideTool
.add(Key
)
790 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Key
in OverrideTool
:
791 options
[Key
] = Option
793 options
[Key
] += ' ' + Option
794 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
796 ## Retrieve non-dynamic PCD settings
798 # @param Type PCD type
800 # @retval a dict object contains settings of given PCD type
802 def _GetPcd(self
, Type
):
805 # tdict is a special dict kind of type, used for selecting correct
806 # PCD settings for certain ARCH
809 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
811 PcdDict
= tdict(True, 3)
813 # Find out all possible PCD candidates for self._Arch
814 RecordList
= self
._RawData
[Type
, self
._Arch
]
815 PcdValueDict
= sdict()
816 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
817 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
818 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
819 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
821 #handle pcd value override
822 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
823 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
826 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
827 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
828 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
830 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
832 PcdsKeys
= PcdValueDict
.keys()
833 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
835 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
839 if 'COMMON' in PcdSetting
:
840 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
841 if 'DEFAULT' in PcdSetting
:
842 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
843 if SkuObj
.SystemSkuId
in PcdSetting
:
844 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
846 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
849 self
._PCD
_TYPE
_STRING
_[Type
],
860 ## Retrieve dynamic PCD settings
862 # @param Type PCD type
864 # @retval a dict object contains settings of given PCD type
866 def _GetDynamicPcd(self
, Type
):
868 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
872 # tdict is a special dict kind of type, used for selecting correct
873 # PCD settings for certain ARCH and SKU
875 PcdDict
= tdict(True, 4)
877 # Find out all possible PCD candidates for self._Arch
878 RecordList
= self
._RawData
[Type
, self
._Arch
]
879 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
881 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
882 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
883 if SkuName
not in AvailableSkuIdSet
:
886 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
887 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
888 # Remove redundant PCD candidates, per the ARCH and SKU
889 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
891 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
895 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
896 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
897 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
898 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
899 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
900 if MaxDatumSize
.strip():
901 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
904 if pcdObject
.MaxDatumSize
:
905 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
908 if CurrentMaxSize
> PcdMaxSize
:
909 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
911 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
914 self
._PCD
_TYPE
_STRING
_[Type
],
924 for pcd
in Pcds
.values():
925 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
926 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
927 valuefromDec
= pcdDecObject
.DefaultValue
928 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
929 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
930 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
931 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
932 del(pcd
.SkuInfoList
['COMMON'])
933 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
934 del(pcd
.SkuInfoList
['COMMON'])
935 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
936 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
937 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
938 del(pcd
.SkuInfoList
['DEFAULT'])
942 def CompareVarAttr(self
, Attr1
, Attr2
):
943 if not Attr1
or not Attr2
: # for empty string
945 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
946 Attr1Set
= set(Attr1s
)
947 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
948 Attr2Set
= set(Attr2s
)
949 if Attr2Set
== Attr1Set
:
953 ## Retrieve dynamic HII PCD settings
955 # @param Type PCD type
957 # @retval a dict object contains settings of given PCD type
959 def _GetDynamicHiiPcd(self
, Type
):
961 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
966 # tdict is a special dict kind of type, used for selecting correct
967 # PCD settings for certain ARCH and SKU
969 PcdDict
= tdict(True, 4)
971 RecordList
= self
._RawData
[Type
, self
._Arch
]
972 # Find out all possible PCD candidates for self._Arch
973 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
975 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
976 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
977 if SkuName
not in AvailableSkuIdSet
:
979 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
980 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
981 # Remove redundant PCD candidates, per the ARCH and SKU
982 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
984 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
987 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
989 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
991 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
992 ExtraData
= "[%s]" % VarAttribute
)
995 if VariableOffset
.isdigit():
996 if int(VariableOffset
,10) > 0xFFFF:
998 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
999 if int(VariableOffset
,16) > 0xFFFF:
1001 # For Offset written in "A.B"
1002 elif VariableOffset
.find('.') > -1:
1003 VariableOffsetList
= VariableOffset
.split(".")
1004 if not (len(VariableOffsetList
) == 2
1005 and IsValidWord(VariableOffsetList
[0])
1006 and IsValidWord(VariableOffsetList
[1])):
1007 FormatCorrect
= False
1009 FormatCorrect
= False
1010 if not FormatCorrect
:
1011 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1014 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1015 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1016 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1018 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1019 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
)]))
1021 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
= VarAttribute
)
1022 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1023 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1024 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1025 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1027 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1030 self
._PCD
_TYPE
_STRING
_[Type
],
1035 {SkuName
: SkuInfo
},
1038 pcdDecObject
.validateranges
,
1039 pcdDecObject
.validlists
,
1040 pcdDecObject
.expressions
1044 for pcd
in Pcds
.values():
1045 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1046 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1047 # Only fix the value while no value provided in DSC file.
1048 for sku
in pcd
.SkuInfoList
.values():
1049 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
1050 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1051 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1052 valuefromDec
= pcdDecObject
.DefaultValue
1053 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
1054 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1055 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1056 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1057 del(pcd
.SkuInfoList
['COMMON'])
1058 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1059 del(pcd
.SkuInfoList
['COMMON'])
1061 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1062 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1063 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1064 del(pcd
.SkuInfoList
['DEFAULT'])
1067 if pcd
.MaxDatumSize
.strip():
1068 MaxSize
= int(pcd
.MaxDatumSize
,0)
1071 if pcdDecObject
.DatumType
== 'VOID*':
1072 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1074 if skuobj
.HiiDefaultValue
.startswith("L"):
1075 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
1076 elif skuobj
.HiiDefaultValue
.startswith("{"):
1077 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1079 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
1082 pcd
.MaxDatumSize
= str(MaxSize
)
1085 ## Retrieve dynamic VPD PCD settings
1087 # @param Type PCD type
1089 # @retval a dict object contains settings of given PCD type
1091 def _GetDynamicVpdPcd(self
, Type
):
1093 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
1097 # tdict is a special dict kind of type, used for selecting correct
1098 # PCD settings for certain ARCH and SKU
1100 PcdDict
= tdict(True, 4)
1102 # Find out all possible PCD candidates for self._Arch
1103 RecordList
= self
._RawData
[Type
, self
._Arch
]
1104 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1106 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1107 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1108 if SkuName
not in AvailableSkuIdSet
:
1111 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1112 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1113 # Remove redundant PCD candidates, per the ARCH and SKU
1114 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1115 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1119 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1120 # For the Integer & Boolean type, the optional data can only be InitialValue.
1121 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1122 # until the DEC parser has been called.
1124 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1125 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1126 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1127 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1128 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1129 if MaxDatumSize
.strip():
1130 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1133 if pcdObject
.MaxDatumSize
:
1134 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1137 if CurrentMaxSize
> PcdMaxSize
:
1138 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1140 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1143 self
._PCD
_TYPE
_STRING
_[Type
],
1148 {SkuName
: SkuInfo
},
1152 for pcd
in Pcds
.values():
1153 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1154 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1155 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1156 valuefromDec
= pcdDecObject
.DefaultValue
1157 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1158 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1159 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1160 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1161 del(pcd
.SkuInfoList
['COMMON'])
1162 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1163 del(pcd
.SkuInfoList
['COMMON'])
1164 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1165 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1166 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1167 del(pcd
.SkuInfoList
['DEFAULT'])
1171 ## Add external modules
1173 # The external modules are mostly those listed in FDF file, which don't
1176 # @param FilePath The path of module description file
1178 def AddModule(self
, FilePath
):
1179 FilePath
= NormPath(FilePath
)
1180 if FilePath
not in self
.Modules
:
1181 Module
= ModuleBuildClassObject()
1182 Module
.MetaFile
= FilePath
1183 self
.Modules
.append(Module
)
1185 ## Add external PCDs
1187 # The external PCDs are mostly those listed in FDF file to specify address
1188 # or offset information.
1190 # @param Name Name of the PCD
1191 # @param Guid Token space guid of the PCD
1192 # @param Value Value of the PCD
1194 def AddPcd(self
, Name
, Guid
, Value
):
1195 if (Name
, Guid
) not in self
.Pcds
:
1196 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1197 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1199 _Macros
= property(_GetMacros
)
1200 Arch
= property(_GetArch
, _SetArch
)
1201 Platform
= property(_GetPlatformName
)
1202 PlatformName
= property(_GetPlatformName
)
1203 Guid
= property(_GetFileGuid
)
1204 Version
= property(_GetVersion
)
1205 DscSpecification
= property(_GetDscSpec
)
1206 OutputDirectory
= property(_GetOutpuDir
)
1207 SupArchList
= property(_GetSupArch
)
1208 BuildTargets
= property(_GetBuildTarget
)
1209 SkuName
= property(_GetSkuName
, _SetSkuName
)
1210 SkuIdentifier
= property(_GetSkuIdentifier
)
1211 AvilableSkuIds
= property(_GetAviableSkuIds
)
1212 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1213 VarCheckFlag
= property(_GetVarCheckFlag
)
1214 FlashDefinition
= property(_GetFdfFile
)
1215 BuildNumber
= property(_GetBuildNumber
)
1216 MakefileName
= property(_GetMakefileName
)
1217 BsBaseAddress
= property(_GetBsBaseAddress
)
1218 RtBaseAddress
= property(_GetRtBaseAddress
)
1219 LoadFixAddress
= property(_GetLoadFixAddress
)
1220 RFCLanguages
= property(_GetRFCLanguages
)
1221 ISOLanguages
= property(_GetISOLanguages
)
1222 VpdToolGuid
= property(_GetVpdToolGuid
)
1223 SkuIds
= property(_GetSkuIds
)
1224 Modules
= property(_GetModules
)
1225 LibraryInstances
= property(_GetLibraryInstances
)
1226 LibraryClasses
= property(_GetLibraryClasses
)
1227 Pcds
= property(_GetPcds
)
1228 BuildOptions
= property(_GetBuildOptions
)
1230 ## Platform build information from DEC file
1232 # This class is used to retrieve information stored in database and convert them
1233 # into PackageBuildClassObject form for easier use for AutoGen.
1235 class DecBuildData(PackageBuildClassObject
):
1236 # dict used to convert PCD type in database to string used by build tool
1237 _PCD_TYPE_STRING_
= {
1238 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1239 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1240 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1241 MODEL_PCD_DYNAMIC
: "Dynamic",
1242 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1243 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1244 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1245 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1246 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1247 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1248 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1251 # dict used to convert part of [Defines] to members of DecBuildData directly
1256 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1257 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1258 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1259 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1263 ## Constructor of DecBuildData
1265 # Initialize object of DecBuildData
1267 # @param FilePath The path of package description file
1268 # @param RawData The raw data of DEC file
1269 # @param BuildDataBase Database used to retrieve module information
1270 # @param Arch The target architecture
1271 # @param Platform (not used for DecBuildData)
1272 # @param Macros Macros used for replacement in DSC file
1274 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1275 self
.MetaFile
= File
1276 self
._PackageDir
= File
.Dir
1277 self
._RawData
= RawData
1278 self
._Bdb
= BuildDataBase
1280 self
._Target
= Target
1281 self
._Toolchain
= Toolchain
1285 def __setitem__(self
, key
, value
):
1286 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1289 def __getitem__(self
, key
):
1290 return self
.__dict
__[self
._PROPERTY
_[key
]]
1292 ## "in" test support
1293 def __contains__(self
, key
):
1294 return key
in self
._PROPERTY
_
1296 ## Set all internal used members of DecBuildData to None
1299 self
._PackageName
= None
1301 self
._Version
= None
1302 self
._PkgUniFile
= None
1303 self
._Protocols
= None
1306 self
._Includes
= None
1307 self
._LibraryClasses
= None
1309 self
.__Macros
= None
1311 ## Get current effective macros
1312 def _GetMacros(self
):
1313 if self
.__Macros
== None:
1315 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1316 return self
.__Macros
1324 # Changing the default ARCH to another may affect all other information
1325 # because all information in a platform may be ARCH-related. That's
1326 # why we need to clear all internal used members, in order to cause all
1327 # information to be re-retrieved.
1329 # @param Value The value of ARCH
1331 def _SetArch(self
, Value
):
1332 if self
._Arch
== Value
:
1337 ## Retrieve all information in [Defines] section
1339 # (Retriving all [Defines] information in one-shot is just to save time.)
1341 def _GetHeaderInfo(self
):
1342 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1343 for Record
in RecordList
:
1346 self
[Name
] = Record
[2]
1347 self
._Header
= 'DUMMY'
1349 ## Retrieve package name
1350 def _GetPackageName(self
):
1351 if self
._PackageName
== None:
1352 if self
._Header
== None:
1353 self
._GetHeaderInfo
()
1354 if self
._PackageName
== None:
1355 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1356 return self
._PackageName
1358 ## Retrieve file guid
1359 def _GetFileGuid(self
):
1360 if self
._Guid
== None:
1361 if self
._Header
== None:
1362 self
._GetHeaderInfo
()
1363 if self
._Guid
== None:
1364 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1367 ## Retrieve package version
1368 def _GetVersion(self
):
1369 if self
._Version
== None:
1370 if self
._Header
== None:
1371 self
._GetHeaderInfo
()
1372 if self
._Version
== None:
1374 return self
._Version
1376 ## Retrieve protocol definitions (name/value pairs)
1377 def _GetProtocol(self
):
1378 if self
._Protocols
== None:
1380 # tdict is a special kind of dict, used for selecting correct
1381 # protocol defition for given ARCH
1383 ProtocolDict
= tdict(True)
1385 # find out all protocol definitions for specific and 'common' arch
1386 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1387 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1388 if Name
not in NameList
:
1389 NameList
.append(Name
)
1390 ProtocolDict
[Arch
, Name
] = Guid
1391 # use sdict to keep the order
1392 self
._Protocols
= sdict()
1393 for Name
in NameList
:
1395 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1396 # will automatically turn to 'common' ARCH for trying
1398 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1399 return self
._Protocols
1401 ## Retrieve PPI definitions (name/value pairs)
1403 if self
._Ppis
== None:
1405 # tdict is a special kind of dict, used for selecting correct
1406 # PPI defition for given ARCH
1408 PpiDict
= tdict(True)
1410 # find out all PPI definitions for specific arch and 'common' arch
1411 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1412 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1413 if Name
not in NameList
:
1414 NameList
.append(Name
)
1415 PpiDict
[Arch
, Name
] = Guid
1416 # use sdict to keep the order
1417 self
._Ppis
= sdict()
1418 for Name
in NameList
:
1420 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1421 # will automatically turn to 'common' ARCH for trying
1423 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1426 ## Retrieve GUID definitions (name/value pairs)
1428 if self
._Guids
== None:
1430 # tdict is a special kind of dict, used for selecting correct
1431 # GUID defition for given ARCH
1433 GuidDict
= tdict(True)
1435 # find out all protocol definitions for specific and 'common' arch
1436 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1437 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1438 if Name
not in NameList
:
1439 NameList
.append(Name
)
1440 GuidDict
[Arch
, Name
] = Guid
1441 # use sdict to keep the order
1442 self
._Guids
= sdict()
1443 for Name
in NameList
:
1445 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1446 # will automatically turn to 'common' ARCH for trying
1448 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1451 ## Retrieve public include paths declared in this package
1452 def _GetInclude(self
):
1453 if self
._Includes
== None:
1455 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1456 Macros
= self
._Macros
1457 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1458 for Record
in RecordList
:
1459 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1462 ErrorCode
, ErrorInfo
= File
.Validate()
1464 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1466 # avoid duplicate include path
1467 if File
not in self
._Includes
:
1468 self
._Includes
.append(File
)
1469 return self
._Includes
1471 ## Retrieve library class declarations (not used in build at present)
1472 def _GetLibraryClass(self
):
1473 if self
._LibraryClasses
== None:
1475 # tdict is a special kind of dict, used for selecting correct
1476 # library class declaration for given ARCH
1478 LibraryClassDict
= tdict(True)
1479 LibraryClassSet
= set()
1480 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1481 Macros
= self
._Macros
1482 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1483 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1484 # check the file validation
1485 ErrorCode
, ErrorInfo
= File
.Validate()
1487 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1488 LibraryClassSet
.add(LibraryClass
)
1489 LibraryClassDict
[Arch
, LibraryClass
] = File
1490 self
._LibraryClasses
= sdict()
1491 for LibraryClass
in LibraryClassSet
:
1492 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1493 return self
._LibraryClasses
1495 ## Retrieve PCD declarations
1497 if self
._Pcds
== None:
1498 self
._Pcds
= sdict()
1499 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1500 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1501 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1502 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1503 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1506 ## Retrieve PCD declarations for given type
1507 def _GetPcd(self
, Type
):
1510 # tdict is a special kind of dict, used for selecting correct
1511 # PCD declaration for given ARCH
1513 PcdDict
= tdict(True, 3)
1514 # for summarizing PCD
1516 # find out all PCDs of the 'type'
1517 RecordList
= self
._RawData
[Type
, self
._Arch
]
1518 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1519 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1520 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1522 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1524 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1525 # will automatically turn to 'common' ARCH and try again
1527 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1531 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1533 validateranges
, validlists
, expressions
= self
._RawData
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
1534 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1537 self
._PCD
_TYPE
_STRING
_[Type
],
1545 list(validateranges
),
1552 _Macros
= property(_GetMacros
)
1553 Arch
= property(_GetArch
, _SetArch
)
1554 PackageName
= property(_GetPackageName
)
1555 Guid
= property(_GetFileGuid
)
1556 Version
= property(_GetVersion
)
1558 Protocols
= property(_GetProtocol
)
1559 Ppis
= property(_GetPpi
)
1560 Guids
= property(_GetGuid
)
1561 Includes
= property(_GetInclude
)
1562 LibraryClasses
= property(_GetLibraryClass
)
1563 Pcds
= property(_GetPcds
)
1565 ## Module build information from INF file
1567 # This class is used to retrieve information stored in database and convert them
1568 # into ModuleBuildClassObject form for easier use for AutoGen.
1570 class InfBuildData(ModuleBuildClassObject
):
1571 # dict used to convert PCD type in database to string used by build tool
1572 _PCD_TYPE_STRING_
= {
1573 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1574 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1575 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1576 MODEL_PCD_DYNAMIC
: "Dynamic",
1577 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1578 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1579 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1580 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1581 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1582 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1583 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1586 # dict used to convert part of [Defines] to members of InfBuildData directly
1591 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1592 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1593 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1597 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1598 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1599 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1600 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1601 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1602 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1603 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1604 TAB_INF_DEFINES_VERSION
: "_Version",
1605 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1606 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1608 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1611 # dict used to convert Component type to Module type
1614 "SECURITY_CORE" : "SEC",
1615 "PEI_CORE" : "PEI_CORE",
1616 "COMBINED_PEIM_DRIVER" : "PEIM",
1617 "PIC_PEIM" : "PEIM",
1618 "RELOCATABLE_PEIM" : "PEIM",
1619 "PE32_PEIM" : "PEIM",
1620 "BS_DRIVER" : "DXE_DRIVER",
1621 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1622 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1623 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1624 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1625 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1626 # "BS_DRIVER" : "UEFI_DRIVER",
1627 "APPLICATION" : "UEFI_APPLICATION",
1631 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1632 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1633 # dict used to convert old tool name used in [nmake] section to new ones
1641 ## Constructor of DscBuildData
1643 # Initialize object of DscBuildData
1645 # @param FilePath The path of platform description file
1646 # @param RawData The raw data of DSC file
1647 # @param BuildDataBase Database used to retrieve module/package information
1648 # @param Arch The target architecture
1649 # @param Platform The name of platform employing this module
1650 # @param Macros Macros used for replacement in DSC file
1652 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1653 self
.MetaFile
= FilePath
1654 self
._ModuleDir
= FilePath
.Dir
1655 self
._RawData
= RawData
1656 self
._Bdb
= BuildDatabase
1658 self
._Target
= Target
1659 self
._Toolchain
= Toolchain
1660 self
._Platform
= 'COMMON'
1661 self
._SourceOverridePath
= None
1662 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1663 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1667 def __setitem__(self
, key
, value
):
1668 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1671 def __getitem__(self
, key
):
1672 return self
.__dict
__[self
._PROPERTY
_[key
]]
1674 ## "in" test support
1675 def __contains__(self
, key
):
1676 return key
in self
._PROPERTY
_
1678 ## Set all internal used members of InfBuildData to None
1680 self
._HeaderComments
= None
1681 self
._TailComments
= None
1682 self
._Header
_ = None
1683 self
._AutoGenVersion
= None
1684 self
._BaseName
= None
1685 self
._DxsFile
= None
1686 self
._ModuleType
= None
1687 self
._ComponentType
= None
1688 self
._BuildType
= None
1690 self
._Version
= None
1691 self
._PcdIsDriver
= None
1692 self
._BinaryModule
= None
1694 self
._MakefileName
= None
1695 self
._CustomMakefile
= None
1696 self
._Specification
= None
1697 self
._LibraryClass
= None
1698 self
._ModuleEntryPointList
= None
1699 self
._ModuleUnloadImageList
= None
1700 self
._ConstructorList
= None
1701 self
._DestructorList
= None
1703 self
._Binaries
= None
1704 self
._Sources
= None
1705 self
._LibraryClasses
= None
1706 self
._Libraries
= None
1707 self
._Protocols
= None
1708 self
._ProtocolComments
= None
1710 self
._PpiComments
= None
1712 self
._GuidsUsedByPcd
= sdict()
1713 self
._GuidComments
= None
1714 self
._Includes
= None
1715 self
._Packages
= None
1717 self
._PcdComments
= None
1718 self
._BuildOptions
= None
1720 self
._DepexExpression
= None
1721 self
.__Macros
= None
1723 ## Get current effective macros
1724 def _GetMacros(self
):
1725 if self
.__Macros
== None:
1727 # EDK_GLOBAL defined macros can be applied to EDK module
1728 if self
.AutoGenVersion
< 0x00010005:
1729 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1730 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1731 return self
.__Macros
1739 # Changing the default ARCH to another may affect all other information
1740 # because all information in a platform may be ARCH-related. That's
1741 # why we need to clear all internal used members, in order to cause all
1742 # information to be re-retrieved.
1744 # @param Value The value of ARCH
1746 def _SetArch(self
, Value
):
1747 if self
._Arch
== Value
:
1752 ## Return the name of platform employing this module
1753 def _GetPlatform(self
):
1754 return self
._Platform
1756 ## Change the name of platform employing this module
1758 # Changing the default name of platform to another may affect some information
1759 # because they may be PLATFORM-related. That's why we need to clear all internal
1760 # used members, in order to cause all information to be re-retrieved.
1762 def _SetPlatform(self
, Value
):
1763 if self
._Platform
== Value
:
1765 self
._Platform
= Value
1767 def _GetHeaderComments(self
):
1768 if not self
._HeaderComments
:
1769 self
._HeaderComments
= []
1770 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1771 for Record
in RecordList
:
1772 self
._HeaderComments
.append(Record
[0])
1773 return self
._HeaderComments
1774 def _GetTailComments(self
):
1775 if not self
._TailComments
:
1776 self
._TailComments
= []
1777 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1778 for Record
in RecordList
:
1779 self
._TailComments
.append(Record
[0])
1780 return self
._TailComments
1781 ## Retrieve all information in [Defines] section
1783 # (Retriving all [Defines] information in one-shot is just to save time.)
1785 def _GetHeaderInfo(self
):
1786 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1787 for Record
in RecordList
:
1788 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1789 # items defined _PROPERTY_ don't need additional processing
1792 if self
._Defs
== None:
1793 self
._Defs
= sdict()
1794 self
._Defs
[Name
] = Value
1795 # some special items in [Defines] section need special treatment
1796 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1797 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1798 Name
= 'UEFI_SPECIFICATION_VERSION'
1799 if self
._Specification
== None:
1800 self
._Specification
= sdict()
1801 self
._Specification
[Name
] = GetHexVerValue(Value
)
1802 if self
._Specification
[Name
] == None:
1803 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1804 "'%s' format is not supported for %s" % (Value
, Name
),
1805 File
=self
.MetaFile
, Line
=Record
[-1])
1806 elif Name
== 'LIBRARY_CLASS':
1807 if self
._LibraryClass
== None:
1808 self
._LibraryClass
= []
1809 ValueList
= GetSplitValueList(Value
)
1810 LibraryClass
= ValueList
[0]
1811 if len(ValueList
) > 1:
1812 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1814 SupModuleList
= SUP_MODULE_LIST
1815 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1816 elif Name
== 'ENTRY_POINT':
1817 if self
._ModuleEntryPointList
== None:
1818 self
._ModuleEntryPointList
= []
1819 self
._ModuleEntryPointList
.append(Value
)
1820 elif Name
== 'UNLOAD_IMAGE':
1821 if self
._ModuleUnloadImageList
== None:
1822 self
._ModuleUnloadImageList
= []
1825 self
._ModuleUnloadImageList
.append(Value
)
1826 elif Name
== 'CONSTRUCTOR':
1827 if self
._ConstructorList
== None:
1828 self
._ConstructorList
= []
1831 self
._ConstructorList
.append(Value
)
1832 elif Name
== 'DESTRUCTOR':
1833 if self
._DestructorList
== None:
1834 self
._DestructorList
= []
1837 self
._DestructorList
.append(Value
)
1838 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1839 TokenList
= GetSplitValueList(Value
)
1840 if self
._CustomMakefile
== None:
1841 self
._CustomMakefile
= {}
1842 if len(TokenList
) < 2:
1843 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1844 self
._CustomMakefile
['GCC'] = TokenList
[0]
1846 if TokenList
[0] not in ['MSFT', 'GCC']:
1847 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1848 "No supported family [%s]" % TokenList
[0],
1849 File
=self
.MetaFile
, Line
=Record
[-1])
1850 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1852 if self
._Defs
== None:
1853 self
._Defs
= sdict()
1854 self
._Defs
[Name
] = Value
1857 # Retrieve information in sections specific to Edk.x modules
1859 if self
.AutoGenVersion
>= 0x00010005:
1860 if not self
._ModuleType
:
1861 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1862 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1863 if self
._ModuleType
not in SUP_MODULE_LIST
:
1864 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1865 for Record
in RecordList
:
1867 if Name
== "MODULE_TYPE":
1870 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1871 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1872 File
=self
.MetaFile
, Line
=LineNo
)
1873 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1874 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1875 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
)
1876 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1877 and 'PCI_CLASS_CODE' in self
._Defs
:
1878 self
._BuildType
= 'UEFI_OPTIONROM'
1879 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1880 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1881 self
._BuildType
= 'UEFI_HII'
1883 self
._BuildType
= self
._ModuleType
.upper()
1886 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1887 # check the file validation
1888 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1890 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1891 File
=self
.MetaFile
, Line
=LineNo
)
1892 if self
.Sources
== None:
1894 self
._Sources
.append(File
)
1896 if not self
._ComponentType
:
1897 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1898 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1899 self
._BuildType
= self
._ComponentType
.upper()
1900 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1901 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1902 if self
._ComponentType
== 'LIBRARY':
1903 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1904 # make use some [nmake] section macros
1905 Macros
= self
._Macros
1906 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1907 Macros
['PROCESSOR'] = self
._Arch
1908 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1909 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1910 Value
= ReplaceMacro(Value
, Macros
, True)
1911 if Name
== "IMAGE_ENTRY_POINT":
1912 if self
._ModuleEntryPointList
== None:
1913 self
._ModuleEntryPointList
= []
1914 self
._ModuleEntryPointList
.append(Value
)
1915 elif Name
== "DPX_SOURCE":
1916 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1917 # check the file validation
1918 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1920 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1921 File
=self
.MetaFile
, Line
=LineNo
)
1922 if self
.Sources
== None:
1924 self
._Sources
.append(File
)
1926 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1927 if len(ToolList
) == 0 or len(ToolList
) != 1:
1929 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1930 # File=self.MetaFile, Line=LineNo)
1932 if self
._BuildOptions
== None:
1933 self
._BuildOptions
= sdict()
1935 if ToolList
[0] in self
._TOOL
_CODE
_:
1936 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1939 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1940 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1941 #ignore not replaced macros in value
1942 ValueList
= GetSplitList(' ' + Value
, '/D')
1943 Dummy
= ValueList
[0]
1944 for Index
in range(1, len(ValueList
)):
1945 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1947 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1948 Value
= Dummy
.strip()
1949 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1950 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1952 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1953 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1954 # set _Header to non-None in order to avoid database re-querying
1955 self
._Header
_ = 'DUMMY'
1957 ## Retrieve file version
1958 def _GetInfVersion(self
):
1959 if self
._AutoGenVersion
== None:
1960 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1961 for Record
in RecordList
:
1962 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1963 self
._AutoGenVersion
= int(Record
[2], 0)
1965 if self
._AutoGenVersion
== None:
1966 self
._AutoGenVersion
= 0x00010000
1967 return self
._AutoGenVersion
1969 ## Retrieve BASE_NAME
1970 def _GetBaseName(self
):
1971 if self
._BaseName
== None:
1972 if self
._Header
_ == None:
1973 self
._GetHeaderInfo
()
1974 if self
._BaseName
== None:
1975 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1976 return self
._BaseName
1979 def _GetDxsFile(self
):
1980 if self
._DxsFile
== None:
1981 if self
._Header
_ == None:
1982 self
._GetHeaderInfo
()
1983 if self
._DxsFile
== None:
1985 return self
._DxsFile
1987 ## Retrieve MODULE_TYPE
1988 def _GetModuleType(self
):
1989 if self
._ModuleType
== None:
1990 if self
._Header
_ == None:
1991 self
._GetHeaderInfo
()
1992 if self
._ModuleType
== None:
1993 self
._ModuleType
= 'BASE'
1994 if self
._ModuleType
not in SUP_MODULE_LIST
:
1995 self
._ModuleType
= "USER_DEFINED"
1996 return self
._ModuleType
1998 ## Retrieve COMPONENT_TYPE
1999 def _GetComponentType(self
):
2000 if self
._ComponentType
== None:
2001 if self
._Header
_ == None:
2002 self
._GetHeaderInfo
()
2003 if self
._ComponentType
== None:
2004 self
._ComponentType
= 'USER_DEFINED'
2005 return self
._ComponentType
2007 ## Retrieve "BUILD_TYPE"
2008 def _GetBuildType(self
):
2009 if self
._BuildType
== None:
2010 if self
._Header
_ == None:
2011 self
._GetHeaderInfo
()
2012 if not self
._BuildType
:
2013 self
._BuildType
= "BASE"
2014 return self
._BuildType
2016 ## Retrieve file guid
2017 def _GetFileGuid(self
):
2018 if self
._Guid
== None:
2019 if self
._Header
_ == None:
2020 self
._GetHeaderInfo
()
2021 if self
._Guid
== None:
2022 self
._Guid
= '00000000-0000-0000-0000-000000000000'
2025 ## Retrieve module version
2026 def _GetVersion(self
):
2027 if self
._Version
== None:
2028 if self
._Header
_ == None:
2029 self
._GetHeaderInfo
()
2030 if self
._Version
== None:
2031 self
._Version
= '0.0'
2032 return self
._Version
2034 ## Retrieve PCD_IS_DRIVER
2035 def _GetPcdIsDriver(self
):
2036 if self
._PcdIsDriver
== None:
2037 if self
._Header
_ == None:
2038 self
._GetHeaderInfo
()
2039 if self
._PcdIsDriver
== None:
2040 self
._PcdIsDriver
= ''
2041 return self
._PcdIsDriver
2044 def _GetShadow(self
):
2045 if self
._Shadow
== None:
2046 if self
._Header
_ == None:
2047 self
._GetHeaderInfo
()
2048 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
2051 self
._Shadow
= False
2054 ## Retrieve CUSTOM_MAKEFILE
2055 def _GetMakefile(self
):
2056 if self
._CustomMakefile
== None:
2057 if self
._Header
_ == None:
2058 self
._GetHeaderInfo
()
2059 if self
._CustomMakefile
== None:
2060 self
._CustomMakefile
= {}
2061 return self
._CustomMakefile
2063 ## Retrieve EFI_SPECIFICATION_VERSION
2065 if self
._Specification
== None:
2066 if self
._Header
_ == None:
2067 self
._GetHeaderInfo
()
2068 if self
._Specification
== None:
2069 self
._Specification
= {}
2070 return self
._Specification
2072 ## Retrieve LIBRARY_CLASS
2073 def _GetLibraryClass(self
):
2074 if self
._LibraryClass
== None:
2075 if self
._Header
_ == None:
2076 self
._GetHeaderInfo
()
2077 if self
._LibraryClass
== None:
2078 self
._LibraryClass
= []
2079 return self
._LibraryClass
2081 ## Retrieve ENTRY_POINT
2082 def _GetEntryPoint(self
):
2083 if self
._ModuleEntryPointList
== None:
2084 if self
._Header
_ == None:
2085 self
._GetHeaderInfo
()
2086 if self
._ModuleEntryPointList
== None:
2087 self
._ModuleEntryPointList
= []
2088 return self
._ModuleEntryPointList
2090 ## Retrieve UNLOAD_IMAGE
2091 def _GetUnloadImage(self
):
2092 if self
._ModuleUnloadImageList
== None:
2093 if self
._Header
_ == None:
2094 self
._GetHeaderInfo
()
2095 if self
._ModuleUnloadImageList
== None:
2096 self
._ModuleUnloadImageList
= []
2097 return self
._ModuleUnloadImageList
2099 ## Retrieve CONSTRUCTOR
2100 def _GetConstructor(self
):
2101 if self
._ConstructorList
== None:
2102 if self
._Header
_ == None:
2103 self
._GetHeaderInfo
()
2104 if self
._ConstructorList
== None:
2105 self
._ConstructorList
= []
2106 return self
._ConstructorList
2108 ## Retrieve DESTRUCTOR
2109 def _GetDestructor(self
):
2110 if self
._DestructorList
== None:
2111 if self
._Header
_ == None:
2112 self
._GetHeaderInfo
()
2113 if self
._DestructorList
== None:
2114 self
._DestructorList
= []
2115 return self
._DestructorList
2117 ## Retrieve definies other than above ones
2118 def _GetDefines(self
):
2119 if self
._Defs
== None:
2120 if self
._Header
_ == None:
2121 self
._GetHeaderInfo
()
2122 if self
._Defs
== None:
2123 self
._Defs
= sdict()
2126 ## Retrieve binary files
2127 def _GetBinaries(self
):
2128 if self
._Binaries
== None:
2130 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2131 Macros
= self
._Macros
2132 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2133 Macros
['PROCESSOR'] = self
._Arch
2134 for Record
in RecordList
:
2135 FileType
= Record
[0]
2140 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2142 Target
= TokenList
[0]
2143 if len(TokenList
) > 1:
2144 FeatureFlag
= Record
[1:]
2146 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2147 # check the file validation
2148 ErrorCode
, ErrorInfo
= File
.Validate()
2150 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2151 self
._Binaries
.append(File
)
2152 return self
._Binaries
2154 ## Retrieve binary files with error check.
2155 def _GetBinaryFiles(self
):
2156 Binaries
= self
._GetBinaries
()
2157 if GlobalData
.gIgnoreSource
and Binaries
== []:
2158 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2159 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2162 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2163 def _IsSupportedArch(self
):
2164 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2168 ## Retrieve source files
2169 def _GetSourceFiles(self
):
2170 #Ignore all source files in a binary build mode
2171 if GlobalData
.gIgnoreSource
:
2173 return self
._Sources
2175 if self
._Sources
== None:
2177 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2178 Macros
= self
._Macros
2179 for Record
in RecordList
:
2181 ToolChainFamily
= Record
[1]
2183 ToolCode
= Record
[3]
2184 FeatureFlag
= Record
[4]
2185 if self
.AutoGenVersion
< 0x00010005:
2186 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2187 Macros
['PROCESSOR'] = self
._Arch
2188 # old module source files (Edk)
2189 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
2190 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2191 # check the file validation
2192 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2194 if File
.Ext
.lower() == '.h':
2195 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2196 File
=self
.MetaFile
, Line
=LineNo
)
2199 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2201 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2202 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2203 # check the file validation
2204 ErrorCode
, ErrorInfo
= File
.Validate()
2206 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2208 self
._Sources
.append(File
)
2209 return self
._Sources
2211 ## Retrieve library classes employed by this module
2212 def _GetLibraryClassUses(self
):
2213 if self
._LibraryClasses
== None:
2214 self
._LibraryClasses
= sdict()
2215 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2216 for Record
in RecordList
:
2218 Instance
= Record
[1]
2220 Instance
= NormPath(Instance
, self
._Macros
)
2221 self
._LibraryClasses
[Lib
] = Instance
2222 return self
._LibraryClasses
2224 ## Retrieve library names (for Edk.x style of modules)
2225 def _GetLibraryNames(self
):
2226 if self
._Libraries
== None:
2227 self
._Libraries
= []
2228 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2229 for Record
in RecordList
:
2230 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2231 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2232 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2233 if LibraryName
not in self
._Libraries
:
2234 self
._Libraries
.append(LibraryName
)
2235 return self
._Libraries
2237 def _GetProtocolComments(self
):
2238 self
._GetProtocols
()
2239 return self
._ProtocolComments
2240 ## Retrieve protocols consumed/produced by this module
2241 def _GetProtocols(self
):
2242 if self
._Protocols
== None:
2243 self
._Protocols
= sdict()
2244 self
._ProtocolComments
= sdict()
2245 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2246 for Record
in RecordList
:
2248 Value
= ProtocolValue(CName
, self
.Packages
)
2250 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2251 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2252 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2253 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2254 self
._Protocols
[CName
] = Value
2255 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2257 for CmtRec
in CommentRecords
:
2258 Comments
.append(CmtRec
[0])
2259 self
._ProtocolComments
[CName
] = Comments
2260 return self
._Protocols
2262 def _GetPpiComments(self
):
2264 return self
._PpiComments
2265 ## Retrieve PPIs consumed/produced by this module
2267 if self
._Ppis
== None:
2268 self
._Ppis
= sdict()
2269 self
._PpiComments
= sdict()
2270 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2271 for Record
in RecordList
:
2273 Value
= PpiValue(CName
, self
.Packages
)
2275 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2276 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2277 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2278 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2279 self
._Ppis
[CName
] = Value
2280 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2282 for CmtRec
in CommentRecords
:
2283 Comments
.append(CmtRec
[0])
2284 self
._PpiComments
[CName
] = Comments
2287 def _GetGuidComments(self
):
2289 return self
._GuidComments
2290 ## Retrieve GUIDs consumed/produced by this module
2291 def _GetGuids(self
):
2292 if self
._Guids
== None:
2293 self
._Guids
= sdict()
2294 self
._GuidComments
= sdict()
2295 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2296 for Record
in RecordList
:
2298 Value
= GuidValue(CName
, self
.Packages
)
2300 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2301 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2302 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2303 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2304 self
._Guids
[CName
] = Value
2305 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2307 for CmtRec
in CommentRecords
:
2308 Comments
.append(CmtRec
[0])
2309 self
._GuidComments
[CName
] = Comments
2312 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2313 def _GetIncludes(self
):
2314 if self
._Includes
== None:
2316 if self
._SourceOverridePath
:
2317 self
._Includes
.append(self
._SourceOverridePath
)
2319 Macros
= self
._Macros
2320 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2321 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2323 Macros
['PROCESSOR'] = self
._Arch
2324 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2325 for Record
in RecordList
:
2326 if Record
[0].find('EDK_SOURCE') > -1:
2327 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2328 File
= NormPath(Record
[0], self
._Macros
)
2330 File
= os
.path
.join(self
._ModuleDir
, File
)
2332 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2333 File
= RealPath(os
.path
.normpath(File
))
2335 self
._Includes
.append(File
)
2337 #TRICK: let compiler to choose correct header file
2338 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2339 File
= NormPath(Record
[0], self
._Macros
)
2341 File
= os
.path
.join(self
._ModuleDir
, File
)
2343 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2344 File
= RealPath(os
.path
.normpath(File
))
2346 self
._Includes
.append(File
)
2348 File
= NormPath(Record
[0], Macros
)
2350 File
= os
.path
.join(self
._ModuleDir
, File
)
2352 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2353 File
= RealPath(os
.path
.normpath(File
))
2355 self
._Includes
.append(File
)
2356 return self
._Includes
2358 ## Retrieve packages this module depends on
2359 def _GetPackages(self
):
2360 if self
._Packages
== None:
2362 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2363 Macros
= self
._Macros
2364 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2365 for Record
in RecordList
:
2366 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2368 # check the file validation
2369 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2371 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2372 # parse this package now. we need it to get protocol/ppi/guid value
2373 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2374 self
._Packages
.append(Package
)
2375 return self
._Packages
2377 ## Retrieve PCD comments
2378 def _GetPcdComments(self
):
2380 return self
._PcdComments
2381 ## Retrieve PCDs used in this module
2383 if self
._Pcds
== None:
2384 self
._Pcds
= sdict()
2385 self
._PcdComments
= sdict()
2386 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2387 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2388 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2389 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2390 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2393 ## Retrieve build options specific to this module
2394 def _GetBuildOptions(self
):
2395 if self
._BuildOptions
== None:
2396 self
._BuildOptions
= sdict()
2397 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2398 for Record
in RecordList
:
2399 ToolChainFamily
= Record
[0]
2400 ToolChain
= Record
[1]
2402 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2403 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2405 # concatenate the option string if they're for the same tool
2406 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2407 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2408 return self
._BuildOptions
2410 ## Retrieve dependency expression
2411 def _GetDepex(self
):
2412 if self
._Depex
== None:
2413 self
._Depex
= tdict(False, 2)
2414 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2416 # If the module has only Binaries and no Sources, then ignore [Depex]
2417 if self
.Sources
== None or self
.Sources
== []:
2418 if self
.Binaries
!= None and self
.Binaries
!= []:
2421 # PEIM and DXE drivers must have a valid [Depex] section
2422 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2423 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2424 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2425 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2426 % self
.ModuleType
, File
=self
.MetaFile
)
2428 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2429 for Record
in RecordList
:
2430 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2431 EdkLogger
.error('build', FORMAT_INVALID
,
2432 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2436 for Record
in RecordList
:
2437 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2439 ModuleType
= Record
[4]
2440 TokenList
= DepexStr
.split()
2441 if (Arch
, ModuleType
) not in Depex
:
2442 Depex
[Arch
, ModuleType
] = []
2443 DepexList
= Depex
[Arch
, ModuleType
]
2444 for Token
in TokenList
:
2445 if Token
in DEPEX_SUPPORTED_OPCODE
:
2446 DepexList
.append(Token
)
2447 elif Token
.endswith(".inf"): # module file name
2448 ModuleFile
= os
.path
.normpath(Token
)
2449 Module
= self
.BuildDatabase
[ModuleFile
]
2451 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2452 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2453 DepexList
.append(Module
.Guid
)
2455 # get the GUID value now
2456 Value
= ProtocolValue(Token
, self
.Packages
)
2458 Value
= PpiValue(Token
, self
.Packages
)
2460 Value
= GuidValue(Token
, self
.Packages
)
2462 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2463 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2464 "Value of [%s] is not found in" % Token
,
2465 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2466 DepexList
.append(Value
)
2467 for Arch
, ModuleType
in Depex
:
2468 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2471 ## Retrieve depedency expression
2472 def _GetDepexExpression(self
):
2473 if self
._DepexExpression
== None:
2474 self
._DepexExpression
= tdict(False, 2)
2475 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2476 DepexExpression
= sdict()
2477 for Record
in RecordList
:
2478 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2480 ModuleType
= Record
[4]
2481 TokenList
= DepexStr
.split()
2482 if (Arch
, ModuleType
) not in DepexExpression
:
2483 DepexExpression
[Arch
, ModuleType
] = ''
2484 for Token
in TokenList
:
2485 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2486 for Arch
, ModuleType
in DepexExpression
:
2487 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2488 return self
._DepexExpression
2490 def GetGuidsUsedByPcd(self
):
2491 return self
._GuidsUsedByPcd
2492 ## Retrieve PCD for given type
2493 def _GetPcd(self
, Type
):
2495 PcdDict
= tdict(True, 4)
2497 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2498 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2499 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2500 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2501 # get the guid value
2502 if TokenSpaceGuid
not in self
.Guids
:
2503 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2505 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2506 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2507 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2508 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2509 self
.Guids
[TokenSpaceGuid
] = Value
2510 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2511 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2513 for CmtRec
in CommentRecords
:
2514 Comments
.append(CmtRec
[0])
2515 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2517 # resolve PCD type, value, datum info, etc. by getting its definition from package
2518 for PcdCName
, TokenSpaceGuid
in PcdList
:
2519 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2522 ValueList
= AnalyzePcdData(Setting
)
2523 DefaultValue
= ValueList
[0]
2524 Pcd
= PcdClassObject(
2534 self
.Guids
[TokenSpaceGuid
]
2536 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2537 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2538 Pcd
.Offset
= ValueList
[1]
2540 # get necessary info from package declaring this PCD
2541 for Package
in self
.Packages
:
2543 # 'dynamic' in INF means its type is determined by platform;
2544 # if platform doesn't give its type, use 'lowest' one in the
2545 # following order, if any
2547 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2549 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2550 if Type
== MODEL_PCD_DYNAMIC
:
2552 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2553 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2559 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2560 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2562 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2565 # Check whether the token value exist or not.
2567 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2571 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2572 File
=self
.MetaFile
, Line
=LineNo
,
2576 # Check hexadecimal token value length and format.
2578 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2579 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2580 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2584 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2585 File
=self
.MetaFile
, Line
=LineNo
,
2590 # Check decimal token value length and format.
2594 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2595 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2599 "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
)),
2600 File
=self
.MetaFile
, Line
=LineNo
,
2607 "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
)),
2608 File
=self
.MetaFile
, Line
=LineNo
,
2612 Pcd
.DatumType
= PcdInPackage
.DatumType
2613 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2614 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2615 if Pcd
.DefaultValue
in [None, '']:
2616 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2622 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2623 File
=self
.MetaFile
, Line
=LineNo
,
2624 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2626 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2630 ## check whether current module is binary module
2631 def _IsBinaryModule(self
):
2632 if self
.Binaries
and not self
.Sources
:
2634 elif GlobalData
.gIgnoreSource
:
2639 _Macros
= property(_GetMacros
)
2640 Arch
= property(_GetArch
, _SetArch
)
2641 Platform
= property(_GetPlatform
, _SetPlatform
)
2643 HeaderComments
= property(_GetHeaderComments
)
2644 TailComments
= property(_GetTailComments
)
2645 AutoGenVersion
= property(_GetInfVersion
)
2646 BaseName
= property(_GetBaseName
)
2647 ModuleType
= property(_GetModuleType
)
2648 ComponentType
= property(_GetComponentType
)
2649 BuildType
= property(_GetBuildType
)
2650 Guid
= property(_GetFileGuid
)
2651 Version
= property(_GetVersion
)
2652 PcdIsDriver
= property(_GetPcdIsDriver
)
2653 Shadow
= property(_GetShadow
)
2654 CustomMakefile
= property(_GetMakefile
)
2655 Specification
= property(_GetSpec
)
2656 LibraryClass
= property(_GetLibraryClass
)
2657 ModuleEntryPointList
= property(_GetEntryPoint
)
2658 ModuleUnloadImageList
= property(_GetUnloadImage
)
2659 ConstructorList
= property(_GetConstructor
)
2660 DestructorList
= property(_GetDestructor
)
2661 Defines
= property(_GetDefines
)
2662 DxsFile
= property(_GetDxsFile
)
2664 Binaries
= property(_GetBinaryFiles
)
2665 Sources
= property(_GetSourceFiles
)
2666 LibraryClasses
= property(_GetLibraryClassUses
)
2667 Libraries
= property(_GetLibraryNames
)
2668 Protocols
= property(_GetProtocols
)
2669 ProtocolComments
= property(_GetProtocolComments
)
2670 Ppis
= property(_GetPpis
)
2671 PpiComments
= property(_GetPpiComments
)
2672 Guids
= property(_GetGuids
)
2673 GuidComments
= property(_GetGuidComments
)
2674 Includes
= property(_GetIncludes
)
2675 Packages
= property(_GetPackages
)
2676 Pcds
= property(_GetPcds
)
2677 PcdComments
= property(_GetPcdComments
)
2678 BuildOptions
= property(_GetBuildOptions
)
2679 Depex
= property(_GetDepex
)
2680 DepexExpression
= property(_GetDepexExpression
)
2681 IsBinaryModule
= property(_IsBinaryModule
)
2682 IsSupportedArch
= property(_IsSupportedArch
)
2686 # This class defined the build database for all modules, packages and platform.
2687 # It will call corresponding parser for the given file if it cannot find it in
2690 # @param DbPath Path of database file
2691 # @param GlobalMacros Global macros used for replacement during file parsing
2692 # @prarm RenewDb=False Create new database file if it's already there
2694 class WorkspaceDatabase(object):
2698 # internal class used for call corresponding file parser and caching the result
2699 # to avoid unnecessary re-parsing
2701 class BuildObjectFactory(object):
2704 ".inf" : MODEL_FILE_INF
,
2705 ".dec" : MODEL_FILE_DEC
,
2706 ".dsc" : MODEL_FILE_DSC
,
2711 MODEL_FILE_INF
: InfParser
,
2712 MODEL_FILE_DEC
: DecParser
,
2713 MODEL_FILE_DSC
: DscParser
,
2716 # convert to xxxBuildData object
2718 MODEL_FILE_INF
: InfBuildData
,
2719 MODEL_FILE_DEC
: DecBuildData
,
2720 MODEL_FILE_DSC
: DscBuildData
,
2723 _CACHE_
= {} # (FilePath, Arch) : <object>
2726 def __init__(self
, WorkspaceDb
):
2727 self
.WorkspaceDb
= WorkspaceDb
2729 # key = (FilePath, Arch=None)
2730 def __contains__(self
, Key
):
2736 return (FilePath
, Arch
) in self
._CACHE
_
2738 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2739 def __getitem__(self
, Key
):
2741 KeyLength
= len(Key
)
2755 # if it's generated before, just return the cached one
2756 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2757 if Key
in self
._CACHE
_:
2758 return self
._CACHE
_[Key
]
2762 if Ext
not in self
._FILE
_TYPE
_:
2764 FileType
= self
._FILE
_TYPE
_[Ext
]
2765 if FileType
not in self
._GENERATOR
_:
2768 # get the parser ready for this file
2769 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2772 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2774 # alwasy do post-process, in case of macros change
2775 MetaFile
.DoPostProcess()
2776 # object the build is based on
2777 BuildObject
= self
._GENERATOR
_[FileType
](
2785 self
._CACHE
_[Key
] = BuildObject
2788 # placeholder for file format conversion
2789 class TransformObjectFactory
:
2790 def __init__(self
, WorkspaceDb
):
2791 self
.WorkspaceDb
= WorkspaceDb
2793 # key = FilePath, Arch
2794 def __getitem__(self
, Key
):
2797 ## Constructor of WorkspaceDatabase
2799 # @param DbPath Path of database file
2800 # @param GlobalMacros Global macros used for replacement during file parsing
2801 # @prarm RenewDb=False Create new database file if it's already there
2803 def __init__(self
, DbPath
, RenewDb
=False):
2804 self
._DbClosedFlag
= False
2806 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2808 # don't create necessary path for db in memory
2809 if DbPath
!= ':memory:':
2810 DbDir
= os
.path
.split(DbPath
)[0]
2811 if not os
.path
.exists(DbDir
):
2814 # remove db file in case inconsistency between db and file in file system
2815 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2818 # create db with optimized parameters
2819 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2820 self
.Conn
.execute("PRAGMA synchronous=OFF")
2821 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2822 self
.Conn
.execute("PRAGMA count_changes=OFF")
2823 self
.Conn
.execute("PRAGMA cache_size=8192")
2824 #self.Conn.execute("PRAGMA page_size=8192")
2826 # to avoid non-ascii character conversion issue
2827 self
.Conn
.text_factory
= str
2828 self
.Cur
= self
.Conn
.cursor()
2830 # create table for internal uses
2831 self
.TblDataModel
= TableDataModel(self
.Cur
)
2832 self
.TblFile
= TableFile(self
.Cur
)
2833 self
.Platform
= None
2835 # conversion object for build or file format conversion purpose
2836 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2837 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2839 ## Check whether workspace database need to be renew.
2840 # The renew reason maybe:
2841 # 1) If user force to renew;
2842 # 2) If user do not force renew, and
2843 # a) If the time of last modified python source is newer than database file;
2844 # b) If the time of last modified frozen executable file is newer than database file;
2846 # @param force User force renew database
2847 # @param DbPath The absolute path of workspace database file
2849 # @return Bool value for whether need renew workspace databse
2851 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2852 # if database does not exist, we need do nothing
2853 if not os
.path
.exists(DbPath
): return False
2855 # if user force to renew database, then not check whether database is out of date
2856 if force
: return True
2859 # Check the time of last modified source file or build.exe
2860 # if is newer than time of database, then database need to be re-created.
2862 timeOfToolModified
= 0
2863 if hasattr(sys
, "frozen"):
2864 exePath
= os
.path
.abspath(sys
.executable
)
2865 timeOfToolModified
= os
.stat(exePath
).st_mtime
2867 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2868 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2869 if rootPath
== "" or rootPath
== None:
2870 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2871 determine whether database file is out of date!\n")
2873 # walk the root path of source or build's binary to get the time last modified.
2875 for root
, dirs
, files
in os
.walk (rootPath
):
2877 # bypass source control folder
2878 if dir.lower() in [".svn", "_svn", "cvs"]:
2882 ext
= os
.path
.splitext(file)[1]
2883 if ext
.lower() == ".py": # only check .py files
2884 fd
= os
.stat(os
.path
.join(root
, file))
2885 if timeOfToolModified
< fd
.st_mtime
:
2886 timeOfToolModified
= fd
.st_mtime
2887 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2888 EdkLogger
.verbose("\nWorkspace database is out of data!")
2893 ## Initialize build database
2894 def InitDatabase(self
):
2895 EdkLogger
.verbose("\nInitialize build database started ...")
2900 self
.TblDataModel
.Create(False)
2901 self
.TblFile
.Create(False)
2904 # Initialize table DataModel
2906 self
.TblDataModel
.InitTable()
2907 EdkLogger
.verbose("Initialize build database ... DONE!")
2911 # @param Table: The instance of the table to be queried
2913 def QueryTable(self
, Table
):
2919 ## Close entire database
2922 # Close the connection and cursor
2925 if not self
._DbClosedFlag
:
2929 self
._DbClosedFlag
= True
2931 ## Summarize all packages in the database
2932 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2933 self
.Platform
= Platform
2935 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2937 # Get Package related to Modules
2939 for Module
in Pa
.Modules
:
2940 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2941 for Package
in ModuleObj
.Packages
:
2942 if Package
not in PackageList
:
2943 PackageList
.append(Package
)
2945 # Get Packages related to Libraries
2947 for Lib
in Pa
.LibraryInstances
:
2948 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2949 for Package
in LibObj
.Packages
:
2950 if Package
not in PackageList
:
2951 PackageList
.append(Package
)
2955 ## Summarize all platforms in the database
2956 def _GetPlatformList(self
):
2958 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2960 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2963 if Platform
!= None:
2964 PlatformList
.append(Platform
)
2967 PlatformList
= property(_GetPlatformList
)
2971 # This acts like the main() function for the script, unless it is 'import'ed into another
2974 if __name__
== '__main__':