2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 import Common
.LongFilePathOs
as os
22 import Common
.EdkLogger
as EdkLogger
23 import Common
.GlobalData
as GlobalData
25 from Common
.String
import *
26 from Common
.DataType
import *
27 from Common
.Misc
import *
30 from CommonDataClass
.CommonClass
import SkuInfoClass
32 from MetaDataTable
import *
33 from MetaFileTable
import *
34 from MetaFileParser
import *
35 from BuildClassObject
import *
36 from WorkspaceCommon
import GetDeclaredPcd
37 from Common
.Misc
import AnalyzeDscPcd
38 from Common
.Misc
import ProcessDuplicatedInf
40 from Common
.Parsing
import IsValidWord
41 from Common
.VariableAttributes
import VariableAttributes
42 import Common
.GlobalData
as GlobalData
44 ## Platform build information from DSC file
46 # This class is used to retrieve information stored in database and convert them
47 # into PlatformBuildClassObject form for easier use for AutoGen.
49 class DscBuildData(PlatformBuildClassObject
):
50 # dict used to convert PCD type in database to string used by build tool
52 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
53 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
54 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
55 MODEL_PCD_DYNAMIC
: "Dynamic",
56 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
57 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
58 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
59 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
60 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
61 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
62 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
65 # dict used to convert part of [Defines] to members of DscBuildData directly
70 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
71 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
72 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
73 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
74 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
75 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
76 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
77 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
78 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
79 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
80 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
81 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
82 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
83 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
84 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
87 # used to compose dummy library class name for those forced library instances
88 _NullLibraryNumber
= 0
90 ## Constructor of DscBuildData
92 # Initialize object of DscBuildData
94 # @param FilePath The path of platform description file
95 # @param RawData The raw data of DSC file
96 # @param BuildDataBase Database used to retrieve module/package information
97 # @param Arch The target architecture
98 # @param Platform (not used for DscBuildData)
99 # @param Macros Macros used for replacement in DSC file
101 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
102 self
.MetaFile
= FilePath
103 self
._RawData
= RawData
104 self
._Bdb
= BuildDataBase
106 self
._Target
= Target
107 self
._Toolchain
= Toolchain
109 self
._HandleOverridePath
()
112 def __setitem__(self
, key
, value
):
113 self
.__dict
__[self
._PROPERTY
_[key
]] = value
116 def __getitem__(self
, key
):
117 return self
.__dict
__[self
._PROPERTY
_[key
]]
120 def __contains__(self
, key
):
121 return key
in self
._PROPERTY
_
123 ## Set all internal used members of DscBuildData to None
126 self
._PlatformName
= None
129 self
._DscSpecification
= None
130 self
._OutputDirectory
= None
131 self
._SupArchList
= None
132 self
._BuildTargets
= None
134 self
._SkuIdentifier
= None
135 self
._AvilableSkuIds
= None
136 self
._PcdInfoFlag
= None
137 self
._VarCheckFlag
= None
138 self
._FlashDefinition
= None
139 self
._BuildNumber
= None
140 self
._MakefileName
= None
141 self
._BsBaseAddress
= None
142 self
._RtBaseAddress
= None
145 self
._LibraryInstances
= None
146 self
._LibraryClasses
= None
149 self
._BuildOptions
= None
150 self
._ModuleTypeOptions
= None
151 self
._LoadFixAddress
= None
152 self
._RFCLanguages
= None
153 self
._ISOLanguages
= None
154 self
._VpdToolGuid
= None
158 ## handle Override Path of Module
159 def _HandleOverridePath(self
):
160 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
161 Macros
= self
._Macros
162 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
163 for Record
in RecordList
:
166 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
167 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
169 SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
171 # Check if the source override path exists
172 if not os
.path
.isdir(SourceOverridePath
):
173 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
175 #Add to GlobalData Variables
176 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
178 ## Get current effective macros
179 def _GetMacros(self
):
180 if self
.__Macros
== None:
182 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
183 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
184 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
193 # Changing the default ARCH to another may affect all other information
194 # because all information in a platform may be ARCH-related. That's
195 # why we need to clear all internal used members, in order to cause all
196 # information to be re-retrieved.
198 # @param Value The value of ARCH
200 def _SetArch(self
, Value
):
201 if self
._Arch
== Value
:
206 ## Retrieve all information in [Defines] section
208 # (Retriving all [Defines] information in one-shot is just to save time.)
210 def _GetHeaderInfo(self
):
211 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
212 for Record
in RecordList
:
214 # items defined _PROPERTY_ don't need additional processing
216 # some special items in [Defines] section need special treatment
217 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
218 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
219 if ' ' in self
._OutputDirectory
:
220 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
221 File
=self
.MetaFile
, Line
=Record
[-1],
222 ExtraData
=self
._OutputDirectory
)
223 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
224 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
225 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
227 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
229 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
230 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
231 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
232 self
._BuildTargets
= GetSplitValueList(Record
[2])
233 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
234 if self
._SkuName
== None:
235 self
._SkuName
= Record
[2]
236 self
._SkuIdentifier
= Record
[2]
237 self
._AvilableSkuIds
= Record
[2]
238 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
239 self
._PcdInfoFlag
= Record
[2]
240 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
241 self
._VarCheckFlag
= Record
[2]
242 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
244 self
._LoadFixAddress
= int (Record
[2], 0)
246 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
247 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
248 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
249 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
250 File
=self
.MetaFile
, Line
=Record
[-1])
251 LanguageCodes
= Record
[2][1:-1]
252 if not LanguageCodes
:
253 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
254 File
=self
.MetaFile
, Line
=Record
[-1])
255 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
256 # check whether there is empty entries in the list
257 if None in LanguageList
:
258 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
259 File
=self
.MetaFile
, Line
=Record
[-1])
260 self
._RFCLanguages
= LanguageList
261 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
262 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
263 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
264 File
=self
.MetaFile
, Line
=Record
[-1])
265 LanguageCodes
= Record
[2][1:-1]
266 if not LanguageCodes
:
267 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
268 File
=self
.MetaFile
, Line
=Record
[-1])
269 if len(LanguageCodes
)%3:
270 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
271 File
=self
.MetaFile
, Line
=Record
[-1])
273 for i
in range(0, len(LanguageCodes
), 3):
274 LanguageList
.append(LanguageCodes
[i
:i
+3])
275 self
._ISOLanguages
= LanguageList
276 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
278 # try to convert GUID to a real UUID value to see whether the GUID is format
279 # for VPD_TOOL_GUID is correct.
284 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
285 self
._VpdToolGuid
= Record
[2]
287 self
[Name
] = Record
[2]
288 # set _Header to non-None in order to avoid database re-querying
289 self
._Header
= 'DUMMY'
291 ## Retrieve platform name
292 def _GetPlatformName(self
):
293 if self
._PlatformName
== None:
294 if self
._Header
== None:
295 self
._GetHeaderInfo
()
296 if self
._PlatformName
== None:
297 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
298 return self
._PlatformName
300 ## Retrieve file guid
301 def _GetFileGuid(self
):
302 if self
._Guid
== None:
303 if self
._Header
== None:
304 self
._GetHeaderInfo
()
305 if self
._Guid
== None:
306 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
309 ## Retrieve platform version
310 def _GetVersion(self
):
311 if self
._Version
== None:
312 if self
._Header
== None:
313 self
._GetHeaderInfo
()
314 if self
._Version
== None:
315 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
318 ## Retrieve platform description file version
319 def _GetDscSpec(self
):
320 if self
._DscSpecification
== None:
321 if self
._Header
== None:
322 self
._GetHeaderInfo
()
323 if self
._DscSpecification
== None:
324 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
325 return self
._DscSpecification
327 ## Retrieve OUTPUT_DIRECTORY
328 def _GetOutpuDir(self
):
329 if self
._OutputDirectory
== None:
330 if self
._Header
== None:
331 self
._GetHeaderInfo
()
332 if self
._OutputDirectory
== None:
333 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
334 return self
._OutputDirectory
336 ## Retrieve SUPPORTED_ARCHITECTURES
337 def _GetSupArch(self
):
338 if self
._SupArchList
== None:
339 if self
._Header
== None:
340 self
._GetHeaderInfo
()
341 if self
._SupArchList
== None:
342 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
343 return self
._SupArchList
345 ## Retrieve BUILD_TARGETS
346 def _GetBuildTarget(self
):
347 if self
._BuildTargets
== None:
348 if self
._Header
== None:
349 self
._GetHeaderInfo
()
350 if self
._BuildTargets
== None:
351 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
352 return self
._BuildTargets
354 def _GetPcdInfoFlag(self
):
355 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
357 elif self
._PcdInfoFlag
.upper() == 'TRUE':
361 def _GetVarCheckFlag(self
):
362 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
364 elif self
._VarCheckFlag
.upper() == 'TRUE':
368 def _GetAviableSkuIds(self
):
369 if self
._AvilableSkuIds
:
370 return self
._AvilableSkuIds
371 return self
.SkuIdentifier
372 def _GetSkuIdentifier(self
):
375 if self
._SkuIdentifier
== None:
376 if self
._Header
== None:
377 self
._GetHeaderInfo
()
378 return self
._SkuIdentifier
379 ## Retrieve SKUID_IDENTIFIER
380 def _GetSkuName(self
):
381 if self
._SkuName
== None:
382 if self
._Header
== None:
383 self
._GetHeaderInfo
()
384 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
385 self
._SkuName
= 'DEFAULT'
388 ## Override SKUID_IDENTIFIER
389 def _SetSkuName(self
, Value
):
390 self
._SkuName
= Value
393 def _GetFdfFile(self
):
394 if self
._FlashDefinition
== None:
395 if self
._Header
== None:
396 self
._GetHeaderInfo
()
397 if self
._FlashDefinition
== None:
398 self
._FlashDefinition
= ''
399 return self
._FlashDefinition
401 ## Retrieve FLASH_DEFINITION
402 def _GetBuildNumber(self
):
403 if self
._BuildNumber
== None:
404 if self
._Header
== None:
405 self
._GetHeaderInfo
()
406 if self
._BuildNumber
== None:
407 self
._BuildNumber
= ''
408 return self
._BuildNumber
410 ## Retrieve MAKEFILE_NAME
411 def _GetMakefileName(self
):
412 if self
._MakefileName
== None:
413 if self
._Header
== None:
414 self
._GetHeaderInfo
()
415 if self
._MakefileName
== None:
416 self
._MakefileName
= ''
417 return self
._MakefileName
419 ## Retrieve BsBaseAddress
420 def _GetBsBaseAddress(self
):
421 if self
._BsBaseAddress
== None:
422 if self
._Header
== None:
423 self
._GetHeaderInfo
()
424 if self
._BsBaseAddress
== None:
425 self
._BsBaseAddress
= ''
426 return self
._BsBaseAddress
428 ## Retrieve RtBaseAddress
429 def _GetRtBaseAddress(self
):
430 if self
._RtBaseAddress
== None:
431 if self
._Header
== None:
432 self
._GetHeaderInfo
()
433 if self
._RtBaseAddress
== None:
434 self
._RtBaseAddress
= ''
435 return self
._RtBaseAddress
437 ## Retrieve the top address for the load fix address
438 def _GetLoadFixAddress(self
):
439 if self
._LoadFixAddress
== None:
440 if self
._Header
== None:
441 self
._GetHeaderInfo
()
443 if self
._LoadFixAddress
== None:
444 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
447 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
449 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
452 # If command line defined, should override the value in DSC file.
454 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
456 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
458 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS']))
460 if self
._LoadFixAddress
< 0:
461 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
462 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
463 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
465 return self
._LoadFixAddress
467 ## Retrieve RFCLanguage filter
468 def _GetRFCLanguages(self
):
469 if self
._RFCLanguages
== None:
470 if self
._Header
== None:
471 self
._GetHeaderInfo
()
472 if self
._RFCLanguages
== None:
473 self
._RFCLanguages
= []
474 return self
._RFCLanguages
476 ## Retrieve ISOLanguage filter
477 def _GetISOLanguages(self
):
478 if self
._ISOLanguages
== None:
479 if self
._Header
== None:
480 self
._GetHeaderInfo
()
481 if self
._ISOLanguages
== None:
482 self
._ISOLanguages
= []
483 return self
._ISOLanguages
484 ## Retrieve the GUID string for VPD tool
485 def _GetVpdToolGuid(self
):
486 if self
._VpdToolGuid
== None:
487 if self
._Header
== None:
488 self
._GetHeaderInfo
()
489 if self
._VpdToolGuid
== None:
490 self
._VpdToolGuid
= ''
491 return self
._VpdToolGuid
493 ## Retrieve [SkuIds] section information
494 def _GetSkuIds(self
):
495 if self
._SkuIds
== None:
496 self
._SkuIds
= sdict()
497 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
498 for Record
in RecordList
:
499 if Record
[0] in [None, '']:
500 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
501 File
=self
.MetaFile
, Line
=Record
[-1])
502 if Record
[1] in [None, '']:
503 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
504 File
=self
.MetaFile
, Line
=Record
[-1])
505 self
._SkuIds
[Record
[1]] = Record
[0]
506 if 'DEFAULT' not in self
._SkuIds
:
507 self
._SkuIds
['DEFAULT'] = '0'
508 if 'COMMON' not in self
._SkuIds
:
509 self
._SkuIds
['COMMON'] = '0'
512 ## Retrieve [Components] section information
513 def _GetModules(self
):
514 if self
._Modules
!= None:
517 self
._Modules
= sdict()
518 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
519 Macros
= self
._Macros
520 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
521 for Record
in RecordList
:
522 DuplicatedFile
= False
523 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
527 # check the file validation
528 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
530 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
533 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
534 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
535 DuplicatedFile
= True
537 Module
= ModuleBuildClassObject()
538 Module
.MetaFile
= ModuleFile
540 # get module private library instance
541 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
542 for Record
in RecordList
:
543 LibraryClass
= Record
[0]
544 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
547 # check the file validation
548 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
550 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
553 if LibraryClass
== '' or LibraryClass
== 'NULL':
554 self
._NullLibraryNumber
+= 1
555 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
556 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
557 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
558 if LibraryPath
not in self
.LibraryInstances
:
559 self
.LibraryInstances
.append(LibraryPath
)
561 # get module private PCD setting
562 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
563 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
564 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
565 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
566 TokenList
= GetSplitValueList(Setting
)
567 DefaultValue
= TokenList
[0]
568 if len(TokenList
) > 1:
569 MaxDatumSize
= TokenList
[1]
572 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
573 Pcd
= PcdClassObject(
585 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
587 # get module private build options
588 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
589 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
590 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
591 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
593 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
594 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
596 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
597 if DuplicatedFile
and not RecordList
:
598 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
600 if len(RecordList
) != 1:
601 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
602 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
603 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
604 ModuleFile
.Arch
= self
._Arch
606 self
._Modules
[ModuleFile
] = Module
609 ## Retrieve all possible library instances used in this platform
610 def _GetLibraryInstances(self
):
611 if self
._LibraryInstances
== None:
612 self
._GetLibraryClasses
()
613 return self
._LibraryInstances
615 ## Retrieve [LibraryClasses] information
616 def _GetLibraryClasses(self
):
617 if self
._LibraryClasses
== None:
618 self
._LibraryInstances
= []
620 # tdict is a special dict kind of type, used for selecting correct
621 # library instance for given library class and module type
623 LibraryClassDict
= tdict(True, 3)
624 # track all library class names
625 LibraryClassSet
= set()
626 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
627 Macros
= self
._Macros
628 for Record
in RecordList
:
629 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
630 if LibraryClass
== '' or LibraryClass
== 'NULL':
631 self
._NullLibraryNumber
+= 1
632 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
633 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
634 LibraryClassSet
.add(LibraryClass
)
635 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
636 # check the file validation
637 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
639 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
642 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
643 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
644 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
645 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
646 if LibraryInstance
not in self
._LibraryInstances
:
647 self
._LibraryInstances
.append(LibraryInstance
)
649 # resolve the specific library instance for each class and each module type
650 self
._LibraryClasses
= tdict(True)
651 for LibraryClass
in LibraryClassSet
:
652 # try all possible module types
653 for ModuleType
in SUP_MODULE_LIST
:
654 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
655 if LibraryInstance
== None:
657 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
659 # for Edk style library instances, which are listed in different section
660 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
661 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
662 for Record
in RecordList
:
663 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
665 # check the file validation
666 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
668 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
670 if File
not in self
._LibraryInstances
:
671 self
._LibraryInstances
.append(File
)
673 # we need the module name as the library class name, so we have
674 # to parse it here. (self._Bdb[] will trigger a file parse if it
675 # hasn't been parsed)
677 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
678 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
679 return self
._LibraryClasses
681 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
682 if self
._DecPcds
== None:
683 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
685 if GlobalData
.gFdfParser
:
686 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
689 for Inf
in FdfInfList
:
690 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
691 if ModuleFile
in self
._Modules
:
693 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
694 PkgSet
.update(ModuleData
.Packages
)
698 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
699 self
._DecPcds
.update(DecPcds
)
701 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
702 EdkLogger
.error('build', PARSER_ERROR
,
703 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
704 File
=self
.MetaFile
, Line
=LineNo
)
705 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
706 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
707 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
708 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
709 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
711 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
712 except WrnExpression
, Value
:
713 ValueList
[Index
] = Value
.result
714 except EvaluationException
, Excpt
:
715 if hasattr(Excpt
, 'Pcd'):
716 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
717 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
718 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
719 " of the DSC file" % Excpt
.Pcd
,
720 File
=self
.MetaFile
, Line
=LineNo
)
722 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
723 File
=self
.MetaFile
, Line
=LineNo
)
725 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
726 File
=self
.MetaFile
, Line
=LineNo
)
727 if ValueList
[Index
] == 'True':
728 ValueList
[Index
] = '1'
729 elif ValueList
[Index
] == 'False':
730 ValueList
[Index
] = '0'
732 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
734 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
735 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
738 ## Retrieve all PCD settings in platform
740 if self
._Pcds
== None:
742 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
743 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
744 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
745 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
746 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
747 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
748 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
749 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
750 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
753 ## Retrieve [BuildOptions]
754 def _GetBuildOptions(self
):
755 if self
._BuildOptions
== None:
756 self
._BuildOptions
= sdict()
758 # Retrieve build option for EDKII and EDK style module
760 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
761 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
762 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
763 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
765 # Only flags can be appended
767 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
768 self
._BuildOptions
[CurKey
] = Option
770 self
._BuildOptions
[CurKey
] += ' ' + Option
771 return self
._BuildOptions
773 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
774 if self
._ModuleTypeOptions
== None:
775 self
._ModuleTypeOptions
= sdict()
776 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
778 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
779 DriverType
= '%s.%s' % (Edk
, ModuleType
)
780 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, DriverType
]
781 for ToolChainFamily
, ToolChain
, Option
, Arch
, Type
, Dummy3
, Dummy4
in RecordList
:
782 if Type
== DriverType
:
783 Key
= (ToolChainFamily
, ToolChain
, Edk
)
784 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
785 options
[Key
] = Option
787 options
[Key
] += ' ' + Option
788 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
790 ## Retrieve non-dynamic PCD settings
792 # @param Type PCD type
794 # @retval a dict object contains settings of given PCD type
796 def _GetPcd(self
, Type
):
799 # tdict is a special dict kind of type, used for selecting correct
800 # PCD settings for certain ARCH
803 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
805 PcdDict
= tdict(True, 3)
807 # Find out all possible PCD candidates for self._Arch
808 RecordList
= self
._RawData
[Type
, self
._Arch
]
809 PcdValueDict
= sdict()
810 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
811 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
812 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
813 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
815 #handle pcd value override
816 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
817 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
820 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
821 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
822 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
824 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
826 PcdsKeys
= PcdValueDict
.keys()
827 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
829 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
833 if 'COMMON' in PcdSetting
:
834 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
835 if 'DEFAULT' in PcdSetting
:
836 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
837 if SkuObj
.SystemSkuId
in PcdSetting
:
838 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
840 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
843 self
._PCD
_TYPE
_STRING
_[Type
],
854 ## Retrieve dynamic PCD settings
856 # @param Type PCD type
858 # @retval a dict object contains settings of given PCD type
860 def _GetDynamicPcd(self
, Type
):
862 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
866 # tdict is a special dict kind of type, used for selecting correct
867 # PCD settings for certain ARCH and SKU
869 PcdDict
= tdict(True, 4)
871 # Find out all possible PCD candidates for self._Arch
872 RecordList
= self
._RawData
[Type
, self
._Arch
]
873 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
875 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
876 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
877 if SkuName
not in AvailableSkuIdSet
:
880 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
881 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
882 # Remove redundant PCD candidates, per the ARCH and SKU
883 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
885 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
889 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
890 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
891 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
892 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
893 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
894 if MaxDatumSize
.strip():
895 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
898 if pcdObject
.MaxDatumSize
:
899 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
902 if CurrentMaxSize
> PcdMaxSize
:
903 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
905 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
908 self
._PCD
_TYPE
_STRING
_[Type
],
918 for pcd
in Pcds
.values():
919 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
920 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
921 valuefromDec
= pcdDecObject
.DefaultValue
922 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
923 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
924 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
925 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
926 del(pcd
.SkuInfoList
['COMMON'])
927 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
928 del(pcd
.SkuInfoList
['COMMON'])
929 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
930 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
931 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
932 del(pcd
.SkuInfoList
['DEFAULT'])
936 def CompareVarAttr(self
, Attr1
, Attr2
):
937 if not Attr1
or not Attr2
: # for empty string
939 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
940 Attr1Set
= set(Attr1s
)
941 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
942 Attr2Set
= set(Attr2s
)
943 if Attr2Set
== Attr1Set
:
947 ## Retrieve dynamic HII PCD settings
949 # @param Type PCD type
951 # @retval a dict object contains settings of given PCD type
953 def _GetDynamicHiiPcd(self
, Type
):
955 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
960 # tdict is a special dict kind of type, used for selecting correct
961 # PCD settings for certain ARCH and SKU
963 PcdDict
= tdict(True, 4)
965 RecordList
= self
._RawData
[Type
, self
._Arch
]
966 # Find out all possible PCD candidates for self._Arch
967 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
969 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
970 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
971 if SkuName
not in AvailableSkuIdSet
:
973 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
974 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
975 # Remove redundant PCD candidates, per the ARCH and SKU
976 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
978 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
981 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
983 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
985 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
986 ExtraData
= "[%s]" % VarAttribute
)
989 if VariableOffset
.isdigit():
990 if int(VariableOffset
,10) > 0xFFFF:
992 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
993 if int(VariableOffset
,16) > 0xFFFF:
995 # For Offset written in "A.B"
996 elif VariableOffset
.find('.') > -1:
997 VariableOffsetList
= VariableOffset
.split(".")
998 if not (len(VariableOffsetList
) == 2
999 and IsValidWord(VariableOffsetList
[0])
1000 and IsValidWord(VariableOffsetList
[1])):
1001 FormatCorrect
= False
1003 FormatCorrect
= False
1004 if not FormatCorrect
:
1005 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1008 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1009 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1010 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1012 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1013 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
)]))
1015 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
= VarAttribute
)
1016 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1017 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1018 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1019 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1021 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1024 self
._PCD
_TYPE
_STRING
_[Type
],
1029 {SkuName
: SkuInfo
},
1032 pcdDecObject
.validateranges
,
1033 pcdDecObject
.validlists
,
1034 pcdDecObject
.expressions
1038 for pcd
in Pcds
.values():
1039 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1040 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1041 # Only fix the value while no value provided in DSC file.
1042 for sku
in pcd
.SkuInfoList
.values():
1043 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
1044 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1045 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1046 valuefromDec
= pcdDecObject
.DefaultValue
1047 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
1048 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1049 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1050 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1051 del(pcd
.SkuInfoList
['COMMON'])
1052 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1053 del(pcd
.SkuInfoList
['COMMON'])
1055 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1056 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1057 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1058 del(pcd
.SkuInfoList
['DEFAULT'])
1061 if pcd
.MaxDatumSize
.strip():
1062 MaxSize
= int(pcd
.MaxDatumSize
,0)
1065 if pcdDecObject
.DatumType
== 'VOID*':
1066 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1068 if skuobj
.HiiDefaultValue
.startswith("L"):
1069 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
1070 elif skuobj
.HiiDefaultValue
.startswith("{"):
1071 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1073 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
1076 pcd
.MaxDatumSize
= str(MaxSize
)
1079 ## Retrieve dynamic VPD PCD settings
1081 # @param Type PCD type
1083 # @retval a dict object contains settings of given PCD type
1085 def _GetDynamicVpdPcd(self
, Type
):
1087 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
1091 # tdict is a special dict kind of type, used for selecting correct
1092 # PCD settings for certain ARCH and SKU
1094 PcdDict
= tdict(True, 4)
1096 # Find out all possible PCD candidates for self._Arch
1097 RecordList
= self
._RawData
[Type
, self
._Arch
]
1098 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1100 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1101 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1102 if SkuName
not in AvailableSkuIdSet
:
1105 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1106 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1107 # Remove redundant PCD candidates, per the ARCH and SKU
1108 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1109 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1113 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1114 # For the Integer & Boolean type, the optional data can only be InitialValue.
1115 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1116 # until the DEC parser has been called.
1118 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1119 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1120 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1121 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1122 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1123 if MaxDatumSize
.strip():
1124 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1127 if pcdObject
.MaxDatumSize
:
1128 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1131 if CurrentMaxSize
> PcdMaxSize
:
1132 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1134 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1137 self
._PCD
_TYPE
_STRING
_[Type
],
1142 {SkuName
: SkuInfo
},
1146 for pcd
in Pcds
.values():
1147 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1148 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1149 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1150 valuefromDec
= pcdDecObject
.DefaultValue
1151 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1152 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1153 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1154 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1155 del(pcd
.SkuInfoList
['COMMON'])
1156 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1157 del(pcd
.SkuInfoList
['COMMON'])
1158 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1159 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1160 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1161 del(pcd
.SkuInfoList
['DEFAULT'])
1165 ## Add external modules
1167 # The external modules are mostly those listed in FDF file, which don't
1170 # @param FilePath The path of module description file
1172 def AddModule(self
, FilePath
):
1173 FilePath
= NormPath(FilePath
)
1174 if FilePath
not in self
.Modules
:
1175 Module
= ModuleBuildClassObject()
1176 Module
.MetaFile
= FilePath
1177 self
.Modules
.append(Module
)
1179 ## Add external PCDs
1181 # The external PCDs are mostly those listed in FDF file to specify address
1182 # or offset information.
1184 # @param Name Name of the PCD
1185 # @param Guid Token space guid of the PCD
1186 # @param Value Value of the PCD
1188 def AddPcd(self
, Name
, Guid
, Value
):
1189 if (Name
, Guid
) not in self
.Pcds
:
1190 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1191 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1193 _Macros
= property(_GetMacros
)
1194 Arch
= property(_GetArch
, _SetArch
)
1195 Platform
= property(_GetPlatformName
)
1196 PlatformName
= property(_GetPlatformName
)
1197 Guid
= property(_GetFileGuid
)
1198 Version
= property(_GetVersion
)
1199 DscSpecification
= property(_GetDscSpec
)
1200 OutputDirectory
= property(_GetOutpuDir
)
1201 SupArchList
= property(_GetSupArch
)
1202 BuildTargets
= property(_GetBuildTarget
)
1203 SkuName
= property(_GetSkuName
, _SetSkuName
)
1204 SkuIdentifier
= property(_GetSkuIdentifier
)
1205 AvilableSkuIds
= property(_GetAviableSkuIds
)
1206 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1207 VarCheckFlag
= property(_GetVarCheckFlag
)
1208 FlashDefinition
= property(_GetFdfFile
)
1209 BuildNumber
= property(_GetBuildNumber
)
1210 MakefileName
= property(_GetMakefileName
)
1211 BsBaseAddress
= property(_GetBsBaseAddress
)
1212 RtBaseAddress
= property(_GetRtBaseAddress
)
1213 LoadFixAddress
= property(_GetLoadFixAddress
)
1214 RFCLanguages
= property(_GetRFCLanguages
)
1215 ISOLanguages
= property(_GetISOLanguages
)
1216 VpdToolGuid
= property(_GetVpdToolGuid
)
1217 SkuIds
= property(_GetSkuIds
)
1218 Modules
= property(_GetModules
)
1219 LibraryInstances
= property(_GetLibraryInstances
)
1220 LibraryClasses
= property(_GetLibraryClasses
)
1221 Pcds
= property(_GetPcds
)
1222 BuildOptions
= property(_GetBuildOptions
)
1224 ## Platform build information from DEC file
1226 # This class is used to retrieve information stored in database and convert them
1227 # into PackageBuildClassObject form for easier use for AutoGen.
1229 class DecBuildData(PackageBuildClassObject
):
1230 # dict used to convert PCD type in database to string used by build tool
1231 _PCD_TYPE_STRING_
= {
1232 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1233 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1234 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1235 MODEL_PCD_DYNAMIC
: "Dynamic",
1236 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1237 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1238 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1239 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1240 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1241 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1242 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1245 # dict used to convert part of [Defines] to members of DecBuildData directly
1250 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1251 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1252 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1253 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1257 ## Constructor of DecBuildData
1259 # Initialize object of DecBuildData
1261 # @param FilePath The path of package description file
1262 # @param RawData The raw data of DEC file
1263 # @param BuildDataBase Database used to retrieve module information
1264 # @param Arch The target architecture
1265 # @param Platform (not used for DecBuildData)
1266 # @param Macros Macros used for replacement in DSC file
1268 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1269 self
.MetaFile
= File
1270 self
._PackageDir
= File
.Dir
1271 self
._RawData
= RawData
1272 self
._Bdb
= BuildDataBase
1274 self
._Target
= Target
1275 self
._Toolchain
= Toolchain
1279 def __setitem__(self
, key
, value
):
1280 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1283 def __getitem__(self
, key
):
1284 return self
.__dict
__[self
._PROPERTY
_[key
]]
1286 ## "in" test support
1287 def __contains__(self
, key
):
1288 return key
in self
._PROPERTY
_
1290 ## Set all internal used members of DecBuildData to None
1293 self
._PackageName
= None
1295 self
._Version
= None
1296 self
._PkgUniFile
= None
1297 self
._Protocols
= None
1300 self
._Includes
= None
1301 self
._LibraryClasses
= None
1303 self
.__Macros
= None
1305 ## Get current effective macros
1306 def _GetMacros(self
):
1307 if self
.__Macros
== None:
1309 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1310 return self
.__Macros
1318 # Changing the default ARCH to another may affect all other information
1319 # because all information in a platform may be ARCH-related. That's
1320 # why we need to clear all internal used members, in order to cause all
1321 # information to be re-retrieved.
1323 # @param Value The value of ARCH
1325 def _SetArch(self
, Value
):
1326 if self
._Arch
== Value
:
1331 ## Retrieve all information in [Defines] section
1333 # (Retriving all [Defines] information in one-shot is just to save time.)
1335 def _GetHeaderInfo(self
):
1336 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1337 for Record
in RecordList
:
1340 self
[Name
] = Record
[2]
1341 self
._Header
= 'DUMMY'
1343 ## Retrieve package name
1344 def _GetPackageName(self
):
1345 if self
._PackageName
== None:
1346 if self
._Header
== None:
1347 self
._GetHeaderInfo
()
1348 if self
._PackageName
== None:
1349 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1350 return self
._PackageName
1352 ## Retrieve file guid
1353 def _GetFileGuid(self
):
1354 if self
._Guid
== None:
1355 if self
._Header
== None:
1356 self
._GetHeaderInfo
()
1357 if self
._Guid
== None:
1358 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1361 ## Retrieve package version
1362 def _GetVersion(self
):
1363 if self
._Version
== None:
1364 if self
._Header
== None:
1365 self
._GetHeaderInfo
()
1366 if self
._Version
== None:
1368 return self
._Version
1370 ## Retrieve protocol definitions (name/value pairs)
1371 def _GetProtocol(self
):
1372 if self
._Protocols
== None:
1374 # tdict is a special kind of dict, used for selecting correct
1375 # protocol defition for given ARCH
1377 ProtocolDict
= tdict(True)
1379 # find out all protocol definitions for specific and 'common' arch
1380 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1381 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1382 if Name
not in NameList
:
1383 NameList
.append(Name
)
1384 ProtocolDict
[Arch
, Name
] = Guid
1385 # use sdict to keep the order
1386 self
._Protocols
= sdict()
1387 for Name
in NameList
:
1389 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1390 # will automatically turn to 'common' ARCH for trying
1392 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1393 return self
._Protocols
1395 ## Retrieve PPI definitions (name/value pairs)
1397 if self
._Ppis
== None:
1399 # tdict is a special kind of dict, used for selecting correct
1400 # PPI defition for given ARCH
1402 PpiDict
= tdict(True)
1404 # find out all PPI definitions for specific arch and 'common' arch
1405 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1406 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1407 if Name
not in NameList
:
1408 NameList
.append(Name
)
1409 PpiDict
[Arch
, Name
] = Guid
1410 # use sdict to keep the order
1411 self
._Ppis
= sdict()
1412 for Name
in NameList
:
1414 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1415 # will automatically turn to 'common' ARCH for trying
1417 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1420 ## Retrieve GUID definitions (name/value pairs)
1422 if self
._Guids
== None:
1424 # tdict is a special kind of dict, used for selecting correct
1425 # GUID defition for given ARCH
1427 GuidDict
= tdict(True)
1429 # find out all protocol definitions for specific and 'common' arch
1430 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1431 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1432 if Name
not in NameList
:
1433 NameList
.append(Name
)
1434 GuidDict
[Arch
, Name
] = Guid
1435 # use sdict to keep the order
1436 self
._Guids
= sdict()
1437 for Name
in NameList
:
1439 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1440 # will automatically turn to 'common' ARCH for trying
1442 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1445 ## Retrieve public include paths declared in this package
1446 def _GetInclude(self
):
1447 if self
._Includes
== None:
1449 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1450 Macros
= self
._Macros
1451 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1452 for Record
in RecordList
:
1453 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1456 ErrorCode
, ErrorInfo
= File
.Validate()
1458 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1460 # avoid duplicate include path
1461 if File
not in self
._Includes
:
1462 self
._Includes
.append(File
)
1463 return self
._Includes
1465 ## Retrieve library class declarations (not used in build at present)
1466 def _GetLibraryClass(self
):
1467 if self
._LibraryClasses
== None:
1469 # tdict is a special kind of dict, used for selecting correct
1470 # library class declaration for given ARCH
1472 LibraryClassDict
= tdict(True)
1473 LibraryClassSet
= set()
1474 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1475 Macros
= self
._Macros
1476 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1477 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1478 # check the file validation
1479 ErrorCode
, ErrorInfo
= File
.Validate()
1481 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1482 LibraryClassSet
.add(LibraryClass
)
1483 LibraryClassDict
[Arch
, LibraryClass
] = File
1484 self
._LibraryClasses
= sdict()
1485 for LibraryClass
in LibraryClassSet
:
1486 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1487 return self
._LibraryClasses
1489 ## Retrieve PCD declarations
1491 if self
._Pcds
== None:
1492 self
._Pcds
= sdict()
1493 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1494 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1495 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1496 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1497 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1500 ## Retrieve PCD declarations for given type
1501 def _GetPcd(self
, Type
):
1504 # tdict is a special kind of dict, used for selecting correct
1505 # PCD declaration for given ARCH
1507 PcdDict
= tdict(True, 3)
1508 # for summarizing PCD
1510 # find out all PCDs of the 'type'
1511 RecordList
= self
._RawData
[Type
, self
._Arch
]
1512 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1513 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1514 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1516 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1518 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1519 # will automatically turn to 'common' ARCH and try again
1521 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1525 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1527 validateranges
, validlists
, expressions
= self
._RawData
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
1528 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1531 self
._PCD
_TYPE
_STRING
_[Type
],
1539 list(validateranges
),
1546 _Macros
= property(_GetMacros
)
1547 Arch
= property(_GetArch
, _SetArch
)
1548 PackageName
= property(_GetPackageName
)
1549 Guid
= property(_GetFileGuid
)
1550 Version
= property(_GetVersion
)
1552 Protocols
= property(_GetProtocol
)
1553 Ppis
= property(_GetPpi
)
1554 Guids
= property(_GetGuid
)
1555 Includes
= property(_GetInclude
)
1556 LibraryClasses
= property(_GetLibraryClass
)
1557 Pcds
= property(_GetPcds
)
1559 ## Module build information from INF file
1561 # This class is used to retrieve information stored in database and convert them
1562 # into ModuleBuildClassObject form for easier use for AutoGen.
1564 class InfBuildData(ModuleBuildClassObject
):
1565 # dict used to convert PCD type in database to string used by build tool
1566 _PCD_TYPE_STRING_
= {
1567 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1568 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1569 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1570 MODEL_PCD_DYNAMIC
: "Dynamic",
1571 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1572 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1573 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1574 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1575 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1576 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1577 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1580 # dict used to convert part of [Defines] to members of InfBuildData directly
1585 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1586 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1587 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1591 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1592 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1593 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1594 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1595 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1596 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1597 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1598 TAB_INF_DEFINES_VERSION
: "_Version",
1599 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1600 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1602 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1605 # dict used to convert Component type to Module type
1608 "SECURITY_CORE" : "SEC",
1609 "PEI_CORE" : "PEI_CORE",
1610 "COMBINED_PEIM_DRIVER" : "PEIM",
1611 "PIC_PEIM" : "PEIM",
1612 "RELOCATABLE_PEIM" : "PEIM",
1613 "PE32_PEIM" : "PEIM",
1614 "BS_DRIVER" : "DXE_DRIVER",
1615 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1616 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1617 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1618 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1619 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1620 # "BS_DRIVER" : "UEFI_DRIVER",
1621 "APPLICATION" : "UEFI_APPLICATION",
1625 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1626 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1627 # dict used to convert old tool name used in [nmake] section to new ones
1635 ## Constructor of DscBuildData
1637 # Initialize object of DscBuildData
1639 # @param FilePath The path of platform description file
1640 # @param RawData The raw data of DSC file
1641 # @param BuildDataBase Database used to retrieve module/package information
1642 # @param Arch The target architecture
1643 # @param Platform The name of platform employing this module
1644 # @param Macros Macros used for replacement in DSC file
1646 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1647 self
.MetaFile
= FilePath
1648 self
._ModuleDir
= FilePath
.Dir
1649 self
._RawData
= RawData
1650 self
._Bdb
= BuildDatabase
1652 self
._Target
= Target
1653 self
._Toolchain
= Toolchain
1654 self
._Platform
= 'COMMON'
1655 self
._SourceOverridePath
= None
1656 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1657 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1661 def __setitem__(self
, key
, value
):
1662 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1665 def __getitem__(self
, key
):
1666 return self
.__dict
__[self
._PROPERTY
_[key
]]
1668 ## "in" test support
1669 def __contains__(self
, key
):
1670 return key
in self
._PROPERTY
_
1672 ## Set all internal used members of InfBuildData to None
1674 self
._HeaderComments
= None
1675 self
._TailComments
= None
1676 self
._Header
_ = None
1677 self
._AutoGenVersion
= None
1678 self
._BaseName
= None
1679 self
._DxsFile
= None
1680 self
._ModuleType
= None
1681 self
._ComponentType
= None
1682 self
._BuildType
= None
1684 self
._Version
= None
1685 self
._PcdIsDriver
= None
1686 self
._BinaryModule
= None
1688 self
._MakefileName
= None
1689 self
._CustomMakefile
= None
1690 self
._Specification
= None
1691 self
._LibraryClass
= None
1692 self
._ModuleEntryPointList
= None
1693 self
._ModuleUnloadImageList
= None
1694 self
._ConstructorList
= None
1695 self
._DestructorList
= None
1697 self
._Binaries
= None
1698 self
._Sources
= None
1699 self
._LibraryClasses
= None
1700 self
._Libraries
= None
1701 self
._Protocols
= None
1702 self
._ProtocolComments
= None
1704 self
._PpiComments
= None
1706 self
._GuidsUsedByPcd
= sdict()
1707 self
._GuidComments
= None
1708 self
._Includes
= None
1709 self
._Packages
= None
1711 self
._PcdComments
= None
1712 self
._BuildOptions
= None
1714 self
._DepexExpression
= None
1715 self
.__Macros
= None
1717 ## Get current effective macros
1718 def _GetMacros(self
):
1719 if self
.__Macros
== None:
1721 # EDK_GLOBAL defined macros can be applied to EDK module
1722 if self
.AutoGenVersion
< 0x00010005:
1723 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1724 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1725 return self
.__Macros
1733 # Changing the default ARCH to another may affect all other information
1734 # because all information in a platform may be ARCH-related. That's
1735 # why we need to clear all internal used members, in order to cause all
1736 # information to be re-retrieved.
1738 # @param Value The value of ARCH
1740 def _SetArch(self
, Value
):
1741 if self
._Arch
== Value
:
1746 ## Return the name of platform employing this module
1747 def _GetPlatform(self
):
1748 return self
._Platform
1750 ## Change the name of platform employing this module
1752 # Changing the default name of platform to another may affect some information
1753 # because they may be PLATFORM-related. That's why we need to clear all internal
1754 # used members, in order to cause all information to be re-retrieved.
1756 def _SetPlatform(self
, Value
):
1757 if self
._Platform
== Value
:
1759 self
._Platform
= Value
1761 def _GetHeaderComments(self
):
1762 if not self
._HeaderComments
:
1763 self
._HeaderComments
= []
1764 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1765 for Record
in RecordList
:
1766 self
._HeaderComments
.append(Record
[0])
1767 return self
._HeaderComments
1768 def _GetTailComments(self
):
1769 if not self
._TailComments
:
1770 self
._TailComments
= []
1771 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1772 for Record
in RecordList
:
1773 self
._TailComments
.append(Record
[0])
1774 return self
._TailComments
1775 ## Retrieve all information in [Defines] section
1777 # (Retriving all [Defines] information in one-shot is just to save time.)
1779 def _GetHeaderInfo(self
):
1780 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1781 for Record
in RecordList
:
1782 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1783 # items defined _PROPERTY_ don't need additional processing
1786 if self
._Defs
== None:
1787 self
._Defs
= sdict()
1788 self
._Defs
[Name
] = Value
1789 # some special items in [Defines] section need special treatment
1790 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1791 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1792 Name
= 'UEFI_SPECIFICATION_VERSION'
1793 if self
._Specification
== None:
1794 self
._Specification
= sdict()
1795 self
._Specification
[Name
] = GetHexVerValue(Value
)
1796 if self
._Specification
[Name
] == None:
1797 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1798 "'%s' format is not supported for %s" % (Value
, Name
),
1799 File
=self
.MetaFile
, Line
=Record
[-1])
1800 elif Name
== 'LIBRARY_CLASS':
1801 if self
._LibraryClass
== None:
1802 self
._LibraryClass
= []
1803 ValueList
= GetSplitValueList(Value
)
1804 LibraryClass
= ValueList
[0]
1805 if len(ValueList
) > 1:
1806 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1808 SupModuleList
= SUP_MODULE_LIST
1809 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1810 elif Name
== 'ENTRY_POINT':
1811 if self
._ModuleEntryPointList
== None:
1812 self
._ModuleEntryPointList
= []
1813 self
._ModuleEntryPointList
.append(Value
)
1814 elif Name
== 'UNLOAD_IMAGE':
1815 if self
._ModuleUnloadImageList
== None:
1816 self
._ModuleUnloadImageList
= []
1819 self
._ModuleUnloadImageList
.append(Value
)
1820 elif Name
== 'CONSTRUCTOR':
1821 if self
._ConstructorList
== None:
1822 self
._ConstructorList
= []
1825 self
._ConstructorList
.append(Value
)
1826 elif Name
== 'DESTRUCTOR':
1827 if self
._DestructorList
== None:
1828 self
._DestructorList
= []
1831 self
._DestructorList
.append(Value
)
1832 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1833 TokenList
= GetSplitValueList(Value
)
1834 if self
._CustomMakefile
== None:
1835 self
._CustomMakefile
= {}
1836 if len(TokenList
) < 2:
1837 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1838 self
._CustomMakefile
['GCC'] = TokenList
[0]
1840 if TokenList
[0] not in ['MSFT', 'GCC']:
1841 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1842 "No supported family [%s]" % TokenList
[0],
1843 File
=self
.MetaFile
, Line
=Record
[-1])
1844 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1846 if self
._Defs
== None:
1847 self
._Defs
= sdict()
1848 self
._Defs
[Name
] = Value
1851 # Retrieve information in sections specific to Edk.x modules
1853 if self
.AutoGenVersion
>= 0x00010005:
1854 if not self
._ModuleType
:
1855 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1856 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1857 if self
._ModuleType
not in SUP_MODULE_LIST
:
1858 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1859 for Record
in RecordList
:
1861 if Name
== "MODULE_TYPE":
1864 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1865 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1866 File
=self
.MetaFile
, Line
=LineNo
)
1867 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1868 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1869 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
)
1870 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1871 and 'PCI_CLASS_CODE' in self
._Defs
:
1872 self
._BuildType
= 'UEFI_OPTIONROM'
1873 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1874 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1875 self
._BuildType
= 'UEFI_HII'
1877 self
._BuildType
= self
._ModuleType
.upper()
1880 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1881 # check the file validation
1882 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1884 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1885 File
=self
.MetaFile
, Line
=LineNo
)
1886 if self
.Sources
== None:
1888 self
._Sources
.append(File
)
1890 if not self
._ComponentType
:
1891 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1892 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1893 self
._BuildType
= self
._ComponentType
.upper()
1894 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1895 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1896 if self
._ComponentType
== 'LIBRARY':
1897 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1898 # make use some [nmake] section macros
1899 Macros
= self
._Macros
1900 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1901 Macros
['PROCESSOR'] = self
._Arch
1902 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1903 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1904 Value
= ReplaceMacro(Value
, Macros
, True)
1905 if Name
== "IMAGE_ENTRY_POINT":
1906 if self
._ModuleEntryPointList
== None:
1907 self
._ModuleEntryPointList
= []
1908 self
._ModuleEntryPointList
.append(Value
)
1909 elif Name
== "DPX_SOURCE":
1910 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1911 # check the file validation
1912 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1914 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1915 File
=self
.MetaFile
, Line
=LineNo
)
1916 if self
.Sources
== None:
1918 self
._Sources
.append(File
)
1920 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1921 if len(ToolList
) == 0 or len(ToolList
) != 1:
1923 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1924 # File=self.MetaFile, Line=LineNo)
1926 if self
._BuildOptions
== None:
1927 self
._BuildOptions
= sdict()
1929 if ToolList
[0] in self
._TOOL
_CODE
_:
1930 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1933 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1934 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1935 #ignore not replaced macros in value
1936 ValueList
= GetSplitList(' ' + Value
, '/D')
1937 Dummy
= ValueList
[0]
1938 for Index
in range(1, len(ValueList
)):
1939 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1941 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1942 Value
= Dummy
.strip()
1943 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1944 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1946 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1947 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1948 # set _Header to non-None in order to avoid database re-querying
1949 self
._Header
_ = 'DUMMY'
1951 ## Retrieve file version
1952 def _GetInfVersion(self
):
1953 if self
._AutoGenVersion
== None:
1954 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1955 for Record
in RecordList
:
1956 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1957 self
._AutoGenVersion
= int(Record
[2], 0)
1959 if self
._AutoGenVersion
== None:
1960 self
._AutoGenVersion
= 0x00010000
1961 return self
._AutoGenVersion
1963 ## Retrieve BASE_NAME
1964 def _GetBaseName(self
):
1965 if self
._BaseName
== None:
1966 if self
._Header
_ == None:
1967 self
._GetHeaderInfo
()
1968 if self
._BaseName
== None:
1969 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1970 return self
._BaseName
1973 def _GetDxsFile(self
):
1974 if self
._DxsFile
== None:
1975 if self
._Header
_ == None:
1976 self
._GetHeaderInfo
()
1977 if self
._DxsFile
== None:
1979 return self
._DxsFile
1981 ## Retrieve MODULE_TYPE
1982 def _GetModuleType(self
):
1983 if self
._ModuleType
== None:
1984 if self
._Header
_ == None:
1985 self
._GetHeaderInfo
()
1986 if self
._ModuleType
== None:
1987 self
._ModuleType
= 'BASE'
1988 if self
._ModuleType
not in SUP_MODULE_LIST
:
1989 self
._ModuleType
= "USER_DEFINED"
1990 return self
._ModuleType
1992 ## Retrieve COMPONENT_TYPE
1993 def _GetComponentType(self
):
1994 if self
._ComponentType
== None:
1995 if self
._Header
_ == None:
1996 self
._GetHeaderInfo
()
1997 if self
._ComponentType
== None:
1998 self
._ComponentType
= 'USER_DEFINED'
1999 return self
._ComponentType
2001 ## Retrieve "BUILD_TYPE"
2002 def _GetBuildType(self
):
2003 if self
._BuildType
== None:
2004 if self
._Header
_ == None:
2005 self
._GetHeaderInfo
()
2006 if not self
._BuildType
:
2007 self
._BuildType
= "BASE"
2008 return self
._BuildType
2010 ## Retrieve file guid
2011 def _GetFileGuid(self
):
2012 if self
._Guid
== None:
2013 if self
._Header
_ == None:
2014 self
._GetHeaderInfo
()
2015 if self
._Guid
== None:
2016 self
._Guid
= '00000000-0000-0000-0000-000000000000'
2019 ## Retrieve module version
2020 def _GetVersion(self
):
2021 if self
._Version
== None:
2022 if self
._Header
_ == None:
2023 self
._GetHeaderInfo
()
2024 if self
._Version
== None:
2025 self
._Version
= '0.0'
2026 return self
._Version
2028 ## Retrieve PCD_IS_DRIVER
2029 def _GetPcdIsDriver(self
):
2030 if self
._PcdIsDriver
== None:
2031 if self
._Header
_ == None:
2032 self
._GetHeaderInfo
()
2033 if self
._PcdIsDriver
== None:
2034 self
._PcdIsDriver
= ''
2035 return self
._PcdIsDriver
2038 def _GetShadow(self
):
2039 if self
._Shadow
== None:
2040 if self
._Header
_ == None:
2041 self
._GetHeaderInfo
()
2042 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
2045 self
._Shadow
= False
2048 ## Retrieve CUSTOM_MAKEFILE
2049 def _GetMakefile(self
):
2050 if self
._CustomMakefile
== None:
2051 if self
._Header
_ == None:
2052 self
._GetHeaderInfo
()
2053 if self
._CustomMakefile
== None:
2054 self
._CustomMakefile
= {}
2055 return self
._CustomMakefile
2057 ## Retrieve EFI_SPECIFICATION_VERSION
2059 if self
._Specification
== None:
2060 if self
._Header
_ == None:
2061 self
._GetHeaderInfo
()
2062 if self
._Specification
== None:
2063 self
._Specification
= {}
2064 return self
._Specification
2066 ## Retrieve LIBRARY_CLASS
2067 def _GetLibraryClass(self
):
2068 if self
._LibraryClass
== None:
2069 if self
._Header
_ == None:
2070 self
._GetHeaderInfo
()
2071 if self
._LibraryClass
== None:
2072 self
._LibraryClass
= []
2073 return self
._LibraryClass
2075 ## Retrieve ENTRY_POINT
2076 def _GetEntryPoint(self
):
2077 if self
._ModuleEntryPointList
== None:
2078 if self
._Header
_ == None:
2079 self
._GetHeaderInfo
()
2080 if self
._ModuleEntryPointList
== None:
2081 self
._ModuleEntryPointList
= []
2082 return self
._ModuleEntryPointList
2084 ## Retrieve UNLOAD_IMAGE
2085 def _GetUnloadImage(self
):
2086 if self
._ModuleUnloadImageList
== None:
2087 if self
._Header
_ == None:
2088 self
._GetHeaderInfo
()
2089 if self
._ModuleUnloadImageList
== None:
2090 self
._ModuleUnloadImageList
= []
2091 return self
._ModuleUnloadImageList
2093 ## Retrieve CONSTRUCTOR
2094 def _GetConstructor(self
):
2095 if self
._ConstructorList
== None:
2096 if self
._Header
_ == None:
2097 self
._GetHeaderInfo
()
2098 if self
._ConstructorList
== None:
2099 self
._ConstructorList
= []
2100 return self
._ConstructorList
2102 ## Retrieve DESTRUCTOR
2103 def _GetDestructor(self
):
2104 if self
._DestructorList
== None:
2105 if self
._Header
_ == None:
2106 self
._GetHeaderInfo
()
2107 if self
._DestructorList
== None:
2108 self
._DestructorList
= []
2109 return self
._DestructorList
2111 ## Retrieve definies other than above ones
2112 def _GetDefines(self
):
2113 if self
._Defs
== None:
2114 if self
._Header
_ == None:
2115 self
._GetHeaderInfo
()
2116 if self
._Defs
== None:
2117 self
._Defs
= sdict()
2120 ## Retrieve binary files
2121 def _GetBinaries(self
):
2122 if self
._Binaries
== None:
2124 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2125 Macros
= self
._Macros
2126 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2127 Macros
['PROCESSOR'] = self
._Arch
2128 for Record
in RecordList
:
2129 FileType
= Record
[0]
2134 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2136 Target
= TokenList
[0]
2137 if len(TokenList
) > 1:
2138 FeatureFlag
= Record
[1:]
2140 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2141 # check the file validation
2142 ErrorCode
, ErrorInfo
= File
.Validate()
2144 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2145 self
._Binaries
.append(File
)
2146 return self
._Binaries
2148 ## Retrieve binary files with error check.
2149 def _GetBinaryFiles(self
):
2150 Binaries
= self
._GetBinaries
()
2151 if GlobalData
.gIgnoreSource
and Binaries
== []:
2152 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2153 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2156 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2157 def _IsSupportedArch(self
):
2158 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2162 ## Retrieve source files
2163 def _GetSourceFiles(self
):
2164 #Ignore all source files in a binary build mode
2165 if GlobalData
.gIgnoreSource
:
2167 return self
._Sources
2169 if self
._Sources
== None:
2171 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2172 Macros
= self
._Macros
2173 for Record
in RecordList
:
2175 ToolChainFamily
= Record
[1]
2177 ToolCode
= Record
[3]
2178 FeatureFlag
= Record
[4]
2179 if self
.AutoGenVersion
< 0x00010005:
2180 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2181 Macros
['PROCESSOR'] = self
._Arch
2182 # old module source files (Edk)
2183 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
2184 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2185 # check the file validation
2186 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2188 if File
.Ext
.lower() == '.h':
2189 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2190 File
=self
.MetaFile
, Line
=LineNo
)
2193 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2195 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2196 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2197 # check the file validation
2198 ErrorCode
, ErrorInfo
= File
.Validate()
2200 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2202 self
._Sources
.append(File
)
2203 return self
._Sources
2205 ## Retrieve library classes employed by this module
2206 def _GetLibraryClassUses(self
):
2207 if self
._LibraryClasses
== None:
2208 self
._LibraryClasses
= sdict()
2209 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2210 for Record
in RecordList
:
2212 Instance
= Record
[1]
2214 Instance
= NormPath(Instance
, self
._Macros
)
2215 self
._LibraryClasses
[Lib
] = Instance
2216 return self
._LibraryClasses
2218 ## Retrieve library names (for Edk.x style of modules)
2219 def _GetLibraryNames(self
):
2220 if self
._Libraries
== None:
2221 self
._Libraries
= []
2222 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2223 for Record
in RecordList
:
2224 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2225 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2226 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2227 if LibraryName
not in self
._Libraries
:
2228 self
._Libraries
.append(LibraryName
)
2229 return self
._Libraries
2231 def _GetProtocolComments(self
):
2232 self
._GetProtocols
()
2233 return self
._ProtocolComments
2234 ## Retrieve protocols consumed/produced by this module
2235 def _GetProtocols(self
):
2236 if self
._Protocols
== None:
2237 self
._Protocols
= sdict()
2238 self
._ProtocolComments
= sdict()
2239 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2240 for Record
in RecordList
:
2242 Value
= ProtocolValue(CName
, self
.Packages
)
2244 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2245 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2246 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2247 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2248 self
._Protocols
[CName
] = Value
2249 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2251 for CmtRec
in CommentRecords
:
2252 Comments
.append(CmtRec
[0])
2253 self
._ProtocolComments
[CName
] = Comments
2254 return self
._Protocols
2256 def _GetPpiComments(self
):
2258 return self
._PpiComments
2259 ## Retrieve PPIs consumed/produced by this module
2261 if self
._Ppis
== None:
2262 self
._Ppis
= sdict()
2263 self
._PpiComments
= sdict()
2264 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2265 for Record
in RecordList
:
2267 Value
= PpiValue(CName
, self
.Packages
)
2269 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2270 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2271 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2272 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2273 self
._Ppis
[CName
] = Value
2274 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2276 for CmtRec
in CommentRecords
:
2277 Comments
.append(CmtRec
[0])
2278 self
._PpiComments
[CName
] = Comments
2281 def _GetGuidComments(self
):
2283 return self
._GuidComments
2284 ## Retrieve GUIDs consumed/produced by this module
2285 def _GetGuids(self
):
2286 if self
._Guids
== None:
2287 self
._Guids
= sdict()
2288 self
._GuidComments
= sdict()
2289 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2290 for Record
in RecordList
:
2292 Value
= GuidValue(CName
, self
.Packages
)
2294 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2295 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2296 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2297 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2298 self
._Guids
[CName
] = Value
2299 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2301 for CmtRec
in CommentRecords
:
2302 Comments
.append(CmtRec
[0])
2303 self
._GuidComments
[CName
] = Comments
2306 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2307 def _GetIncludes(self
):
2308 if self
._Includes
== None:
2310 if self
._SourceOverridePath
:
2311 self
._Includes
.append(self
._SourceOverridePath
)
2313 Macros
= self
._Macros
2314 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2315 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2317 Macros
['PROCESSOR'] = self
._Arch
2318 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2319 for Record
in RecordList
:
2320 if Record
[0].find('EDK_SOURCE') > -1:
2321 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2322 File
= NormPath(Record
[0], self
._Macros
)
2324 File
= os
.path
.join(self
._ModuleDir
, File
)
2326 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2327 File
= RealPath(os
.path
.normpath(File
))
2329 self
._Includes
.append(File
)
2331 #TRICK: let compiler to choose correct header file
2332 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2333 File
= NormPath(Record
[0], self
._Macros
)
2335 File
= os
.path
.join(self
._ModuleDir
, File
)
2337 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2338 File
= RealPath(os
.path
.normpath(File
))
2340 self
._Includes
.append(File
)
2342 File
= NormPath(Record
[0], Macros
)
2344 File
= os
.path
.join(self
._ModuleDir
, File
)
2346 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2347 File
= RealPath(os
.path
.normpath(File
))
2349 self
._Includes
.append(File
)
2350 return self
._Includes
2352 ## Retrieve packages this module depends on
2353 def _GetPackages(self
):
2354 if self
._Packages
== None:
2356 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2357 Macros
= self
._Macros
2358 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2359 for Record
in RecordList
:
2360 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2362 # check the file validation
2363 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2365 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2366 # parse this package now. we need it to get protocol/ppi/guid value
2367 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2368 self
._Packages
.append(Package
)
2369 return self
._Packages
2371 ## Retrieve PCD comments
2372 def _GetPcdComments(self
):
2374 return self
._PcdComments
2375 ## Retrieve PCDs used in this module
2377 if self
._Pcds
== None:
2378 self
._Pcds
= sdict()
2379 self
._PcdComments
= sdict()
2380 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2381 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2382 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2383 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2384 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2387 ## Retrieve build options specific to this module
2388 def _GetBuildOptions(self
):
2389 if self
._BuildOptions
== None:
2390 self
._BuildOptions
= sdict()
2391 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2392 for Record
in RecordList
:
2393 ToolChainFamily
= Record
[0]
2394 ToolChain
= Record
[1]
2396 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
or Option
.startswith('='):
2397 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2399 # concatenate the option string if they're for the same tool
2400 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2401 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2402 return self
._BuildOptions
2404 ## Retrieve dependency expression
2405 def _GetDepex(self
):
2406 if self
._Depex
== None:
2407 self
._Depex
= tdict(False, 2)
2408 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2410 # If the module has only Binaries and no Sources, then ignore [Depex]
2411 if self
.Sources
== None or self
.Sources
== []:
2412 if self
.Binaries
!= None and self
.Binaries
!= []:
2415 # PEIM and DXE drivers must have a valid [Depex] section
2416 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2417 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2418 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2419 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2420 % self
.ModuleType
, File
=self
.MetaFile
)
2422 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2423 for Record
in RecordList
:
2424 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2425 EdkLogger
.error('build', FORMAT_INVALID
,
2426 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2430 for Record
in RecordList
:
2431 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2433 ModuleType
= Record
[4]
2434 TokenList
= DepexStr
.split()
2435 if (Arch
, ModuleType
) not in Depex
:
2436 Depex
[Arch
, ModuleType
] = []
2437 DepexList
= Depex
[Arch
, ModuleType
]
2438 for Token
in TokenList
:
2439 if Token
in DEPEX_SUPPORTED_OPCODE
:
2440 DepexList
.append(Token
)
2441 elif Token
.endswith(".inf"): # module file name
2442 ModuleFile
= os
.path
.normpath(Token
)
2443 Module
= self
.BuildDatabase
[ModuleFile
]
2445 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2446 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2447 DepexList
.append(Module
.Guid
)
2449 # get the GUID value now
2450 Value
= ProtocolValue(Token
, self
.Packages
)
2452 Value
= PpiValue(Token
, self
.Packages
)
2454 Value
= GuidValue(Token
, self
.Packages
)
2456 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2457 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2458 "Value of [%s] is not found in" % Token
,
2459 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2460 DepexList
.append(Value
)
2461 for Arch
, ModuleType
in Depex
:
2462 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2465 ## Retrieve depedency expression
2466 def _GetDepexExpression(self
):
2467 if self
._DepexExpression
== None:
2468 self
._DepexExpression
= tdict(False, 2)
2469 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2470 DepexExpression
= sdict()
2471 for Record
in RecordList
:
2472 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2474 ModuleType
= Record
[4]
2475 TokenList
= DepexStr
.split()
2476 if (Arch
, ModuleType
) not in DepexExpression
:
2477 DepexExpression
[Arch
, ModuleType
] = ''
2478 for Token
in TokenList
:
2479 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2480 for Arch
, ModuleType
in DepexExpression
:
2481 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2482 return self
._DepexExpression
2484 def GetGuidsUsedByPcd(self
):
2485 return self
._GuidsUsedByPcd
2486 ## Retrieve PCD for given type
2487 def _GetPcd(self
, Type
):
2489 PcdDict
= tdict(True, 4)
2491 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2492 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2493 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2494 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2495 # get the guid value
2496 if TokenSpaceGuid
not in self
.Guids
:
2497 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2499 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2500 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2501 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2502 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2503 self
.Guids
[TokenSpaceGuid
] = Value
2504 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2505 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2507 for CmtRec
in CommentRecords
:
2508 Comments
.append(CmtRec
[0])
2509 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2511 # resolve PCD type, value, datum info, etc. by getting its definition from package
2512 for PcdCName
, TokenSpaceGuid
in PcdList
:
2513 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2516 ValueList
= AnalyzePcdData(Setting
)
2517 DefaultValue
= ValueList
[0]
2518 Pcd
= PcdClassObject(
2528 self
.Guids
[TokenSpaceGuid
]
2530 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2531 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2532 Pcd
.Offset
= ValueList
[1]
2534 # get necessary info from package declaring this PCD
2535 for Package
in self
.Packages
:
2537 # 'dynamic' in INF means its type is determined by platform;
2538 # if platform doesn't give its type, use 'lowest' one in the
2539 # following order, if any
2541 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2543 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2544 if Type
== MODEL_PCD_DYNAMIC
:
2546 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2547 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2553 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2554 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2556 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2559 # Check whether the token value exist or not.
2561 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2565 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2566 File
=self
.MetaFile
, Line
=LineNo
,
2570 # Check hexadecimal token value length and format.
2572 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2573 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2574 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2578 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2579 File
=self
.MetaFile
, Line
=LineNo
,
2584 # Check decimal token value length and format.
2588 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2589 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2593 "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
)),
2594 File
=self
.MetaFile
, Line
=LineNo
,
2601 "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
)),
2602 File
=self
.MetaFile
, Line
=LineNo
,
2606 Pcd
.DatumType
= PcdInPackage
.DatumType
2607 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2608 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2609 if Pcd
.DefaultValue
in [None, '']:
2610 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2616 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2617 File
=self
.MetaFile
, Line
=LineNo
,
2618 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2620 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2624 ## check whether current module is binary module
2625 def _IsBinaryModule(self
):
2626 if self
.Binaries
and not self
.Sources
:
2628 elif GlobalData
.gIgnoreSource
:
2633 _Macros
= property(_GetMacros
)
2634 Arch
= property(_GetArch
, _SetArch
)
2635 Platform
= property(_GetPlatform
, _SetPlatform
)
2637 HeaderComments
= property(_GetHeaderComments
)
2638 TailComments
= property(_GetTailComments
)
2639 AutoGenVersion
= property(_GetInfVersion
)
2640 BaseName
= property(_GetBaseName
)
2641 ModuleType
= property(_GetModuleType
)
2642 ComponentType
= property(_GetComponentType
)
2643 BuildType
= property(_GetBuildType
)
2644 Guid
= property(_GetFileGuid
)
2645 Version
= property(_GetVersion
)
2646 PcdIsDriver
= property(_GetPcdIsDriver
)
2647 Shadow
= property(_GetShadow
)
2648 CustomMakefile
= property(_GetMakefile
)
2649 Specification
= property(_GetSpec
)
2650 LibraryClass
= property(_GetLibraryClass
)
2651 ModuleEntryPointList
= property(_GetEntryPoint
)
2652 ModuleUnloadImageList
= property(_GetUnloadImage
)
2653 ConstructorList
= property(_GetConstructor
)
2654 DestructorList
= property(_GetDestructor
)
2655 Defines
= property(_GetDefines
)
2656 DxsFile
= property(_GetDxsFile
)
2658 Binaries
= property(_GetBinaryFiles
)
2659 Sources
= property(_GetSourceFiles
)
2660 LibraryClasses
= property(_GetLibraryClassUses
)
2661 Libraries
= property(_GetLibraryNames
)
2662 Protocols
= property(_GetProtocols
)
2663 ProtocolComments
= property(_GetProtocolComments
)
2664 Ppis
= property(_GetPpis
)
2665 PpiComments
= property(_GetPpiComments
)
2666 Guids
= property(_GetGuids
)
2667 GuidComments
= property(_GetGuidComments
)
2668 Includes
= property(_GetIncludes
)
2669 Packages
= property(_GetPackages
)
2670 Pcds
= property(_GetPcds
)
2671 PcdComments
= property(_GetPcdComments
)
2672 BuildOptions
= property(_GetBuildOptions
)
2673 Depex
= property(_GetDepex
)
2674 DepexExpression
= property(_GetDepexExpression
)
2675 IsBinaryModule
= property(_IsBinaryModule
)
2676 IsSupportedArch
= property(_IsSupportedArch
)
2680 # This class defined the build database for all modules, packages and platform.
2681 # It will call corresponding parser for the given file if it cannot find it in
2684 # @param DbPath Path of database file
2685 # @param GlobalMacros Global macros used for replacement during file parsing
2686 # @prarm RenewDb=False Create new database file if it's already there
2688 class WorkspaceDatabase(object):
2692 # internal class used for call corresponding file parser and caching the result
2693 # to avoid unnecessary re-parsing
2695 class BuildObjectFactory(object):
2698 ".inf" : MODEL_FILE_INF
,
2699 ".dec" : MODEL_FILE_DEC
,
2700 ".dsc" : MODEL_FILE_DSC
,
2705 MODEL_FILE_INF
: InfParser
,
2706 MODEL_FILE_DEC
: DecParser
,
2707 MODEL_FILE_DSC
: DscParser
,
2710 # convert to xxxBuildData object
2712 MODEL_FILE_INF
: InfBuildData
,
2713 MODEL_FILE_DEC
: DecBuildData
,
2714 MODEL_FILE_DSC
: DscBuildData
,
2717 _CACHE_
= {} # (FilePath, Arch) : <object>
2720 def __init__(self
, WorkspaceDb
):
2721 self
.WorkspaceDb
= WorkspaceDb
2723 # key = (FilePath, Arch=None)
2724 def __contains__(self
, Key
):
2730 return (FilePath
, Arch
) in self
._CACHE
_
2732 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2733 def __getitem__(self
, Key
):
2735 KeyLength
= len(Key
)
2749 # if it's generated before, just return the cached one
2750 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2751 if Key
in self
._CACHE
_:
2752 return self
._CACHE
_[Key
]
2756 if Ext
not in self
._FILE
_TYPE
_:
2758 FileType
= self
._FILE
_TYPE
_[Ext
]
2759 if FileType
not in self
._GENERATOR
_:
2762 # get the parser ready for this file
2763 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2766 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2768 # alwasy do post-process, in case of macros change
2769 MetaFile
.DoPostProcess()
2770 # object the build is based on
2771 BuildObject
= self
._GENERATOR
_[FileType
](
2779 self
._CACHE
_[Key
] = BuildObject
2782 # placeholder for file format conversion
2783 class TransformObjectFactory
:
2784 def __init__(self
, WorkspaceDb
):
2785 self
.WorkspaceDb
= WorkspaceDb
2787 # key = FilePath, Arch
2788 def __getitem__(self
, Key
):
2791 ## Constructor of WorkspaceDatabase
2793 # @param DbPath Path of database file
2794 # @param GlobalMacros Global macros used for replacement during file parsing
2795 # @prarm RenewDb=False Create new database file if it's already there
2797 def __init__(self
, DbPath
, RenewDb
=False):
2798 self
._DbClosedFlag
= False
2800 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2802 # don't create necessary path for db in memory
2803 if DbPath
!= ':memory:':
2804 DbDir
= os
.path
.split(DbPath
)[0]
2805 if not os
.path
.exists(DbDir
):
2808 # remove db file in case inconsistency between db and file in file system
2809 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2812 # create db with optimized parameters
2813 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2814 self
.Conn
.execute("PRAGMA synchronous=OFF")
2815 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2816 self
.Conn
.execute("PRAGMA count_changes=OFF")
2817 self
.Conn
.execute("PRAGMA cache_size=8192")
2818 #self.Conn.execute("PRAGMA page_size=8192")
2820 # to avoid non-ascii character conversion issue
2821 self
.Conn
.text_factory
= str
2822 self
.Cur
= self
.Conn
.cursor()
2824 # create table for internal uses
2825 self
.TblDataModel
= TableDataModel(self
.Cur
)
2826 self
.TblFile
= TableFile(self
.Cur
)
2827 self
.Platform
= None
2829 # conversion object for build or file format conversion purpose
2830 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2831 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2833 ## Check whether workspace database need to be renew.
2834 # The renew reason maybe:
2835 # 1) If user force to renew;
2836 # 2) If user do not force renew, and
2837 # a) If the time of last modified python source is newer than database file;
2838 # b) If the time of last modified frozen executable file is newer than database file;
2840 # @param force User force renew database
2841 # @param DbPath The absolute path of workspace database file
2843 # @return Bool value for whether need renew workspace databse
2845 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2846 # if database does not exist, we need do nothing
2847 if not os
.path
.exists(DbPath
): return False
2849 # if user force to renew database, then not check whether database is out of date
2850 if force
: return True
2853 # Check the time of last modified source file or build.exe
2854 # if is newer than time of database, then database need to be re-created.
2856 timeOfToolModified
= 0
2857 if hasattr(sys
, "frozen"):
2858 exePath
= os
.path
.abspath(sys
.executable
)
2859 timeOfToolModified
= os
.stat(exePath
).st_mtime
2861 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2862 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2863 if rootPath
== "" or rootPath
== None:
2864 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2865 determine whether database file is out of date!\n")
2867 # walk the root path of source or build's binary to get the time last modified.
2869 for root
, dirs
, files
in os
.walk (rootPath
):
2871 # bypass source control folder
2872 if dir.lower() in [".svn", "_svn", "cvs"]:
2876 ext
= os
.path
.splitext(file)[1]
2877 if ext
.lower() == ".py": # only check .py files
2878 fd
= os
.stat(os
.path
.join(root
, file))
2879 if timeOfToolModified
< fd
.st_mtime
:
2880 timeOfToolModified
= fd
.st_mtime
2881 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2882 EdkLogger
.verbose("\nWorkspace database is out of data!")
2887 ## Initialize build database
2888 def InitDatabase(self
):
2889 EdkLogger
.verbose("\nInitialize build database started ...")
2894 self
.TblDataModel
.Create(False)
2895 self
.TblFile
.Create(False)
2898 # Initialize table DataModel
2900 self
.TblDataModel
.InitTable()
2901 EdkLogger
.verbose("Initialize build database ... DONE!")
2905 # @param Table: The instance of the table to be queried
2907 def QueryTable(self
, Table
):
2913 ## Close entire database
2916 # Close the connection and cursor
2919 if not self
._DbClosedFlag
:
2923 self
._DbClosedFlag
= True
2925 ## Summarize all packages in the database
2926 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2927 self
.Platform
= Platform
2929 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2931 # Get Package related to Modules
2933 for Module
in Pa
.Modules
:
2934 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2935 for Package
in ModuleObj
.Packages
:
2936 if Package
not in PackageList
:
2937 PackageList
.append(Package
)
2939 # Get Packages related to Libraries
2941 for Lib
in Pa
.LibraryInstances
:
2942 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2943 for Package
in LibObj
.Packages
:
2944 if Package
not in PackageList
:
2945 PackageList
.append(Package
)
2949 ## Summarize all platforms in the database
2950 def _GetPlatformList(self
):
2952 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2954 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2957 if Platform
!= None:
2958 PlatformList
.append(Platform
)
2961 PlatformList
= property(_GetPlatformList
)
2965 # This acts like the main() function for the script, unless it is 'import'ed into another
2968 if __name__
== '__main__':