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
24 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
26 from Common
.String
import *
27 from Common
.DataType
import *
28 from Common
.Misc
import *
31 from CommonDataClass
.CommonClass
import SkuInfoClass
33 from MetaDataTable
import *
34 from MetaFileTable
import *
35 from MetaFileParser
import *
36 from BuildClassObject
import *
37 from WorkspaceCommon
import GetDeclaredPcd
38 from Common
.Misc
import AnalyzeDscPcd
39 from Common
.Misc
import ProcessDuplicatedInf
41 from Common
.Parsing
import IsValidWord
42 from Common
.VariableAttributes
import VariableAttributes
43 import Common
.GlobalData
as GlobalData
45 ## Platform build information from DSC file
47 # This class is used to retrieve information stored in database and convert them
48 # into PlatformBuildClassObject form for easier use for AutoGen.
50 class DscBuildData(PlatformBuildClassObject
):
51 # dict used to convert PCD type in database to string used by build tool
53 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
54 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
55 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
56 MODEL_PCD_DYNAMIC
: "Dynamic",
57 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
58 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
59 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
60 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
61 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
62 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
63 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
66 # dict used to convert part of [Defines] to members of DscBuildData directly
71 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
72 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
73 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
74 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
75 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
76 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
77 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
78 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
79 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
80 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
81 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
82 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
83 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
84 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
85 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
88 # used to compose dummy library class name for those forced library instances
89 _NullLibraryNumber
= 0
91 ## Constructor of DscBuildData
93 # Initialize object of DscBuildData
95 # @param FilePath The path of platform description file
96 # @param RawData The raw data of DSC file
97 # @param BuildDataBase Database used to retrieve module/package information
98 # @param Arch The target architecture
99 # @param Platform (not used for DscBuildData)
100 # @param Macros Macros used for replacement in DSC file
102 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
103 self
.MetaFile
= FilePath
104 self
._RawData
= RawData
105 self
._Bdb
= BuildDataBase
107 self
._Target
= Target
108 self
._Toolchain
= Toolchain
110 self
._HandleOverridePath
()
113 def __setitem__(self
, key
, value
):
114 self
.__dict
__[self
._PROPERTY
_[key
]] = value
117 def __getitem__(self
, key
):
118 return self
.__dict
__[self
._PROPERTY
_[key
]]
121 def __contains__(self
, key
):
122 return key
in self
._PROPERTY
_
124 ## Set all internal used members of DscBuildData to None
127 self
._PlatformName
= None
130 self
._DscSpecification
= None
131 self
._OutputDirectory
= None
132 self
._SupArchList
= None
133 self
._BuildTargets
= None
135 self
._SkuIdentifier
= None
136 self
._AvilableSkuIds
= None
137 self
._PcdInfoFlag
= None
138 self
._VarCheckFlag
= None
139 self
._FlashDefinition
= None
140 self
._BuildNumber
= None
141 self
._MakefileName
= None
142 self
._BsBaseAddress
= None
143 self
._RtBaseAddress
= None
146 self
._LibraryInstances
= None
147 self
._LibraryClasses
= None
150 self
._BuildOptions
= None
151 self
._ModuleTypeOptions
= None
152 self
._LoadFixAddress
= None
153 self
._RFCLanguages
= None
154 self
._ISOLanguages
= None
155 self
._VpdToolGuid
= None
159 ## handle Override Path of Module
160 def _HandleOverridePath(self
):
161 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
162 Macros
= self
._Macros
163 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
164 for Record
in RecordList
:
167 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
168 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
170 SourceOverridePath
= mws
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
172 # Check if the source override path exists
173 if not os
.path
.isdir(SourceOverridePath
):
174 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
176 #Add to GlobalData Variables
177 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
179 ## Get current effective macros
180 def _GetMacros(self
):
181 if self
.__Macros
== None:
183 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
184 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
185 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
194 # Changing the default ARCH to another may affect all other information
195 # because all information in a platform may be ARCH-related. That's
196 # why we need to clear all internal used members, in order to cause all
197 # information to be re-retrieved.
199 # @param Value The value of ARCH
201 def _SetArch(self
, Value
):
202 if self
._Arch
== Value
:
207 ## Retrieve all information in [Defines] section
209 # (Retriving all [Defines] information in one-shot is just to save time.)
211 def _GetHeaderInfo(self
):
212 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
213 for Record
in RecordList
:
215 # items defined _PROPERTY_ don't need additional processing
217 # some special items in [Defines] section need special treatment
218 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
219 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
220 if ' ' in self
._OutputDirectory
:
221 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
222 File
=self
.MetaFile
, Line
=Record
[-1],
223 ExtraData
=self
._OutputDirectory
)
224 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
225 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
226 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
228 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
230 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
231 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
232 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
233 self
._BuildTargets
= GetSplitValueList(Record
[2])
234 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
235 if self
._SkuName
== None:
236 self
._SkuName
= Record
[2]
237 self
._SkuIdentifier
= Record
[2]
238 self
._AvilableSkuIds
= Record
[2]
239 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
240 self
._PcdInfoFlag
= Record
[2]
241 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
242 self
._VarCheckFlag
= Record
[2]
243 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
245 self
._LoadFixAddress
= int (Record
[2], 0)
247 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
248 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
249 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
250 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"',
251 File
=self
.MetaFile
, Line
=Record
[-1])
252 LanguageCodes
= Record
[2][1:-1]
253 if not LanguageCodes
:
254 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
255 File
=self
.MetaFile
, Line
=Record
[-1])
256 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
257 # check whether there is empty entries in the list
258 if None in LanguageList
:
259 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
260 File
=self
.MetaFile
, Line
=Record
[-1])
261 self
._RFCLanguages
= LanguageList
262 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
263 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
264 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
265 File
=self
.MetaFile
, Line
=Record
[-1])
266 LanguageCodes
= Record
[2][1:-1]
267 if not LanguageCodes
:
268 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
269 File
=self
.MetaFile
, Line
=Record
[-1])
270 if len(LanguageCodes
)%3:
271 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
272 File
=self
.MetaFile
, Line
=Record
[-1])
274 for i
in range(0, len(LanguageCodes
), 3):
275 LanguageList
.append(LanguageCodes
[i
:i
+3])
276 self
._ISOLanguages
= LanguageList
277 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
279 # try to convert GUID to a real UUID value to see whether the GUID is format
280 # for VPD_TOOL_GUID is correct.
285 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
286 self
._VpdToolGuid
= Record
[2]
288 self
[Name
] = Record
[2]
289 # set _Header to non-None in order to avoid database re-querying
290 self
._Header
= 'DUMMY'
292 ## Retrieve platform name
293 def _GetPlatformName(self
):
294 if self
._PlatformName
== None:
295 if self
._Header
== None:
296 self
._GetHeaderInfo
()
297 if self
._PlatformName
== None:
298 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
299 return self
._PlatformName
301 ## Retrieve file guid
302 def _GetFileGuid(self
):
303 if self
._Guid
== None:
304 if self
._Header
== None:
305 self
._GetHeaderInfo
()
306 if self
._Guid
== None:
307 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
310 ## Retrieve platform version
311 def _GetVersion(self
):
312 if self
._Version
== None:
313 if self
._Header
== None:
314 self
._GetHeaderInfo
()
315 if self
._Version
== None:
316 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
319 ## Retrieve platform description file version
320 def _GetDscSpec(self
):
321 if self
._DscSpecification
== None:
322 if self
._Header
== None:
323 self
._GetHeaderInfo
()
324 if self
._DscSpecification
== None:
325 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
326 return self
._DscSpecification
328 ## Retrieve OUTPUT_DIRECTORY
329 def _GetOutpuDir(self
):
330 if self
._OutputDirectory
== None:
331 if self
._Header
== None:
332 self
._GetHeaderInfo
()
333 if self
._OutputDirectory
== None:
334 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
335 return self
._OutputDirectory
337 ## Retrieve SUPPORTED_ARCHITECTURES
338 def _GetSupArch(self
):
339 if self
._SupArchList
== None:
340 if self
._Header
== None:
341 self
._GetHeaderInfo
()
342 if self
._SupArchList
== None:
343 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
344 return self
._SupArchList
346 ## Retrieve BUILD_TARGETS
347 def _GetBuildTarget(self
):
348 if self
._BuildTargets
== None:
349 if self
._Header
== None:
350 self
._GetHeaderInfo
()
351 if self
._BuildTargets
== None:
352 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
353 return self
._BuildTargets
355 def _GetPcdInfoFlag(self
):
356 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
358 elif self
._PcdInfoFlag
.upper() == 'TRUE':
362 def _GetVarCheckFlag(self
):
363 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
365 elif self
._VarCheckFlag
.upper() == 'TRUE':
369 def _GetAviableSkuIds(self
):
370 if self
._AvilableSkuIds
:
371 return self
._AvilableSkuIds
372 return self
.SkuIdentifier
373 def _GetSkuIdentifier(self
):
376 if self
._SkuIdentifier
== None:
377 if self
._Header
== None:
378 self
._GetHeaderInfo
()
379 return self
._SkuIdentifier
380 ## Retrieve SKUID_IDENTIFIER
381 def _GetSkuName(self
):
382 if self
._SkuName
== None:
383 if self
._Header
== None:
384 self
._GetHeaderInfo
()
385 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
386 self
._SkuName
= 'DEFAULT'
389 ## Override SKUID_IDENTIFIER
390 def _SetSkuName(self
, Value
):
391 self
._SkuName
= Value
394 def _GetFdfFile(self
):
395 if self
._FlashDefinition
== None:
396 if self
._Header
== None:
397 self
._GetHeaderInfo
()
398 if self
._FlashDefinition
== None:
399 self
._FlashDefinition
= ''
400 return self
._FlashDefinition
402 ## Retrieve FLASH_DEFINITION
403 def _GetBuildNumber(self
):
404 if self
._BuildNumber
== None:
405 if self
._Header
== None:
406 self
._GetHeaderInfo
()
407 if self
._BuildNumber
== None:
408 self
._BuildNumber
= ''
409 return self
._BuildNumber
411 ## Retrieve MAKEFILE_NAME
412 def _GetMakefileName(self
):
413 if self
._MakefileName
== None:
414 if self
._Header
== None:
415 self
._GetHeaderInfo
()
416 if self
._MakefileName
== None:
417 self
._MakefileName
= ''
418 return self
._MakefileName
420 ## Retrieve BsBaseAddress
421 def _GetBsBaseAddress(self
):
422 if self
._BsBaseAddress
== None:
423 if self
._Header
== None:
424 self
._GetHeaderInfo
()
425 if self
._BsBaseAddress
== None:
426 self
._BsBaseAddress
= ''
427 return self
._BsBaseAddress
429 ## Retrieve RtBaseAddress
430 def _GetRtBaseAddress(self
):
431 if self
._RtBaseAddress
== None:
432 if self
._Header
== None:
433 self
._GetHeaderInfo
()
434 if self
._RtBaseAddress
== None:
435 self
._RtBaseAddress
= ''
436 return self
._RtBaseAddress
438 ## Retrieve the top address for the load fix address
439 def _GetLoadFixAddress(self
):
440 if self
._LoadFixAddress
== None:
441 if self
._Header
== None:
442 self
._GetHeaderInfo
()
444 if self
._LoadFixAddress
== None:
445 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
448 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
450 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
453 # If command line defined, should override the value in DSC file.
455 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
457 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
459 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']))
461 if self
._LoadFixAddress
< 0:
462 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
463 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
464 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
466 return self
._LoadFixAddress
468 ## Retrieve RFCLanguage filter
469 def _GetRFCLanguages(self
):
470 if self
._RFCLanguages
== None:
471 if self
._Header
== None:
472 self
._GetHeaderInfo
()
473 if self
._RFCLanguages
== None:
474 self
._RFCLanguages
= []
475 return self
._RFCLanguages
477 ## Retrieve ISOLanguage filter
478 def _GetISOLanguages(self
):
479 if self
._ISOLanguages
== None:
480 if self
._Header
== None:
481 self
._GetHeaderInfo
()
482 if self
._ISOLanguages
== None:
483 self
._ISOLanguages
= []
484 return self
._ISOLanguages
485 ## Retrieve the GUID string for VPD tool
486 def _GetVpdToolGuid(self
):
487 if self
._VpdToolGuid
== None:
488 if self
._Header
== None:
489 self
._GetHeaderInfo
()
490 if self
._VpdToolGuid
== None:
491 self
._VpdToolGuid
= ''
492 return self
._VpdToolGuid
494 ## Retrieve [SkuIds] section information
495 def _GetSkuIds(self
):
496 if self
._SkuIds
== None:
497 self
._SkuIds
= sdict()
498 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
499 for Record
in RecordList
:
500 if Record
[0] in [None, '']:
501 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
502 File
=self
.MetaFile
, Line
=Record
[-1])
503 if Record
[1] in [None, '']:
504 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
505 File
=self
.MetaFile
, Line
=Record
[-1])
506 self
._SkuIds
[Record
[1]] = Record
[0]
507 if 'DEFAULT' not in self
._SkuIds
:
508 self
._SkuIds
['DEFAULT'] = '0'
509 if 'COMMON' not in self
._SkuIds
:
510 self
._SkuIds
['COMMON'] = '0'
513 ## Retrieve [Components] section information
514 def _GetModules(self
):
515 if self
._Modules
!= None:
518 self
._Modules
= sdict()
519 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
520 Macros
= self
._Macros
521 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
522 for Record
in RecordList
:
523 DuplicatedFile
= False
524 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
528 # check the file validation
529 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
531 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
534 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
535 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
536 DuplicatedFile
= True
538 Module
= ModuleBuildClassObject()
539 Module
.MetaFile
= ModuleFile
541 # get module private library instance
542 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
543 for Record
in RecordList
:
544 LibraryClass
= Record
[0]
545 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
548 # check the file validation
549 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
551 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
554 if LibraryClass
== '' or LibraryClass
== 'NULL':
555 self
._NullLibraryNumber
+= 1
556 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
557 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
558 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
559 if LibraryPath
not in self
.LibraryInstances
:
560 self
.LibraryInstances
.append(LibraryPath
)
562 # get module private PCD setting
563 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
564 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
565 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
566 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
567 TokenList
= GetSplitValueList(Setting
)
568 DefaultValue
= TokenList
[0]
569 if len(TokenList
) > 1:
570 MaxDatumSize
= TokenList
[1]
573 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
574 Pcd
= PcdClassObject(
586 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
588 # get module private build options
589 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
590 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
591 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
592 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
594 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
595 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
597 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
598 if DuplicatedFile
and not RecordList
:
599 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
601 if len(RecordList
) != 1:
602 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
603 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
604 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
605 ModuleFile
.Arch
= self
._Arch
607 self
._Modules
[ModuleFile
] = Module
610 ## Retrieve all possible library instances used in this platform
611 def _GetLibraryInstances(self
):
612 if self
._LibraryInstances
== None:
613 self
._GetLibraryClasses
()
614 return self
._LibraryInstances
616 ## Retrieve [LibraryClasses] information
617 def _GetLibraryClasses(self
):
618 if self
._LibraryClasses
== None:
619 self
._LibraryInstances
= []
621 # tdict is a special dict kind of type, used for selecting correct
622 # library instance for given library class and module type
624 LibraryClassDict
= tdict(True, 3)
625 # track all library class names
626 LibraryClassSet
= set()
627 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
628 Macros
= self
._Macros
629 for Record
in RecordList
:
630 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
631 if LibraryClass
== '' or LibraryClass
== 'NULL':
632 self
._NullLibraryNumber
+= 1
633 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
634 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
635 LibraryClassSet
.add(LibraryClass
)
636 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
637 # check the file validation
638 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
640 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
643 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
644 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
645 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
646 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
647 if LibraryInstance
not in self
._LibraryInstances
:
648 self
._LibraryInstances
.append(LibraryInstance
)
650 # resolve the specific library instance for each class and each module type
651 self
._LibraryClasses
= tdict(True)
652 for LibraryClass
in LibraryClassSet
:
653 # try all possible module types
654 for ModuleType
in SUP_MODULE_LIST
:
655 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
656 if LibraryInstance
== None:
658 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
660 # for Edk style library instances, which are listed in different section
661 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
662 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
663 for Record
in RecordList
:
664 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
666 # check the file validation
667 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
669 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
671 if File
not in self
._LibraryInstances
:
672 self
._LibraryInstances
.append(File
)
674 # we need the module name as the library class name, so we have
675 # to parse it here. (self._Bdb[] will trigger a file parse if it
676 # hasn't been parsed)
678 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
679 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
680 return self
._LibraryClasses
682 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
683 if self
._DecPcds
== None:
684 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
686 if GlobalData
.gFdfParser
:
687 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
690 for Inf
in FdfInfList
:
691 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
692 if ModuleFile
in self
._Modules
:
694 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
695 PkgSet
.update(ModuleData
.Packages
)
699 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
700 self
._DecPcds
.update(DecPcds
)
702 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
703 EdkLogger
.error('build', PARSER_ERROR
,
704 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
705 File
=self
.MetaFile
, Line
=LineNo
)
706 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
707 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
708 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
709 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
710 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
712 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
713 except WrnExpression
, Value
:
714 ValueList
[Index
] = Value
.result
715 except EvaluationException
, Excpt
:
716 if hasattr(Excpt
, 'Pcd'):
717 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
718 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
719 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
720 " of the DSC file" % Excpt
.Pcd
,
721 File
=self
.MetaFile
, Line
=LineNo
)
723 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
724 File
=self
.MetaFile
, Line
=LineNo
)
726 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
727 File
=self
.MetaFile
, Line
=LineNo
)
728 if ValueList
[Index
] == 'True':
729 ValueList
[Index
] = '1'
730 elif ValueList
[Index
] == 'False':
731 ValueList
[Index
] = '0'
733 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
735 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
736 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
739 ## Retrieve all PCD settings in platform
741 if self
._Pcds
== None:
743 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
744 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
745 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
746 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
747 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
748 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
749 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
750 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
751 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
754 ## Retrieve [BuildOptions]
755 def _GetBuildOptions(self
):
756 if self
._BuildOptions
== None:
757 self
._BuildOptions
= sdict()
759 # Retrieve build option for EDKII and EDK style module
761 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
762 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
763 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
764 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
766 # Only flags can be appended
768 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
769 self
._BuildOptions
[CurKey
] = Option
771 self
._BuildOptions
[CurKey
] += ' ' + Option
772 return self
._BuildOptions
774 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
775 if self
._ModuleTypeOptions
== None:
776 self
._ModuleTypeOptions
= sdict()
777 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
779 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
780 DriverType
= '%s.%s' % (Edk
, ModuleType
)
781 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, DriverType
]
782 for ToolChainFamily
, ToolChain
, Option
, Arch
, Type
, Dummy3
, Dummy4
in RecordList
:
783 if Type
== DriverType
:
784 Key
= (ToolChainFamily
, ToolChain
, Edk
)
785 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
786 options
[Key
] = Option
788 options
[Key
] += ' ' + Option
789 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
791 ## Retrieve non-dynamic PCD settings
793 # @param Type PCD type
795 # @retval a dict object contains settings of given PCD type
797 def _GetPcd(self
, Type
):
800 # tdict is a special dict kind of type, used for selecting correct
801 # PCD settings for certain ARCH
804 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
806 PcdDict
= tdict(True, 3)
808 # Find out all possible PCD candidates for self._Arch
809 RecordList
= self
._RawData
[Type
, self
._Arch
]
810 PcdValueDict
= sdict()
811 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
812 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
813 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
814 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
816 #handle pcd value override
817 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
818 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
821 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
822 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
823 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
825 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
827 PcdsKeys
= PcdValueDict
.keys()
828 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
830 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
834 if 'COMMON' in PcdSetting
:
835 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
836 if 'DEFAULT' in PcdSetting
:
837 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
838 if SkuObj
.SystemSkuId
in PcdSetting
:
839 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
841 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
844 self
._PCD
_TYPE
_STRING
_[Type
],
855 ## Retrieve dynamic PCD settings
857 # @param Type PCD type
859 # @retval a dict object contains settings of given PCD type
861 def _GetDynamicPcd(self
, Type
):
863 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
867 # tdict is a special dict kind of type, used for selecting correct
868 # PCD settings for certain ARCH and SKU
870 PcdDict
= tdict(True, 4)
872 # Find out all possible PCD candidates for self._Arch
873 RecordList
= self
._RawData
[Type
, self
._Arch
]
874 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
876 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
877 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
878 if SkuName
not in AvailableSkuIdSet
:
881 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
882 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
883 # Remove redundant PCD candidates, per the ARCH and SKU
884 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
886 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
890 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
891 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
892 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
893 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
894 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
895 if MaxDatumSize
.strip():
896 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
899 if pcdObject
.MaxDatumSize
:
900 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
903 if CurrentMaxSize
> PcdMaxSize
:
904 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
906 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
909 self
._PCD
_TYPE
_STRING
_[Type
],
919 for pcd
in Pcds
.values():
920 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
921 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
922 valuefromDec
= pcdDecObject
.DefaultValue
923 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
924 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
925 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
926 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
927 del(pcd
.SkuInfoList
['COMMON'])
928 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
929 del(pcd
.SkuInfoList
['COMMON'])
930 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
931 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
932 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
933 del(pcd
.SkuInfoList
['DEFAULT'])
937 def CompareVarAttr(self
, Attr1
, Attr2
):
938 if not Attr1
or not Attr2
: # for empty string
940 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
941 Attr1Set
= set(Attr1s
)
942 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
943 Attr2Set
= set(Attr2s
)
944 if Attr2Set
== Attr1Set
:
948 ## Retrieve dynamic HII PCD settings
950 # @param Type PCD type
952 # @retval a dict object contains settings of given PCD type
954 def _GetDynamicHiiPcd(self
, Type
):
956 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
961 # tdict is a special dict kind of type, used for selecting correct
962 # PCD settings for certain ARCH and SKU
964 PcdDict
= tdict(True, 4)
966 RecordList
= self
._RawData
[Type
, self
._Arch
]
967 # Find out all possible PCD candidates for self._Arch
968 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
970 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
971 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
972 if SkuName
not in AvailableSkuIdSet
:
974 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
975 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
976 # Remove redundant PCD candidates, per the ARCH and SKU
977 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
979 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
982 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
984 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
986 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
987 ExtraData
= "[%s]" % VarAttribute
)
990 if VariableOffset
.isdigit():
991 if int(VariableOffset
,10) > 0xFFFF:
993 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
994 if int(VariableOffset
,16) > 0xFFFF:
996 # For Offset written in "A.B"
997 elif VariableOffset
.find('.') > -1:
998 VariableOffsetList
= VariableOffset
.split(".")
999 if not (len(VariableOffsetList
) == 2
1000 and IsValidWord(VariableOffsetList
[0])
1001 and IsValidWord(VariableOffsetList
[1])):
1002 FormatCorrect
= False
1004 FormatCorrect
= False
1005 if not FormatCorrect
:
1006 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1009 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1010 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1011 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1013 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1014 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
)]))
1016 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
= VarAttribute
)
1017 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1018 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1019 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1020 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1022 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1025 self
._PCD
_TYPE
_STRING
_[Type
],
1030 {SkuName
: SkuInfo
},
1033 pcdDecObject
.validateranges
,
1034 pcdDecObject
.validlists
,
1035 pcdDecObject
.expressions
1039 for pcd
in Pcds
.values():
1040 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1041 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1042 # Only fix the value while no value provided in DSC file.
1043 for sku
in pcd
.SkuInfoList
.values():
1044 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
1045 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1046 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1047 valuefromDec
= pcdDecObject
.DefaultValue
1048 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
1049 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1050 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1051 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1052 del(pcd
.SkuInfoList
['COMMON'])
1053 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1054 del(pcd
.SkuInfoList
['COMMON'])
1056 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1057 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1058 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1059 del(pcd
.SkuInfoList
['DEFAULT'])
1062 if pcd
.MaxDatumSize
.strip():
1063 MaxSize
= int(pcd
.MaxDatumSize
,0)
1066 if pcdDecObject
.DatumType
== 'VOID*':
1067 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1069 if skuobj
.HiiDefaultValue
.startswith("L"):
1070 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
1071 elif skuobj
.HiiDefaultValue
.startswith("{"):
1072 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1074 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
1077 pcd
.MaxDatumSize
= str(MaxSize
)
1080 ## Retrieve dynamic VPD PCD settings
1082 # @param Type PCD type
1084 # @retval a dict object contains settings of given PCD type
1086 def _GetDynamicVpdPcd(self
, Type
):
1088 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
1092 # tdict is a special dict kind of type, used for selecting correct
1093 # PCD settings for certain ARCH and SKU
1095 PcdDict
= tdict(True, 4)
1097 # Find out all possible PCD candidates for self._Arch
1098 RecordList
= self
._RawData
[Type
, self
._Arch
]
1099 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1101 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1102 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1103 if SkuName
not in AvailableSkuIdSet
:
1106 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1107 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1108 # Remove redundant PCD candidates, per the ARCH and SKU
1109 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1110 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1114 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1115 # For the Integer & Boolean type, the optional data can only be InitialValue.
1116 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1117 # until the DEC parser has been called.
1119 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1120 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1121 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1122 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1123 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1124 if MaxDatumSize
.strip():
1125 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1128 if pcdObject
.MaxDatumSize
:
1129 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1132 if CurrentMaxSize
> PcdMaxSize
:
1133 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1135 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1138 self
._PCD
_TYPE
_STRING
_[Type
],
1143 {SkuName
: SkuInfo
},
1147 for pcd
in Pcds
.values():
1148 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1149 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1150 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1151 valuefromDec
= pcdDecObject
.DefaultValue
1152 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1153 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1154 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1155 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1156 del(pcd
.SkuInfoList
['COMMON'])
1157 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1158 del(pcd
.SkuInfoList
['COMMON'])
1159 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1160 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1161 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1162 del(pcd
.SkuInfoList
['DEFAULT'])
1166 ## Add external modules
1168 # The external modules are mostly those listed in FDF file, which don't
1171 # @param FilePath The path of module description file
1173 def AddModule(self
, FilePath
):
1174 FilePath
= NormPath(FilePath
)
1175 if FilePath
not in self
.Modules
:
1176 Module
= ModuleBuildClassObject()
1177 Module
.MetaFile
= FilePath
1178 self
.Modules
.append(Module
)
1180 ## Add external PCDs
1182 # The external PCDs are mostly those listed in FDF file to specify address
1183 # or offset information.
1185 # @param Name Name of the PCD
1186 # @param Guid Token space guid of the PCD
1187 # @param Value Value of the PCD
1189 def AddPcd(self
, Name
, Guid
, Value
):
1190 if (Name
, Guid
) not in self
.Pcds
:
1191 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1192 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1194 _Macros
= property(_GetMacros
)
1195 Arch
= property(_GetArch
, _SetArch
)
1196 Platform
= property(_GetPlatformName
)
1197 PlatformName
= property(_GetPlatformName
)
1198 Guid
= property(_GetFileGuid
)
1199 Version
= property(_GetVersion
)
1200 DscSpecification
= property(_GetDscSpec
)
1201 OutputDirectory
= property(_GetOutpuDir
)
1202 SupArchList
= property(_GetSupArch
)
1203 BuildTargets
= property(_GetBuildTarget
)
1204 SkuName
= property(_GetSkuName
, _SetSkuName
)
1205 SkuIdentifier
= property(_GetSkuIdentifier
)
1206 AvilableSkuIds
= property(_GetAviableSkuIds
)
1207 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1208 VarCheckFlag
= property(_GetVarCheckFlag
)
1209 FlashDefinition
= property(_GetFdfFile
)
1210 BuildNumber
= property(_GetBuildNumber
)
1211 MakefileName
= property(_GetMakefileName
)
1212 BsBaseAddress
= property(_GetBsBaseAddress
)
1213 RtBaseAddress
= property(_GetRtBaseAddress
)
1214 LoadFixAddress
= property(_GetLoadFixAddress
)
1215 RFCLanguages
= property(_GetRFCLanguages
)
1216 ISOLanguages
= property(_GetISOLanguages
)
1217 VpdToolGuid
= property(_GetVpdToolGuid
)
1218 SkuIds
= property(_GetSkuIds
)
1219 Modules
= property(_GetModules
)
1220 LibraryInstances
= property(_GetLibraryInstances
)
1221 LibraryClasses
= property(_GetLibraryClasses
)
1222 Pcds
= property(_GetPcds
)
1223 BuildOptions
= property(_GetBuildOptions
)
1225 ## Platform build information from DEC file
1227 # This class is used to retrieve information stored in database and convert them
1228 # into PackageBuildClassObject form for easier use for AutoGen.
1230 class DecBuildData(PackageBuildClassObject
):
1231 # dict used to convert PCD type in database to string used by build tool
1232 _PCD_TYPE_STRING_
= {
1233 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1234 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1235 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1236 MODEL_PCD_DYNAMIC
: "Dynamic",
1237 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1238 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1239 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1240 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1241 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1242 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1243 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1246 # dict used to convert part of [Defines] to members of DecBuildData directly
1251 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1252 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1253 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1254 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1258 ## Constructor of DecBuildData
1260 # Initialize object of DecBuildData
1262 # @param FilePath The path of package description file
1263 # @param RawData The raw data of DEC file
1264 # @param BuildDataBase Database used to retrieve module information
1265 # @param Arch The target architecture
1266 # @param Platform (not used for DecBuildData)
1267 # @param Macros Macros used for replacement in DSC file
1269 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1270 self
.MetaFile
= File
1271 self
._PackageDir
= File
.Dir
1272 self
._RawData
= RawData
1273 self
._Bdb
= BuildDataBase
1275 self
._Target
= Target
1276 self
._Toolchain
= Toolchain
1280 def __setitem__(self
, key
, value
):
1281 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1284 def __getitem__(self
, key
):
1285 return self
.__dict
__[self
._PROPERTY
_[key
]]
1287 ## "in" test support
1288 def __contains__(self
, key
):
1289 return key
in self
._PROPERTY
_
1291 ## Set all internal used members of DecBuildData to None
1294 self
._PackageName
= None
1296 self
._Version
= None
1297 self
._PkgUniFile
= None
1298 self
._Protocols
= None
1301 self
._Includes
= None
1302 self
._LibraryClasses
= None
1304 self
.__Macros
= None
1306 ## Get current effective macros
1307 def _GetMacros(self
):
1308 if self
.__Macros
== None:
1310 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1311 return self
.__Macros
1319 # Changing the default ARCH to another may affect all other information
1320 # because all information in a platform may be ARCH-related. That's
1321 # why we need to clear all internal used members, in order to cause all
1322 # information to be re-retrieved.
1324 # @param Value The value of ARCH
1326 def _SetArch(self
, Value
):
1327 if self
._Arch
== Value
:
1332 ## Retrieve all information in [Defines] section
1334 # (Retriving all [Defines] information in one-shot is just to save time.)
1336 def _GetHeaderInfo(self
):
1337 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1338 for Record
in RecordList
:
1341 self
[Name
] = Record
[2]
1342 self
._Header
= 'DUMMY'
1344 ## Retrieve package name
1345 def _GetPackageName(self
):
1346 if self
._PackageName
== None:
1347 if self
._Header
== None:
1348 self
._GetHeaderInfo
()
1349 if self
._PackageName
== None:
1350 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1351 return self
._PackageName
1353 ## Retrieve file guid
1354 def _GetFileGuid(self
):
1355 if self
._Guid
== None:
1356 if self
._Header
== None:
1357 self
._GetHeaderInfo
()
1358 if self
._Guid
== None:
1359 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1362 ## Retrieve package version
1363 def _GetVersion(self
):
1364 if self
._Version
== None:
1365 if self
._Header
== None:
1366 self
._GetHeaderInfo
()
1367 if self
._Version
== None:
1369 return self
._Version
1371 ## Retrieve protocol definitions (name/value pairs)
1372 def _GetProtocol(self
):
1373 if self
._Protocols
== None:
1375 # tdict is a special kind of dict, used for selecting correct
1376 # protocol defition for given ARCH
1378 ProtocolDict
= tdict(True)
1380 # find out all protocol definitions for specific and 'common' arch
1381 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1382 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1383 if Name
not in NameList
:
1384 NameList
.append(Name
)
1385 ProtocolDict
[Arch
, Name
] = Guid
1386 # use sdict to keep the order
1387 self
._Protocols
= sdict()
1388 for Name
in NameList
:
1390 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1391 # will automatically turn to 'common' ARCH for trying
1393 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1394 return self
._Protocols
1396 ## Retrieve PPI definitions (name/value pairs)
1398 if self
._Ppis
== None:
1400 # tdict is a special kind of dict, used for selecting correct
1401 # PPI defition for given ARCH
1403 PpiDict
= tdict(True)
1405 # find out all PPI definitions for specific arch and 'common' arch
1406 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1407 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1408 if Name
not in NameList
:
1409 NameList
.append(Name
)
1410 PpiDict
[Arch
, Name
] = Guid
1411 # use sdict to keep the order
1412 self
._Ppis
= sdict()
1413 for Name
in NameList
:
1415 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1416 # will automatically turn to 'common' ARCH for trying
1418 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1421 ## Retrieve GUID definitions (name/value pairs)
1423 if self
._Guids
== None:
1425 # tdict is a special kind of dict, used for selecting correct
1426 # GUID defition for given ARCH
1428 GuidDict
= tdict(True)
1430 # find out all protocol definitions for specific and 'common' arch
1431 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1432 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1433 if Name
not in NameList
:
1434 NameList
.append(Name
)
1435 GuidDict
[Arch
, Name
] = Guid
1436 # use sdict to keep the order
1437 self
._Guids
= sdict()
1438 for Name
in NameList
:
1440 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1441 # will automatically turn to 'common' ARCH for trying
1443 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1446 ## Retrieve public include paths declared in this package
1447 def _GetInclude(self
):
1448 if self
._Includes
== None:
1450 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1451 Macros
= self
._Macros
1452 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1453 for Record
in RecordList
:
1454 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1457 ErrorCode
, ErrorInfo
= File
.Validate()
1459 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1461 # avoid duplicate include path
1462 if File
not in self
._Includes
:
1463 self
._Includes
.append(File
)
1464 return self
._Includes
1466 ## Retrieve library class declarations (not used in build at present)
1467 def _GetLibraryClass(self
):
1468 if self
._LibraryClasses
== None:
1470 # tdict is a special kind of dict, used for selecting correct
1471 # library class declaration for given ARCH
1473 LibraryClassDict
= tdict(True)
1474 LibraryClassSet
= set()
1475 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1476 Macros
= self
._Macros
1477 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1478 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1479 # check the file validation
1480 ErrorCode
, ErrorInfo
= File
.Validate()
1482 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1483 LibraryClassSet
.add(LibraryClass
)
1484 LibraryClassDict
[Arch
, LibraryClass
] = File
1485 self
._LibraryClasses
= sdict()
1486 for LibraryClass
in LibraryClassSet
:
1487 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1488 return self
._LibraryClasses
1490 ## Retrieve PCD declarations
1492 if self
._Pcds
== None:
1493 self
._Pcds
= sdict()
1494 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1495 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1496 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1497 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1498 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1501 ## Retrieve PCD declarations for given type
1502 def _GetPcd(self
, Type
):
1505 # tdict is a special kind of dict, used for selecting correct
1506 # PCD declaration for given ARCH
1508 PcdDict
= tdict(True, 3)
1509 # for summarizing PCD
1511 # find out all PCDs of the 'type'
1512 RecordList
= self
._RawData
[Type
, self
._Arch
]
1513 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1514 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1515 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1517 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1519 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1520 # will automatically turn to 'common' ARCH and try again
1522 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1526 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1528 validateranges
, validlists
, expressions
= self
._RawData
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
1529 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1532 self
._PCD
_TYPE
_STRING
_[Type
],
1540 list(validateranges
),
1547 _Macros
= property(_GetMacros
)
1548 Arch
= property(_GetArch
, _SetArch
)
1549 PackageName
= property(_GetPackageName
)
1550 Guid
= property(_GetFileGuid
)
1551 Version
= property(_GetVersion
)
1553 Protocols
= property(_GetProtocol
)
1554 Ppis
= property(_GetPpi
)
1555 Guids
= property(_GetGuid
)
1556 Includes
= property(_GetInclude
)
1557 LibraryClasses
= property(_GetLibraryClass
)
1558 Pcds
= property(_GetPcds
)
1560 ## Module build information from INF file
1562 # This class is used to retrieve information stored in database and convert them
1563 # into ModuleBuildClassObject form for easier use for AutoGen.
1565 class InfBuildData(ModuleBuildClassObject
):
1566 # dict used to convert PCD type in database to string used by build tool
1567 _PCD_TYPE_STRING_
= {
1568 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1569 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1570 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1571 MODEL_PCD_DYNAMIC
: "Dynamic",
1572 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1573 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1574 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1575 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1576 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1577 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1578 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1581 # dict used to convert part of [Defines] to members of InfBuildData directly
1586 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1587 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1588 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1592 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1593 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1594 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1595 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1596 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1597 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1598 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1599 TAB_INF_DEFINES_VERSION
: "_Version",
1600 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1601 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1603 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1606 # dict used to convert Component type to Module type
1609 "SECURITY_CORE" : "SEC",
1610 "PEI_CORE" : "PEI_CORE",
1611 "COMBINED_PEIM_DRIVER" : "PEIM",
1612 "PIC_PEIM" : "PEIM",
1613 "RELOCATABLE_PEIM" : "PEIM",
1614 "PE32_PEIM" : "PEIM",
1615 "BS_DRIVER" : "DXE_DRIVER",
1616 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1617 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1618 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1619 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1620 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1621 # "BS_DRIVER" : "UEFI_DRIVER",
1622 "APPLICATION" : "UEFI_APPLICATION",
1626 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1627 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1628 # dict used to convert old tool name used in [nmake] section to new ones
1636 ## Constructor of DscBuildData
1638 # Initialize object of DscBuildData
1640 # @param FilePath The path of platform description file
1641 # @param RawData The raw data of DSC file
1642 # @param BuildDataBase Database used to retrieve module/package information
1643 # @param Arch The target architecture
1644 # @param Platform The name of platform employing this module
1645 # @param Macros Macros used for replacement in DSC file
1647 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1648 self
.MetaFile
= FilePath
1649 self
._ModuleDir
= FilePath
.Dir
1650 self
._RawData
= RawData
1651 self
._Bdb
= BuildDatabase
1653 self
._Target
= Target
1654 self
._Toolchain
= Toolchain
1655 self
._Platform
= 'COMMON'
1656 self
._SourceOverridePath
= None
1657 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1658 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1662 def __setitem__(self
, key
, value
):
1663 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1666 def __getitem__(self
, key
):
1667 return self
.__dict
__[self
._PROPERTY
_[key
]]
1669 ## "in" test support
1670 def __contains__(self
, key
):
1671 return key
in self
._PROPERTY
_
1673 ## Set all internal used members of InfBuildData to None
1675 self
._HeaderComments
= None
1676 self
._TailComments
= None
1677 self
._Header
_ = None
1678 self
._AutoGenVersion
= None
1679 self
._BaseName
= None
1680 self
._DxsFile
= None
1681 self
._ModuleType
= None
1682 self
._ComponentType
= None
1683 self
._BuildType
= None
1685 self
._Version
= None
1686 self
._PcdIsDriver
= None
1687 self
._BinaryModule
= None
1689 self
._MakefileName
= None
1690 self
._CustomMakefile
= None
1691 self
._Specification
= None
1692 self
._LibraryClass
= None
1693 self
._ModuleEntryPointList
= None
1694 self
._ModuleUnloadImageList
= None
1695 self
._ConstructorList
= None
1696 self
._DestructorList
= None
1698 self
._Binaries
= None
1699 self
._Sources
= None
1700 self
._LibraryClasses
= None
1701 self
._Libraries
= None
1702 self
._Protocols
= None
1703 self
._ProtocolComments
= None
1705 self
._PpiComments
= None
1707 self
._GuidsUsedByPcd
= sdict()
1708 self
._GuidComments
= None
1709 self
._Includes
= None
1710 self
._Packages
= None
1712 self
._PcdComments
= None
1713 self
._BuildOptions
= None
1715 self
._DepexExpression
= None
1716 self
.__Macros
= None
1718 ## Get current effective macros
1719 def _GetMacros(self
):
1720 if self
.__Macros
== None:
1722 # EDK_GLOBAL defined macros can be applied to EDK module
1723 if self
.AutoGenVersion
< 0x00010005:
1724 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1725 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1726 return self
.__Macros
1734 # Changing the default ARCH to another may affect all other information
1735 # because all information in a platform may be ARCH-related. That's
1736 # why we need to clear all internal used members, in order to cause all
1737 # information to be re-retrieved.
1739 # @param Value The value of ARCH
1741 def _SetArch(self
, Value
):
1742 if self
._Arch
== Value
:
1747 ## Return the name of platform employing this module
1748 def _GetPlatform(self
):
1749 return self
._Platform
1751 ## Change the name of platform employing this module
1753 # Changing the default name of platform to another may affect some information
1754 # because they may be PLATFORM-related. That's why we need to clear all internal
1755 # used members, in order to cause all information to be re-retrieved.
1757 def _SetPlatform(self
, Value
):
1758 if self
._Platform
== Value
:
1760 self
._Platform
= Value
1762 def _GetHeaderComments(self
):
1763 if not self
._HeaderComments
:
1764 self
._HeaderComments
= []
1765 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1766 for Record
in RecordList
:
1767 self
._HeaderComments
.append(Record
[0])
1768 return self
._HeaderComments
1769 def _GetTailComments(self
):
1770 if not self
._TailComments
:
1771 self
._TailComments
= []
1772 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1773 for Record
in RecordList
:
1774 self
._TailComments
.append(Record
[0])
1775 return self
._TailComments
1776 ## Retrieve all information in [Defines] section
1778 # (Retriving all [Defines] information in one-shot is just to save time.)
1780 def _GetHeaderInfo(self
):
1781 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1782 for Record
in RecordList
:
1783 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1784 # items defined _PROPERTY_ don't need additional processing
1787 if self
._Defs
== None:
1788 self
._Defs
= sdict()
1789 self
._Defs
[Name
] = Value
1790 # some special items in [Defines] section need special treatment
1791 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1792 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1793 Name
= 'UEFI_SPECIFICATION_VERSION'
1794 if self
._Specification
== None:
1795 self
._Specification
= sdict()
1796 self
._Specification
[Name
] = GetHexVerValue(Value
)
1797 if self
._Specification
[Name
] == None:
1798 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1799 "'%s' format is not supported for %s" % (Value
, Name
),
1800 File
=self
.MetaFile
, Line
=Record
[-1])
1801 elif Name
== 'LIBRARY_CLASS':
1802 if self
._LibraryClass
== None:
1803 self
._LibraryClass
= []
1804 ValueList
= GetSplitValueList(Value
)
1805 LibraryClass
= ValueList
[0]
1806 if len(ValueList
) > 1:
1807 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1809 SupModuleList
= SUP_MODULE_LIST
1810 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1811 elif Name
== 'ENTRY_POINT':
1812 if self
._ModuleEntryPointList
== None:
1813 self
._ModuleEntryPointList
= []
1814 self
._ModuleEntryPointList
.append(Value
)
1815 elif Name
== 'UNLOAD_IMAGE':
1816 if self
._ModuleUnloadImageList
== None:
1817 self
._ModuleUnloadImageList
= []
1820 self
._ModuleUnloadImageList
.append(Value
)
1821 elif Name
== 'CONSTRUCTOR':
1822 if self
._ConstructorList
== None:
1823 self
._ConstructorList
= []
1826 self
._ConstructorList
.append(Value
)
1827 elif Name
== 'DESTRUCTOR':
1828 if self
._DestructorList
== None:
1829 self
._DestructorList
= []
1832 self
._DestructorList
.append(Value
)
1833 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1834 TokenList
= GetSplitValueList(Value
)
1835 if self
._CustomMakefile
== None:
1836 self
._CustomMakefile
= {}
1837 if len(TokenList
) < 2:
1838 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1839 self
._CustomMakefile
['GCC'] = TokenList
[0]
1841 if TokenList
[0] not in ['MSFT', 'GCC']:
1842 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1843 "No supported family [%s]" % TokenList
[0],
1844 File
=self
.MetaFile
, Line
=Record
[-1])
1845 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1847 if self
._Defs
== None:
1848 self
._Defs
= sdict()
1849 self
._Defs
[Name
] = Value
1852 # Retrieve information in sections specific to Edk.x modules
1854 if self
.AutoGenVersion
>= 0x00010005:
1855 if not self
._ModuleType
:
1856 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1857 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1858 if self
._ModuleType
not in SUP_MODULE_LIST
:
1859 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1860 for Record
in RecordList
:
1862 if Name
== "MODULE_TYPE":
1865 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1866 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1867 File
=self
.MetaFile
, Line
=LineNo
)
1868 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1869 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1870 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
)
1871 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1872 and 'PCI_CLASS_CODE' in self
._Defs
:
1873 self
._BuildType
= 'UEFI_OPTIONROM'
1874 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1875 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1876 self
._BuildType
= 'UEFI_HII'
1878 self
._BuildType
= self
._ModuleType
.upper()
1881 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1882 # check the file validation
1883 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1885 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1886 File
=self
.MetaFile
, Line
=LineNo
)
1887 if self
.Sources
== None:
1889 self
._Sources
.append(File
)
1891 if not self
._ComponentType
:
1892 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1893 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1894 self
._BuildType
= self
._ComponentType
.upper()
1895 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1896 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1897 if self
._ComponentType
== 'LIBRARY':
1898 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1899 # make use some [nmake] section macros
1900 Macros
= self
._Macros
1901 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1902 Macros
['PROCESSOR'] = self
._Arch
1903 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1904 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1905 Value
= ReplaceMacro(Value
, Macros
, True)
1906 if Name
== "IMAGE_ENTRY_POINT":
1907 if self
._ModuleEntryPointList
== None:
1908 self
._ModuleEntryPointList
= []
1909 self
._ModuleEntryPointList
.append(Value
)
1910 elif Name
== "DPX_SOURCE":
1911 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1912 # check the file validation
1913 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1915 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1916 File
=self
.MetaFile
, Line
=LineNo
)
1917 if self
.Sources
== None:
1919 self
._Sources
.append(File
)
1921 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1922 if len(ToolList
) == 0 or len(ToolList
) != 1:
1924 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1925 # File=self.MetaFile, Line=LineNo)
1927 if self
._BuildOptions
== None:
1928 self
._BuildOptions
= sdict()
1930 if ToolList
[0] in self
._TOOL
_CODE
_:
1931 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1934 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1935 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1936 #ignore not replaced macros in value
1937 ValueList
= GetSplitList(' ' + Value
, '/D')
1938 Dummy
= ValueList
[0]
1939 for Index
in range(1, len(ValueList
)):
1940 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1942 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1943 Value
= Dummy
.strip()
1944 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1945 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1947 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1948 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1949 # set _Header to non-None in order to avoid database re-querying
1950 self
._Header
_ = 'DUMMY'
1952 ## Retrieve file version
1953 def _GetInfVersion(self
):
1954 if self
._AutoGenVersion
== None:
1955 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1956 for Record
in RecordList
:
1957 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1958 if '.' in Record
[2]:
1959 ValueList
= Record
[2].split('.')
1960 Major
= '%04o' % int(ValueList
[0], 0)
1961 Minor
= '%04o' % int(ValueList
[1], 0)
1962 self
._AutoGenVersion
= int('0x' + Major
+ Minor
, 0)
1964 self
._AutoGenVersion
= int(Record
[2], 0)
1966 if self
._AutoGenVersion
== None:
1967 self
._AutoGenVersion
= 0x00010000
1968 return self
._AutoGenVersion
1970 ## Retrieve BASE_NAME
1971 def _GetBaseName(self
):
1972 if self
._BaseName
== None:
1973 if self
._Header
_ == None:
1974 self
._GetHeaderInfo
()
1975 if self
._BaseName
== None:
1976 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1977 return self
._BaseName
1980 def _GetDxsFile(self
):
1981 if self
._DxsFile
== None:
1982 if self
._Header
_ == None:
1983 self
._GetHeaderInfo
()
1984 if self
._DxsFile
== None:
1986 return self
._DxsFile
1988 ## Retrieve MODULE_TYPE
1989 def _GetModuleType(self
):
1990 if self
._ModuleType
== None:
1991 if self
._Header
_ == None:
1992 self
._GetHeaderInfo
()
1993 if self
._ModuleType
== None:
1994 self
._ModuleType
= 'BASE'
1995 if self
._ModuleType
not in SUP_MODULE_LIST
:
1996 self
._ModuleType
= "USER_DEFINED"
1997 return self
._ModuleType
1999 ## Retrieve COMPONENT_TYPE
2000 def _GetComponentType(self
):
2001 if self
._ComponentType
== None:
2002 if self
._Header
_ == None:
2003 self
._GetHeaderInfo
()
2004 if self
._ComponentType
== None:
2005 self
._ComponentType
= 'USER_DEFINED'
2006 return self
._ComponentType
2008 ## Retrieve "BUILD_TYPE"
2009 def _GetBuildType(self
):
2010 if self
._BuildType
== None:
2011 if self
._Header
_ == None:
2012 self
._GetHeaderInfo
()
2013 if not self
._BuildType
:
2014 self
._BuildType
= "BASE"
2015 return self
._BuildType
2017 ## Retrieve file guid
2018 def _GetFileGuid(self
):
2019 if self
._Guid
== None:
2020 if self
._Header
_ == None:
2021 self
._GetHeaderInfo
()
2022 if self
._Guid
== None:
2023 self
._Guid
= '00000000-0000-0000-0000-000000000000'
2026 ## Retrieve module version
2027 def _GetVersion(self
):
2028 if self
._Version
== None:
2029 if self
._Header
_ == None:
2030 self
._GetHeaderInfo
()
2031 if self
._Version
== None:
2032 self
._Version
= '0.0'
2033 return self
._Version
2035 ## Retrieve PCD_IS_DRIVER
2036 def _GetPcdIsDriver(self
):
2037 if self
._PcdIsDriver
== None:
2038 if self
._Header
_ == None:
2039 self
._GetHeaderInfo
()
2040 if self
._PcdIsDriver
== None:
2041 self
._PcdIsDriver
= ''
2042 return self
._PcdIsDriver
2045 def _GetShadow(self
):
2046 if self
._Shadow
== None:
2047 if self
._Header
_ == None:
2048 self
._GetHeaderInfo
()
2049 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
2052 self
._Shadow
= False
2055 ## Retrieve CUSTOM_MAKEFILE
2056 def _GetMakefile(self
):
2057 if self
._CustomMakefile
== None:
2058 if self
._Header
_ == None:
2059 self
._GetHeaderInfo
()
2060 if self
._CustomMakefile
== None:
2061 self
._CustomMakefile
= {}
2062 return self
._CustomMakefile
2064 ## Retrieve EFI_SPECIFICATION_VERSION
2066 if self
._Specification
== None:
2067 if self
._Header
_ == None:
2068 self
._GetHeaderInfo
()
2069 if self
._Specification
== None:
2070 self
._Specification
= {}
2071 return self
._Specification
2073 ## Retrieve LIBRARY_CLASS
2074 def _GetLibraryClass(self
):
2075 if self
._LibraryClass
== None:
2076 if self
._Header
_ == None:
2077 self
._GetHeaderInfo
()
2078 if self
._LibraryClass
== None:
2079 self
._LibraryClass
= []
2080 return self
._LibraryClass
2082 ## Retrieve ENTRY_POINT
2083 def _GetEntryPoint(self
):
2084 if self
._ModuleEntryPointList
== None:
2085 if self
._Header
_ == None:
2086 self
._GetHeaderInfo
()
2087 if self
._ModuleEntryPointList
== None:
2088 self
._ModuleEntryPointList
= []
2089 return self
._ModuleEntryPointList
2091 ## Retrieve UNLOAD_IMAGE
2092 def _GetUnloadImage(self
):
2093 if self
._ModuleUnloadImageList
== None:
2094 if self
._Header
_ == None:
2095 self
._GetHeaderInfo
()
2096 if self
._ModuleUnloadImageList
== None:
2097 self
._ModuleUnloadImageList
= []
2098 return self
._ModuleUnloadImageList
2100 ## Retrieve CONSTRUCTOR
2101 def _GetConstructor(self
):
2102 if self
._ConstructorList
== None:
2103 if self
._Header
_ == None:
2104 self
._GetHeaderInfo
()
2105 if self
._ConstructorList
== None:
2106 self
._ConstructorList
= []
2107 return self
._ConstructorList
2109 ## Retrieve DESTRUCTOR
2110 def _GetDestructor(self
):
2111 if self
._DestructorList
== None:
2112 if self
._Header
_ == None:
2113 self
._GetHeaderInfo
()
2114 if self
._DestructorList
== None:
2115 self
._DestructorList
= []
2116 return self
._DestructorList
2118 ## Retrieve definies other than above ones
2119 def _GetDefines(self
):
2120 if self
._Defs
== None:
2121 if self
._Header
_ == None:
2122 self
._GetHeaderInfo
()
2123 if self
._Defs
== None:
2124 self
._Defs
= sdict()
2127 ## Retrieve binary files
2128 def _GetBinaries(self
):
2129 if self
._Binaries
== None:
2131 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2132 Macros
= self
._Macros
2133 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2134 Macros
['PROCESSOR'] = self
._Arch
2135 for Record
in RecordList
:
2136 FileType
= Record
[0]
2141 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2143 Target
= TokenList
[0]
2144 if len(TokenList
) > 1:
2145 FeatureFlag
= Record
[1:]
2147 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2148 # check the file validation
2149 ErrorCode
, ErrorInfo
= File
.Validate()
2151 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2152 self
._Binaries
.append(File
)
2153 return self
._Binaries
2155 ## Retrieve binary files with error check.
2156 def _GetBinaryFiles(self
):
2157 Binaries
= self
._GetBinaries
()
2158 if GlobalData
.gIgnoreSource
and Binaries
== []:
2159 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2160 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2163 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2164 def _IsSupportedArch(self
):
2165 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2169 ## Retrieve source files
2170 def _GetSourceFiles(self
):
2171 #Ignore all source files in a binary build mode
2172 if GlobalData
.gIgnoreSource
:
2174 return self
._Sources
2176 if self
._Sources
== None:
2178 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2179 Macros
= self
._Macros
2180 for Record
in RecordList
:
2182 ToolChainFamily
= Record
[1]
2184 ToolCode
= Record
[3]
2185 FeatureFlag
= Record
[4]
2186 if self
.AutoGenVersion
< 0x00010005:
2187 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2188 Macros
['PROCESSOR'] = self
._Arch
2189 SourceFile
= NormPath(Record
[0], Macros
)
2190 if SourceFile
[0] == os
.path
.sep
:
2191 SourceFile
= mws
.join(GlobalData
.gWorkspace
, SourceFile
[1:])
2192 # old module source files (Edk)
2193 File
= PathClass(SourceFile
, self
._ModuleDir
, self
._SourceOverridePath
,
2194 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2195 # check the file validation
2196 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2198 if File
.Ext
.lower() == '.h':
2199 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2200 File
=self
.MetaFile
, Line
=LineNo
)
2203 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2205 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2206 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2207 # check the file validation
2208 ErrorCode
, ErrorInfo
= File
.Validate()
2210 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2212 self
._Sources
.append(File
)
2213 return self
._Sources
2215 ## Retrieve library classes employed by this module
2216 def _GetLibraryClassUses(self
):
2217 if self
._LibraryClasses
== None:
2218 self
._LibraryClasses
= sdict()
2219 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2220 for Record
in RecordList
:
2222 Instance
= Record
[1]
2224 Instance
= NormPath(Instance
, self
._Macros
)
2225 self
._LibraryClasses
[Lib
] = Instance
2226 return self
._LibraryClasses
2228 ## Retrieve library names (for Edk.x style of modules)
2229 def _GetLibraryNames(self
):
2230 if self
._Libraries
== None:
2231 self
._Libraries
= []
2232 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2233 for Record
in RecordList
:
2234 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2235 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2236 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2237 if LibraryName
not in self
._Libraries
:
2238 self
._Libraries
.append(LibraryName
)
2239 return self
._Libraries
2241 def _GetProtocolComments(self
):
2242 self
._GetProtocols
()
2243 return self
._ProtocolComments
2244 ## Retrieve protocols consumed/produced by this module
2245 def _GetProtocols(self
):
2246 if self
._Protocols
== None:
2247 self
._Protocols
= sdict()
2248 self
._ProtocolComments
= sdict()
2249 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2250 for Record
in RecordList
:
2252 Value
= ProtocolValue(CName
, self
.Packages
)
2254 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2255 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2256 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2257 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2258 self
._Protocols
[CName
] = Value
2259 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2261 for CmtRec
in CommentRecords
:
2262 Comments
.append(CmtRec
[0])
2263 self
._ProtocolComments
[CName
] = Comments
2264 return self
._Protocols
2266 def _GetPpiComments(self
):
2268 return self
._PpiComments
2269 ## Retrieve PPIs consumed/produced by this module
2271 if self
._Ppis
== None:
2272 self
._Ppis
= sdict()
2273 self
._PpiComments
= sdict()
2274 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2275 for Record
in RecordList
:
2277 Value
= PpiValue(CName
, self
.Packages
)
2279 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2280 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2281 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2282 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2283 self
._Ppis
[CName
] = Value
2284 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2286 for CmtRec
in CommentRecords
:
2287 Comments
.append(CmtRec
[0])
2288 self
._PpiComments
[CName
] = Comments
2291 def _GetGuidComments(self
):
2293 return self
._GuidComments
2294 ## Retrieve GUIDs consumed/produced by this module
2295 def _GetGuids(self
):
2296 if self
._Guids
== None:
2297 self
._Guids
= sdict()
2298 self
._GuidComments
= sdict()
2299 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2300 for Record
in RecordList
:
2302 Value
= GuidValue(CName
, self
.Packages
)
2304 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2305 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2306 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2307 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2308 self
._Guids
[CName
] = Value
2309 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2311 for CmtRec
in CommentRecords
:
2312 Comments
.append(CmtRec
[0])
2313 self
._GuidComments
[CName
] = Comments
2316 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2317 def _GetIncludes(self
):
2318 if self
._Includes
== None:
2320 if self
._SourceOverridePath
:
2321 self
._Includes
.append(self
._SourceOverridePath
)
2323 Macros
= self
._Macros
2324 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2325 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2327 Macros
['PROCESSOR'] = self
._Arch
2328 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2329 for Record
in RecordList
:
2330 if Record
[0].find('EDK_SOURCE') > -1:
2331 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2332 File
= NormPath(Record
[0], self
._Macros
)
2334 File
= os
.path
.join(self
._ModuleDir
, File
)
2336 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2337 File
= RealPath(os
.path
.normpath(File
))
2339 self
._Includes
.append(File
)
2341 #TRICK: let compiler to choose correct header file
2342 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2343 File
= NormPath(Record
[0], self
._Macros
)
2345 File
= os
.path
.join(self
._ModuleDir
, File
)
2347 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2348 File
= RealPath(os
.path
.normpath(File
))
2350 self
._Includes
.append(File
)
2352 File
= NormPath(Record
[0], Macros
)
2354 File
= os
.path
.join(self
._ModuleDir
, File
)
2356 File
= mws
.join(GlobalData
.gWorkspace
, File
)
2357 File
= RealPath(os
.path
.normpath(File
))
2359 self
._Includes
.append(File
)
2360 if not File
and Record
[0].find('EFI_SOURCE') > -1:
2361 # tricky to regard WorkSpace as EFI_SOURCE
2362 Macros
['EFI_SOURCE'] = GlobalData
.gWorkspace
2363 File
= NormPath(Record
[0], Macros
)
2365 File
= os
.path
.join(self
._ModuleDir
, File
)
2367 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2368 File
= RealPath(os
.path
.normpath(File
))
2370 self
._Includes
.append(File
)
2371 return self
._Includes
2373 ## Retrieve packages this module depends on
2374 def _GetPackages(self
):
2375 if self
._Packages
== None:
2377 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2378 Macros
= self
._Macros
2379 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2380 for Record
in RecordList
:
2381 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2383 # check the file validation
2384 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2386 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2387 # parse this package now. we need it to get protocol/ppi/guid value
2388 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2389 self
._Packages
.append(Package
)
2390 return self
._Packages
2392 ## Retrieve PCD comments
2393 def _GetPcdComments(self
):
2395 return self
._PcdComments
2396 ## Retrieve PCDs used in this module
2398 if self
._Pcds
== None:
2399 self
._Pcds
= sdict()
2400 self
._PcdComments
= sdict()
2401 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2402 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2403 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2404 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2405 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2408 ## Retrieve build options specific to this module
2409 def _GetBuildOptions(self
):
2410 if self
._BuildOptions
== None:
2411 self
._BuildOptions
= sdict()
2412 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2413 for Record
in RecordList
:
2414 ToolChainFamily
= Record
[0]
2415 ToolChain
= Record
[1]
2417 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
or Option
.startswith('='):
2418 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2420 # concatenate the option string if they're for the same tool
2421 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2422 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2423 return self
._BuildOptions
2425 ## Retrieve dependency expression
2426 def _GetDepex(self
):
2427 if self
._Depex
== None:
2428 self
._Depex
= tdict(False, 2)
2429 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2431 # If the module has only Binaries and no Sources, then ignore [Depex]
2432 if self
.Sources
== None or self
.Sources
== []:
2433 if self
.Binaries
!= None and self
.Binaries
!= []:
2436 # PEIM and DXE drivers must have a valid [Depex] section
2437 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2438 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2439 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2440 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2441 % self
.ModuleType
, File
=self
.MetaFile
)
2443 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2444 for Record
in RecordList
:
2445 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2446 EdkLogger
.error('build', FORMAT_INVALID
,
2447 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2451 for Record
in RecordList
:
2452 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2454 ModuleType
= Record
[4]
2455 TokenList
= DepexStr
.split()
2456 if (Arch
, ModuleType
) not in Depex
:
2457 Depex
[Arch
, ModuleType
] = []
2458 DepexList
= Depex
[Arch
, ModuleType
]
2459 for Token
in TokenList
:
2460 if Token
in DEPEX_SUPPORTED_OPCODE
:
2461 DepexList
.append(Token
)
2462 elif Token
.endswith(".inf"): # module file name
2463 ModuleFile
= os
.path
.normpath(Token
)
2464 Module
= self
.BuildDatabase
[ModuleFile
]
2466 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2467 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2468 DepexList
.append(Module
.Guid
)
2470 # get the GUID value now
2471 Value
= ProtocolValue(Token
, self
.Packages
)
2473 Value
= PpiValue(Token
, self
.Packages
)
2475 Value
= GuidValue(Token
, self
.Packages
)
2477 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2478 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2479 "Value of [%s] is not found in" % Token
,
2480 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2481 DepexList
.append(Value
)
2482 for Arch
, ModuleType
in Depex
:
2483 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2486 ## Retrieve depedency expression
2487 def _GetDepexExpression(self
):
2488 if self
._DepexExpression
== None:
2489 self
._DepexExpression
= tdict(False, 2)
2490 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2491 DepexExpression
= sdict()
2492 for Record
in RecordList
:
2493 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2495 ModuleType
= Record
[4]
2496 TokenList
= DepexStr
.split()
2497 if (Arch
, ModuleType
) not in DepexExpression
:
2498 DepexExpression
[Arch
, ModuleType
] = ''
2499 for Token
in TokenList
:
2500 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2501 for Arch
, ModuleType
in DepexExpression
:
2502 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2503 return self
._DepexExpression
2505 def GetGuidsUsedByPcd(self
):
2506 return self
._GuidsUsedByPcd
2507 ## Retrieve PCD for given type
2508 def _GetPcd(self
, Type
):
2510 PcdDict
= tdict(True, 4)
2512 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2513 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2514 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2515 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2516 # get the guid value
2517 if TokenSpaceGuid
not in self
.Guids
:
2518 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2520 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2521 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2522 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2523 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2524 self
.Guids
[TokenSpaceGuid
] = Value
2525 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2526 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2528 for CmtRec
in CommentRecords
:
2529 Comments
.append(CmtRec
[0])
2530 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2532 # resolve PCD type, value, datum info, etc. by getting its definition from package
2533 for PcdCName
, TokenSpaceGuid
in PcdList
:
2534 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2537 ValueList
= AnalyzePcdData(Setting
)
2538 DefaultValue
= ValueList
[0]
2539 Pcd
= PcdClassObject(
2549 self
.Guids
[TokenSpaceGuid
]
2551 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2552 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2553 Pcd
.Offset
= ValueList
[1]
2555 # get necessary info from package declaring this PCD
2556 for Package
in self
.Packages
:
2558 # 'dynamic' in INF means its type is determined by platform;
2559 # if platform doesn't give its type, use 'lowest' one in the
2560 # following order, if any
2562 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2564 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2565 if Type
== MODEL_PCD_DYNAMIC
:
2567 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2568 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2574 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2575 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2577 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2580 # Check whether the token value exist or not.
2582 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2586 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2587 File
=self
.MetaFile
, Line
=LineNo
,
2591 # Check hexadecimal token value length and format.
2593 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2594 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2595 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2599 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2600 File
=self
.MetaFile
, Line
=LineNo
,
2605 # Check decimal token value length and format.
2609 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2610 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2614 "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
)),
2615 File
=self
.MetaFile
, Line
=LineNo
,
2622 "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
)),
2623 File
=self
.MetaFile
, Line
=LineNo
,
2627 Pcd
.DatumType
= PcdInPackage
.DatumType
2628 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2629 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2630 if Pcd
.DefaultValue
in [None, '']:
2631 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2637 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2638 File
=self
.MetaFile
, Line
=LineNo
,
2639 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2641 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2645 ## check whether current module is binary module
2646 def _IsBinaryModule(self
):
2647 if self
.Binaries
and not self
.Sources
:
2649 elif GlobalData
.gIgnoreSource
:
2654 _Macros
= property(_GetMacros
)
2655 Arch
= property(_GetArch
, _SetArch
)
2656 Platform
= property(_GetPlatform
, _SetPlatform
)
2658 HeaderComments
= property(_GetHeaderComments
)
2659 TailComments
= property(_GetTailComments
)
2660 AutoGenVersion
= property(_GetInfVersion
)
2661 BaseName
= property(_GetBaseName
)
2662 ModuleType
= property(_GetModuleType
)
2663 ComponentType
= property(_GetComponentType
)
2664 BuildType
= property(_GetBuildType
)
2665 Guid
= property(_GetFileGuid
)
2666 Version
= property(_GetVersion
)
2667 PcdIsDriver
= property(_GetPcdIsDriver
)
2668 Shadow
= property(_GetShadow
)
2669 CustomMakefile
= property(_GetMakefile
)
2670 Specification
= property(_GetSpec
)
2671 LibraryClass
= property(_GetLibraryClass
)
2672 ModuleEntryPointList
= property(_GetEntryPoint
)
2673 ModuleUnloadImageList
= property(_GetUnloadImage
)
2674 ConstructorList
= property(_GetConstructor
)
2675 DestructorList
= property(_GetDestructor
)
2676 Defines
= property(_GetDefines
)
2677 DxsFile
= property(_GetDxsFile
)
2679 Binaries
= property(_GetBinaryFiles
)
2680 Sources
= property(_GetSourceFiles
)
2681 LibraryClasses
= property(_GetLibraryClassUses
)
2682 Libraries
= property(_GetLibraryNames
)
2683 Protocols
= property(_GetProtocols
)
2684 ProtocolComments
= property(_GetProtocolComments
)
2685 Ppis
= property(_GetPpis
)
2686 PpiComments
= property(_GetPpiComments
)
2687 Guids
= property(_GetGuids
)
2688 GuidComments
= property(_GetGuidComments
)
2689 Includes
= property(_GetIncludes
)
2690 Packages
= property(_GetPackages
)
2691 Pcds
= property(_GetPcds
)
2692 PcdComments
= property(_GetPcdComments
)
2693 BuildOptions
= property(_GetBuildOptions
)
2694 Depex
= property(_GetDepex
)
2695 DepexExpression
= property(_GetDepexExpression
)
2696 IsBinaryModule
= property(_IsBinaryModule
)
2697 IsSupportedArch
= property(_IsSupportedArch
)
2701 # This class defined the build database for all modules, packages and platform.
2702 # It will call corresponding parser for the given file if it cannot find it in
2705 # @param DbPath Path of database file
2706 # @param GlobalMacros Global macros used for replacement during file parsing
2707 # @prarm RenewDb=False Create new database file if it's already there
2709 class WorkspaceDatabase(object):
2713 # internal class used for call corresponding file parser and caching the result
2714 # to avoid unnecessary re-parsing
2716 class BuildObjectFactory(object):
2719 ".inf" : MODEL_FILE_INF
,
2720 ".dec" : MODEL_FILE_DEC
,
2721 ".dsc" : MODEL_FILE_DSC
,
2726 MODEL_FILE_INF
: InfParser
,
2727 MODEL_FILE_DEC
: DecParser
,
2728 MODEL_FILE_DSC
: DscParser
,
2731 # convert to xxxBuildData object
2733 MODEL_FILE_INF
: InfBuildData
,
2734 MODEL_FILE_DEC
: DecBuildData
,
2735 MODEL_FILE_DSC
: DscBuildData
,
2738 _CACHE_
= {} # (FilePath, Arch) : <object>
2741 def __init__(self
, WorkspaceDb
):
2742 self
.WorkspaceDb
= WorkspaceDb
2744 # key = (FilePath, Arch=None)
2745 def __contains__(self
, Key
):
2751 return (FilePath
, Arch
) in self
._CACHE
_
2753 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2754 def __getitem__(self
, Key
):
2756 KeyLength
= len(Key
)
2770 # if it's generated before, just return the cached one
2771 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2772 if Key
in self
._CACHE
_:
2773 return self
._CACHE
_[Key
]
2777 if Ext
not in self
._FILE
_TYPE
_:
2779 FileType
= self
._FILE
_TYPE
_[Ext
]
2780 if FileType
not in self
._GENERATOR
_:
2783 # get the parser ready for this file
2784 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2787 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2789 # alwasy do post-process, in case of macros change
2790 MetaFile
.DoPostProcess()
2791 # object the build is based on
2792 BuildObject
= self
._GENERATOR
_[FileType
](
2800 self
._CACHE
_[Key
] = BuildObject
2803 # placeholder for file format conversion
2804 class TransformObjectFactory
:
2805 def __init__(self
, WorkspaceDb
):
2806 self
.WorkspaceDb
= WorkspaceDb
2808 # key = FilePath, Arch
2809 def __getitem__(self
, Key
):
2812 ## Constructor of WorkspaceDatabase
2814 # @param DbPath Path of database file
2815 # @param GlobalMacros Global macros used for replacement during file parsing
2816 # @prarm RenewDb=False Create new database file if it's already there
2818 def __init__(self
, DbPath
, RenewDb
=False):
2819 self
._DbClosedFlag
= False
2821 DbPath
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2823 # don't create necessary path for db in memory
2824 if DbPath
!= ':memory:':
2825 DbDir
= os
.path
.split(DbPath
)[0]
2826 if not os
.path
.exists(DbDir
):
2829 # remove db file in case inconsistency between db and file in file system
2830 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2833 # create db with optimized parameters
2834 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2835 self
.Conn
.execute("PRAGMA synchronous=OFF")
2836 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2837 self
.Conn
.execute("PRAGMA count_changes=OFF")
2838 self
.Conn
.execute("PRAGMA cache_size=8192")
2839 #self.Conn.execute("PRAGMA page_size=8192")
2841 # to avoid non-ascii character conversion issue
2842 self
.Conn
.text_factory
= str
2843 self
.Cur
= self
.Conn
.cursor()
2845 # create table for internal uses
2846 self
.TblDataModel
= TableDataModel(self
.Cur
)
2847 self
.TblFile
= TableFile(self
.Cur
)
2848 self
.Platform
= None
2850 # conversion object for build or file format conversion purpose
2851 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2852 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2854 ## Check whether workspace database need to be renew.
2855 # The renew reason maybe:
2856 # 1) If user force to renew;
2857 # 2) If user do not force renew, and
2858 # a) If the time of last modified python source is newer than database file;
2859 # b) If the time of last modified frozen executable file is newer than database file;
2861 # @param force User force renew database
2862 # @param DbPath The absolute path of workspace database file
2864 # @return Bool value for whether need renew workspace databse
2866 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2867 # if database does not exist, we need do nothing
2868 if not os
.path
.exists(DbPath
): return False
2870 # if user force to renew database, then not check whether database is out of date
2871 if force
: return True
2874 # Check the time of last modified source file or build.exe
2875 # if is newer than time of database, then database need to be re-created.
2877 timeOfToolModified
= 0
2878 if hasattr(sys
, "frozen"):
2879 exePath
= os
.path
.abspath(sys
.executable
)
2880 timeOfToolModified
= os
.stat(exePath
).st_mtime
2882 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2883 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2884 if rootPath
== "" or rootPath
== None:
2885 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2886 determine whether database file is out of date!\n")
2888 # walk the root path of source or build's binary to get the time last modified.
2890 for root
, dirs
, files
in os
.walk (rootPath
):
2892 # bypass source control folder
2893 if dir.lower() in [".svn", "_svn", "cvs"]:
2897 ext
= os
.path
.splitext(file)[1]
2898 if ext
.lower() == ".py": # only check .py files
2899 fd
= os
.stat(os
.path
.join(root
, file))
2900 if timeOfToolModified
< fd
.st_mtime
:
2901 timeOfToolModified
= fd
.st_mtime
2902 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2903 EdkLogger
.verbose("\nWorkspace database is out of data!")
2908 ## Initialize build database
2909 def InitDatabase(self
):
2910 EdkLogger
.verbose("\nInitialize build database started ...")
2915 self
.TblDataModel
.Create(False)
2916 self
.TblFile
.Create(False)
2919 # Initialize table DataModel
2921 self
.TblDataModel
.InitTable()
2922 EdkLogger
.verbose("Initialize build database ... DONE!")
2926 # @param Table: The instance of the table to be queried
2928 def QueryTable(self
, Table
):
2934 ## Close entire database
2937 # Close the connection and cursor
2940 if not self
._DbClosedFlag
:
2944 self
._DbClosedFlag
= True
2946 ## Summarize all packages in the database
2947 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2948 self
.Platform
= Platform
2950 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2952 # Get Package related to Modules
2954 for Module
in Pa
.Modules
:
2955 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2956 for Package
in ModuleObj
.Packages
:
2957 if Package
not in PackageList
:
2958 PackageList
.append(Package
)
2960 # Get Packages related to Libraries
2962 for Lib
in Pa
.LibraryInstances
:
2963 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2964 for Package
in LibObj
.Packages
:
2965 if Package
not in PackageList
:
2966 PackageList
.append(Package
)
2970 ## Summarize all platforms in the database
2971 def _GetPlatformList(self
):
2973 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2975 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2978 if Platform
!= None:
2979 PlatformList
.append(Platform
)
2982 PlatformList
= property(_GetPlatformList
)
2986 # This acts like the main() function for the script, unless it is 'import'ed into another
2989 if __name__
== '__main__':