2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 import Common
.LongFilePathOs
as os
22 import Common
.EdkLogger
as EdkLogger
23 import Common
.GlobalData
as GlobalData
25 from Common
.String
import *
26 from Common
.DataType
import *
27 from Common
.Misc
import *
30 from CommonDataClass
.CommonClass
import SkuInfoClass
32 from MetaDataTable
import *
33 from MetaFileTable
import *
34 from MetaFileParser
import *
35 from BuildClassObject
import *
36 from WorkspaceCommon
import GetDeclaredPcd
37 from Common
.Misc
import AnalyzeDscPcd
38 from Common
.Misc
import ProcessDuplicatedInf
40 from Common
.Parsing
import IsValidWord
41 from Common
.VariableAttributes
import VariableAttributes
42 import Common
.GlobalData
as GlobalData
44 ## Platform build information from DSC file
46 # This class is used to retrieve information stored in database and convert them
47 # into PlatformBuildClassObject form for easier use for AutoGen.
49 class DscBuildData(PlatformBuildClassObject
):
50 # dict used to convert PCD type in database to string used by build tool
52 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
53 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
54 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
55 MODEL_PCD_DYNAMIC
: "Dynamic",
56 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
57 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
58 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
59 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
60 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
61 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
62 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
65 # dict used to convert part of [Defines] to members of DscBuildData directly
70 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
71 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
72 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
73 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
74 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
75 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
76 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
77 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
78 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
79 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
80 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
81 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
82 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
83 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
84 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
87 # used to compose dummy library class name for those forced library instances
88 _NullLibraryNumber
= 0
90 ## Constructor of DscBuildData
92 # Initialize object of DscBuildData
94 # @param FilePath The path of platform description file
95 # @param RawData The raw data of DSC file
96 # @param BuildDataBase Database used to retrieve module/package information
97 # @param Arch The target architecture
98 # @param Platform (not used for DscBuildData)
99 # @param Macros Macros used for replacement in DSC file
101 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
102 self
.MetaFile
= FilePath
103 self
._RawData
= RawData
104 self
._Bdb
= BuildDataBase
106 self
._Target
= Target
107 self
._Toolchain
= Toolchain
109 self
._HandleOverridePath
()
112 def __setitem__(self
, key
, value
):
113 self
.__dict
__[self
._PROPERTY
_[key
]] = value
116 def __getitem__(self
, key
):
117 return self
.__dict
__[self
._PROPERTY
_[key
]]
120 def __contains__(self
, key
):
121 return key
in self
._PROPERTY
_
123 ## Set all internal used members of DscBuildData to None
126 self
._PlatformName
= None
129 self
._DscSpecification
= None
130 self
._OutputDirectory
= None
131 self
._SupArchList
= None
132 self
._BuildTargets
= None
134 self
._SkuIdentifier
= None
135 self
._AvilableSkuIds
= None
136 self
._PcdInfoFlag
= None
137 self
._VarCheckFlag
= None
138 self
._FlashDefinition
= None
139 self
._BuildNumber
= None
140 self
._MakefileName
= None
141 self
._BsBaseAddress
= None
142 self
._RtBaseAddress
= None
145 self
._LibraryInstances
= None
146 self
._LibraryClasses
= None
149 self
._BuildOptions
= None
150 self
._LoadFixAddress
= None
151 self
._RFCLanguages
= None
152 self
._ISOLanguages
= None
153 self
._VpdToolGuid
= None
157 ## handle Override Path of Module
158 def _HandleOverridePath(self
):
159 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
160 Macros
= self
._Macros
161 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
162 for Record
in RecordList
:
165 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
166 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
168 SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
170 # Check if the source override path exists
171 if not os
.path
.isdir(SourceOverridePath
):
172 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
174 #Add to GlobalData Variables
175 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
177 ## Get current effective macros
178 def _GetMacros(self
):
179 if self
.__Macros
== None:
181 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
182 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
183 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
192 # Changing the default ARCH to another may affect all other information
193 # because all information in a platform may be ARCH-related. That's
194 # why we need to clear all internal used members, in order to cause all
195 # information to be re-retrieved.
197 # @param Value The value of ARCH
199 def _SetArch(self
, Value
):
200 if self
._Arch
== Value
:
205 ## Retrieve all information in [Defines] section
207 # (Retriving all [Defines] information in one-shot is just to save time.)
209 def _GetHeaderInfo(self
):
210 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
211 for Record
in RecordList
:
213 # items defined _PROPERTY_ don't need additional processing
215 # some special items in [Defines] section need special treatment
216 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
217 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
218 if ' ' in self
._OutputDirectory
:
219 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
220 File
=self
.MetaFile
, Line
=Record
[-1],
221 ExtraData
=self
._OutputDirectory
)
222 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
223 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
224 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
226 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
228 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
229 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
230 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
231 self
._BuildTargets
= GetSplitValueList(Record
[2])
232 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
233 if self
._SkuName
== None:
234 self
._SkuName
= Record
[2]
235 self
._SkuIdentifier
= Record
[2]
236 self
._AvilableSkuIds
= Record
[2]
237 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
238 self
._PcdInfoFlag
= Record
[2]
239 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
240 self
._VarCheckFlag
= Record
[2]
241 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
243 self
._LoadFixAddress
= int (Record
[2], 0)
245 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
246 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
247 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
248 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"',
249 File
=self
.MetaFile
, Line
=Record
[-1])
250 LanguageCodes
= Record
[2][1:-1]
251 if not LanguageCodes
:
252 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
253 File
=self
.MetaFile
, Line
=Record
[-1])
254 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
255 # check whether there is empty entries in the list
256 if None in LanguageList
:
257 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
258 File
=self
.MetaFile
, Line
=Record
[-1])
259 self
._RFCLanguages
= LanguageList
260 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
261 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
262 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
263 File
=self
.MetaFile
, Line
=Record
[-1])
264 LanguageCodes
= Record
[2][1:-1]
265 if not LanguageCodes
:
266 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
267 File
=self
.MetaFile
, Line
=Record
[-1])
268 if len(LanguageCodes
)%3:
269 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
270 File
=self
.MetaFile
, Line
=Record
[-1])
272 for i
in range(0, len(LanguageCodes
), 3):
273 LanguageList
.append(LanguageCodes
[i
:i
+3])
274 self
._ISOLanguages
= LanguageList
275 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
277 # try to convert GUID to a real UUID value to see whether the GUID is format
278 # for VPD_TOOL_GUID is correct.
283 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
284 self
._VpdToolGuid
= Record
[2]
286 self
[Name
] = Record
[2]
287 # set _Header to non-None in order to avoid database re-querying
288 self
._Header
= 'DUMMY'
290 ## Retrieve platform name
291 def _GetPlatformName(self
):
292 if self
._PlatformName
== None:
293 if self
._Header
== None:
294 self
._GetHeaderInfo
()
295 if self
._PlatformName
== None:
296 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
297 return self
._PlatformName
299 ## Retrieve file guid
300 def _GetFileGuid(self
):
301 if self
._Guid
== None:
302 if self
._Header
== None:
303 self
._GetHeaderInfo
()
304 if self
._Guid
== None:
305 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
308 ## Retrieve platform version
309 def _GetVersion(self
):
310 if self
._Version
== None:
311 if self
._Header
== None:
312 self
._GetHeaderInfo
()
313 if self
._Version
== None:
314 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
317 ## Retrieve platform description file version
318 def _GetDscSpec(self
):
319 if self
._DscSpecification
== None:
320 if self
._Header
== None:
321 self
._GetHeaderInfo
()
322 if self
._DscSpecification
== None:
323 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
324 return self
._DscSpecification
326 ## Retrieve OUTPUT_DIRECTORY
327 def _GetOutpuDir(self
):
328 if self
._OutputDirectory
== None:
329 if self
._Header
== None:
330 self
._GetHeaderInfo
()
331 if self
._OutputDirectory
== None:
332 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
333 return self
._OutputDirectory
335 ## Retrieve SUPPORTED_ARCHITECTURES
336 def _GetSupArch(self
):
337 if self
._SupArchList
== None:
338 if self
._Header
== None:
339 self
._GetHeaderInfo
()
340 if self
._SupArchList
== None:
341 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
342 return self
._SupArchList
344 ## Retrieve BUILD_TARGETS
345 def _GetBuildTarget(self
):
346 if self
._BuildTargets
== None:
347 if self
._Header
== None:
348 self
._GetHeaderInfo
()
349 if self
._BuildTargets
== None:
350 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
351 return self
._BuildTargets
353 def _GetPcdInfoFlag(self
):
354 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
356 elif self
._PcdInfoFlag
.upper() == 'TRUE':
360 def _GetVarCheckFlag(self
):
361 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
363 elif self
._VarCheckFlag
.upper() == 'TRUE':
367 def _GetAviableSkuIds(self
):
368 if self
._AvilableSkuIds
:
369 return self
._AvilableSkuIds
370 return self
.SkuIdentifier
371 def _GetSkuIdentifier(self
):
374 if self
._SkuIdentifier
== None:
375 if self
._Header
== None:
376 self
._GetHeaderInfo
()
377 return self
._SkuIdentifier
378 ## Retrieve SKUID_IDENTIFIER
379 def _GetSkuName(self
):
380 if self
._SkuName
== None:
381 if self
._Header
== None:
382 self
._GetHeaderInfo
()
383 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
384 self
._SkuName
= 'DEFAULT'
387 ## Override SKUID_IDENTIFIER
388 def _SetSkuName(self
, Value
):
389 self
._SkuName
= Value
392 def _GetFdfFile(self
):
393 if self
._FlashDefinition
== None:
394 if self
._Header
== None:
395 self
._GetHeaderInfo
()
396 if self
._FlashDefinition
== None:
397 self
._FlashDefinition
= ''
398 return self
._FlashDefinition
400 ## Retrieve FLASH_DEFINITION
401 def _GetBuildNumber(self
):
402 if self
._BuildNumber
== None:
403 if self
._Header
== None:
404 self
._GetHeaderInfo
()
405 if self
._BuildNumber
== None:
406 self
._BuildNumber
= ''
407 return self
._BuildNumber
409 ## Retrieve MAKEFILE_NAME
410 def _GetMakefileName(self
):
411 if self
._MakefileName
== None:
412 if self
._Header
== None:
413 self
._GetHeaderInfo
()
414 if self
._MakefileName
== None:
415 self
._MakefileName
= ''
416 return self
._MakefileName
418 ## Retrieve BsBaseAddress
419 def _GetBsBaseAddress(self
):
420 if self
._BsBaseAddress
== None:
421 if self
._Header
== None:
422 self
._GetHeaderInfo
()
423 if self
._BsBaseAddress
== None:
424 self
._BsBaseAddress
= ''
425 return self
._BsBaseAddress
427 ## Retrieve RtBaseAddress
428 def _GetRtBaseAddress(self
):
429 if self
._RtBaseAddress
== None:
430 if self
._Header
== None:
431 self
._GetHeaderInfo
()
432 if self
._RtBaseAddress
== None:
433 self
._RtBaseAddress
= ''
434 return self
._RtBaseAddress
436 ## Retrieve the top address for the load fix address
437 def _GetLoadFixAddress(self
):
438 if self
._LoadFixAddress
== None:
439 if self
._Header
== None:
440 self
._GetHeaderInfo
()
442 if self
._LoadFixAddress
== None:
443 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
446 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
448 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
451 # If command line defined, should override the value in DSC file.
453 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
455 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
457 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']))
459 if self
._LoadFixAddress
< 0:
460 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
461 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
462 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
464 return self
._LoadFixAddress
466 ## Retrieve RFCLanguage filter
467 def _GetRFCLanguages(self
):
468 if self
._RFCLanguages
== None:
469 if self
._Header
== None:
470 self
._GetHeaderInfo
()
471 if self
._RFCLanguages
== None:
472 self
._RFCLanguages
= []
473 return self
._RFCLanguages
475 ## Retrieve ISOLanguage filter
476 def _GetISOLanguages(self
):
477 if self
._ISOLanguages
== None:
478 if self
._Header
== None:
479 self
._GetHeaderInfo
()
480 if self
._ISOLanguages
== None:
481 self
._ISOLanguages
= []
482 return self
._ISOLanguages
483 ## Retrieve the GUID string for VPD tool
484 def _GetVpdToolGuid(self
):
485 if self
._VpdToolGuid
== None:
486 if self
._Header
== None:
487 self
._GetHeaderInfo
()
488 if self
._VpdToolGuid
== None:
489 self
._VpdToolGuid
= ''
490 return self
._VpdToolGuid
492 ## Retrieve [SkuIds] section information
493 def _GetSkuIds(self
):
494 if self
._SkuIds
== None:
495 self
._SkuIds
= sdict()
496 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
497 for Record
in RecordList
:
498 if Record
[0] in [None, '']:
499 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
500 File
=self
.MetaFile
, Line
=Record
[-1])
501 if Record
[1] in [None, '']:
502 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
503 File
=self
.MetaFile
, Line
=Record
[-1])
504 self
._SkuIds
[Record
[1]] = Record
[0]
505 if 'DEFAULT' not in self
._SkuIds
:
506 self
._SkuIds
['DEFAULT'] = '0'
507 if 'COMMON' not in self
._SkuIds
:
508 self
._SkuIds
['COMMON'] = '0'
511 ## Retrieve [Components] section information
512 def _GetModules(self
):
513 if self
._Modules
!= None:
516 self
._Modules
= sdict()
517 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
518 Macros
= self
._Macros
519 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
520 for Record
in RecordList
:
521 DuplicatedFile
= False
522 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
526 # check the file validation
527 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
529 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
532 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
533 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
534 DuplicatedFile
= True
536 Module
= ModuleBuildClassObject()
537 Module
.MetaFile
= ModuleFile
539 # get module private library instance
540 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
541 for Record
in RecordList
:
542 LibraryClass
= Record
[0]
543 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
546 # check the file validation
547 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
549 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
552 if LibraryClass
== '' or LibraryClass
== 'NULL':
553 self
._NullLibraryNumber
+= 1
554 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
555 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
556 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
557 if LibraryPath
not in self
.LibraryInstances
:
558 self
.LibraryInstances
.append(LibraryPath
)
560 # get module private PCD setting
561 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
562 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
563 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
564 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
565 TokenList
= GetSplitValueList(Setting
)
566 DefaultValue
= TokenList
[0]
567 if len(TokenList
) > 1:
568 MaxDatumSize
= TokenList
[1]
571 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
572 Pcd
= PcdClassObject(
584 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
586 # get module private build options
587 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
588 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
589 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
590 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
592 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
593 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
595 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
596 if DuplicatedFile
and not RecordList
:
597 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
599 if len(RecordList
) != 1:
600 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
601 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
602 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
603 ModuleFile
.Arch
= self
._Arch
605 self
._Modules
[ModuleFile
] = Module
608 ## Retrieve all possible library instances used in this platform
609 def _GetLibraryInstances(self
):
610 if self
._LibraryInstances
== None:
611 self
._GetLibraryClasses
()
612 return self
._LibraryInstances
614 ## Retrieve [LibraryClasses] information
615 def _GetLibraryClasses(self
):
616 if self
._LibraryClasses
== None:
617 self
._LibraryInstances
= []
619 # tdict is a special dict kind of type, used for selecting correct
620 # library instance for given library class and module type
622 LibraryClassDict
= tdict(True, 3)
623 # track all library class names
624 LibraryClassSet
= set()
625 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
626 Macros
= self
._Macros
627 for Record
in RecordList
:
628 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
629 if LibraryClass
== '' or LibraryClass
== 'NULL':
630 self
._NullLibraryNumber
+= 1
631 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
632 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
633 LibraryClassSet
.add(LibraryClass
)
634 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
635 # check the file validation
636 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
638 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
641 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
642 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
643 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
644 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
645 if LibraryInstance
not in self
._LibraryInstances
:
646 self
._LibraryInstances
.append(LibraryInstance
)
648 # resolve the specific library instance for each class and each module type
649 self
._LibraryClasses
= tdict(True)
650 for LibraryClass
in LibraryClassSet
:
651 # try all possible module types
652 for ModuleType
in SUP_MODULE_LIST
:
653 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
654 if LibraryInstance
== None:
656 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
658 # for Edk style library instances, which are listed in different section
659 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
660 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
661 for Record
in RecordList
:
662 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
664 # check the file validation
665 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
667 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
669 if File
not in self
._LibraryInstances
:
670 self
._LibraryInstances
.append(File
)
672 # we need the module name as the library class name, so we have
673 # to parse it here. (self._Bdb[] will trigger a file parse if it
674 # hasn't been parsed)
676 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
677 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
678 return self
._LibraryClasses
680 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
681 if self
._DecPcds
== None:
682 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
684 if GlobalData
.gFdfParser
:
685 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
688 for Inf
in FdfInfList
:
689 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
690 if ModuleFile
in self
._Modules
:
692 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
693 PkgSet
.update(ModuleData
.Packages
)
697 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
698 self
._DecPcds
.update(DecPcds
)
700 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
701 EdkLogger
.error('build', PARSER_ERROR
,
702 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
703 File
=self
.MetaFile
, Line
=LineNo
)
704 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
705 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
706 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
707 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
708 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
710 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
711 except WrnExpression
, Value
:
712 ValueList
[Index
] = Value
.result
713 except EvaluationException
, Excpt
:
714 if hasattr(Excpt
, 'Pcd'):
715 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
716 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
717 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
718 " of the DSC file" % Excpt
.Pcd
,
719 File
=self
.MetaFile
, Line
=LineNo
)
721 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
722 File
=self
.MetaFile
, Line
=LineNo
)
724 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
725 File
=self
.MetaFile
, Line
=LineNo
)
726 if ValueList
[Index
] == 'True':
727 ValueList
[Index
] = '1'
728 elif ValueList
[Index
] == 'False':
729 ValueList
[Index
] = '0'
731 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
733 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
734 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
737 ## Retrieve all PCD settings in platform
739 if self
._Pcds
== None:
741 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
742 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
743 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
744 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
745 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
746 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
747 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
748 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
749 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
752 ## Retrieve [BuildOptions]
753 def _GetBuildOptions(self
):
754 if self
._BuildOptions
== None:
755 self
._BuildOptions
= sdict()
757 # Retrieve build option for EDKII style module
759 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
760 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
761 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
763 # Retrieve build option for EDK style module
765 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
766 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
767 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
768 return self
._BuildOptions
770 ## Retrieve non-dynamic PCD settings
772 # @param Type PCD type
774 # @retval a dict object contains settings of given PCD type
776 def _GetPcd(self
, Type
):
779 # tdict is a special dict kind of type, used for selecting correct
780 # PCD settings for certain ARCH
783 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
785 PcdDict
= tdict(True, 3)
787 # Find out all possible PCD candidates for self._Arch
788 RecordList
= self
._RawData
[Type
, self
._Arch
]
789 PcdValueDict
= sdict()
790 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
791 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
792 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
793 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
795 #handle pcd value override
796 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
797 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
800 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
801 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
802 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
804 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
806 PcdsKeys
= PcdValueDict
.keys()
807 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
809 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
813 if 'COMMON' in PcdSetting
:
814 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
815 if 'DEFAULT' in PcdSetting
:
816 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
817 if SkuObj
.SystemSkuId
in PcdSetting
:
818 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
820 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
823 self
._PCD
_TYPE
_STRING
_[Type
],
834 ## Retrieve dynamic PCD settings
836 # @param Type PCD type
838 # @retval a dict object contains settings of given PCD type
840 def _GetDynamicPcd(self
, Type
):
842 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
846 # tdict is a special dict kind of type, used for selecting correct
847 # PCD settings for certain ARCH and SKU
849 PcdDict
= tdict(True, 4)
851 # Find out all possible PCD candidates for self._Arch
852 RecordList
= self
._RawData
[Type
, self
._Arch
]
853 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
855 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
856 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
857 if SkuName
not in AvailableSkuIdSet
:
860 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
861 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
862 # Remove redundant PCD candidates, per the ARCH and SKU
863 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
865 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
869 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
870 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
871 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
872 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
873 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
874 if MaxDatumSize
.strip():
875 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
878 if pcdObject
.MaxDatumSize
:
879 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
882 if CurrentMaxSize
> PcdMaxSize
:
883 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
885 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
888 self
._PCD
_TYPE
_STRING
_[Type
],
898 for pcd
in Pcds
.values():
899 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
900 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
901 valuefromDec
= pcdDecObject
.DefaultValue
902 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
903 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
904 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
905 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
906 del(pcd
.SkuInfoList
['COMMON'])
907 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
908 del(pcd
.SkuInfoList
['COMMON'])
909 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
910 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
911 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
912 del(pcd
.SkuInfoList
['DEFAULT'])
916 def CompareVarAttr(self
, Attr1
, Attr2
):
917 if not Attr1
or not Attr2
: # for empty string
919 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
920 Attr1Set
= set(Attr1s
)
921 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
922 Attr2Set
= set(Attr2s
)
923 if Attr2Set
== Attr1Set
:
927 ## Retrieve dynamic HII PCD settings
929 # @param Type PCD type
931 # @retval a dict object contains settings of given PCD type
933 def _GetDynamicHiiPcd(self
, Type
):
935 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
940 # tdict is a special dict kind of type, used for selecting correct
941 # PCD settings for certain ARCH and SKU
943 PcdDict
= tdict(True, 4)
945 RecordList
= self
._RawData
[Type
, self
._Arch
]
946 # Find out all possible PCD candidates for self._Arch
947 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
949 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
950 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
951 if SkuName
not in AvailableSkuIdSet
:
953 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
954 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
955 # Remove redundant PCD candidates, per the ARCH and SKU
956 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
958 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
961 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
963 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
965 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
966 ExtraData
= "[%s]" % VarAttribute
)
969 if VariableOffset
.isdigit():
970 if int(VariableOffset
,10) > 0xFFFF:
972 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
973 if int(VariableOffset
,16) > 0xFFFF:
975 # For Offset written in "A.B"
976 elif VariableOffset
.find('.') > -1:
977 VariableOffsetList
= VariableOffset
.split(".")
978 if not (len(VariableOffsetList
) == 2
979 and IsValidWord(VariableOffsetList
[0])
980 and IsValidWord(VariableOffsetList
[1])):
981 FormatCorrect
= False
983 FormatCorrect
= False
984 if not FormatCorrect
:
985 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
988 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
989 if (VariableName
, VariableGuid
) not in VariableAttrs
:
990 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
992 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
993 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
)]))
995 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
= VarAttribute
)
996 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
997 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
998 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
999 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1001 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1004 self
._PCD
_TYPE
_STRING
_[Type
],
1009 {SkuName
: SkuInfo
},
1012 pcdDecObject
.validateranges
,
1013 pcdDecObject
.validlists
,
1014 pcdDecObject
.expressions
1018 for pcd
in Pcds
.values():
1019 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1020 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1021 # Only fix the value while no value provided in DSC file.
1022 for sku
in pcd
.SkuInfoList
.values():
1023 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
1024 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1025 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1026 valuefromDec
= pcdDecObject
.DefaultValue
1027 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
1028 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1029 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1030 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1031 del(pcd
.SkuInfoList
['COMMON'])
1032 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1033 del(pcd
.SkuInfoList
['COMMON'])
1035 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1036 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1037 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1038 del(pcd
.SkuInfoList
['DEFAULT'])
1041 if pcd
.MaxDatumSize
.strip():
1042 MaxSize
= int(pcd
.MaxDatumSize
,0)
1045 if pcdDecObject
.DatumType
== 'VOID*':
1046 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1048 if skuobj
.HiiDefaultValue
.startswith("L"):
1049 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
1050 elif skuobj
.HiiDefaultValue
.startswith("{"):
1051 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1053 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
1056 pcd
.MaxDatumSize
= str(MaxSize
)
1059 ## Retrieve dynamic VPD PCD settings
1061 # @param Type PCD type
1063 # @retval a dict object contains settings of given PCD type
1065 def _GetDynamicVpdPcd(self
, Type
):
1067 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
1071 # tdict is a special dict kind of type, used for selecting correct
1072 # PCD settings for certain ARCH and SKU
1074 PcdDict
= tdict(True, 4)
1076 # Find out all possible PCD candidates for self._Arch
1077 RecordList
= self
._RawData
[Type
, self
._Arch
]
1078 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1080 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1081 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1082 if SkuName
not in AvailableSkuIdSet
:
1085 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1086 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1087 # Remove redundant PCD candidates, per the ARCH and SKU
1088 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1089 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1093 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1094 # For the Integer & Boolean type, the optional data can only be InitialValue.
1095 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1096 # until the DEC parser has been called.
1098 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1099 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1100 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1101 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1102 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1103 if MaxDatumSize
.strip():
1104 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1107 if pcdObject
.MaxDatumSize
:
1108 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1111 if CurrentMaxSize
> PcdMaxSize
:
1112 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1114 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1117 self
._PCD
_TYPE
_STRING
_[Type
],
1122 {SkuName
: SkuInfo
},
1126 for pcd
in Pcds
.values():
1127 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1128 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1129 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1130 valuefromDec
= pcdDecObject
.DefaultValue
1131 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1132 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1133 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1134 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1135 del(pcd
.SkuInfoList
['COMMON'])
1136 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1137 del(pcd
.SkuInfoList
['COMMON'])
1138 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1139 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1140 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1141 del(pcd
.SkuInfoList
['DEFAULT'])
1145 ## Add external modules
1147 # The external modules are mostly those listed in FDF file, which don't
1150 # @param FilePath The path of module description file
1152 def AddModule(self
, FilePath
):
1153 FilePath
= NormPath(FilePath
)
1154 if FilePath
not in self
.Modules
:
1155 Module
= ModuleBuildClassObject()
1156 Module
.MetaFile
= FilePath
1157 self
.Modules
.append(Module
)
1159 ## Add external PCDs
1161 # The external PCDs are mostly those listed in FDF file to specify address
1162 # or offset information.
1164 # @param Name Name of the PCD
1165 # @param Guid Token space guid of the PCD
1166 # @param Value Value of the PCD
1168 def AddPcd(self
, Name
, Guid
, Value
):
1169 if (Name
, Guid
) not in self
.Pcds
:
1170 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1171 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1173 _Macros
= property(_GetMacros
)
1174 Arch
= property(_GetArch
, _SetArch
)
1175 Platform
= property(_GetPlatformName
)
1176 PlatformName
= property(_GetPlatformName
)
1177 Guid
= property(_GetFileGuid
)
1178 Version
= property(_GetVersion
)
1179 DscSpecification
= property(_GetDscSpec
)
1180 OutputDirectory
= property(_GetOutpuDir
)
1181 SupArchList
= property(_GetSupArch
)
1182 BuildTargets
= property(_GetBuildTarget
)
1183 SkuName
= property(_GetSkuName
, _SetSkuName
)
1184 SkuIdentifier
= property(_GetSkuIdentifier
)
1185 AvilableSkuIds
= property(_GetAviableSkuIds
)
1186 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1187 VarCheckFlag
= property(_GetVarCheckFlag
)
1188 FlashDefinition
= property(_GetFdfFile
)
1189 BuildNumber
= property(_GetBuildNumber
)
1190 MakefileName
= property(_GetMakefileName
)
1191 BsBaseAddress
= property(_GetBsBaseAddress
)
1192 RtBaseAddress
= property(_GetRtBaseAddress
)
1193 LoadFixAddress
= property(_GetLoadFixAddress
)
1194 RFCLanguages
= property(_GetRFCLanguages
)
1195 ISOLanguages
= property(_GetISOLanguages
)
1196 VpdToolGuid
= property(_GetVpdToolGuid
)
1197 SkuIds
= property(_GetSkuIds
)
1198 Modules
= property(_GetModules
)
1199 LibraryInstances
= property(_GetLibraryInstances
)
1200 LibraryClasses
= property(_GetLibraryClasses
)
1201 Pcds
= property(_GetPcds
)
1202 BuildOptions
= property(_GetBuildOptions
)
1204 ## Platform build information from DEC file
1206 # This class is used to retrieve information stored in database and convert them
1207 # into PackageBuildClassObject form for easier use for AutoGen.
1209 class DecBuildData(PackageBuildClassObject
):
1210 # dict used to convert PCD type in database to string used by build tool
1211 _PCD_TYPE_STRING_
= {
1212 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1213 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1214 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1215 MODEL_PCD_DYNAMIC
: "Dynamic",
1216 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1217 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1218 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1219 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1220 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1221 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1222 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1225 # dict used to convert part of [Defines] to members of DecBuildData directly
1230 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1231 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1232 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1233 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1237 ## Constructor of DecBuildData
1239 # Initialize object of DecBuildData
1241 # @param FilePath The path of package description file
1242 # @param RawData The raw data of DEC file
1243 # @param BuildDataBase Database used to retrieve module information
1244 # @param Arch The target architecture
1245 # @param Platform (not used for DecBuildData)
1246 # @param Macros Macros used for replacement in DSC file
1248 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1249 self
.MetaFile
= File
1250 self
._PackageDir
= File
.Dir
1251 self
._RawData
= RawData
1252 self
._Bdb
= BuildDataBase
1254 self
._Target
= Target
1255 self
._Toolchain
= Toolchain
1259 def __setitem__(self
, key
, value
):
1260 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1263 def __getitem__(self
, key
):
1264 return self
.__dict
__[self
._PROPERTY
_[key
]]
1266 ## "in" test support
1267 def __contains__(self
, key
):
1268 return key
in self
._PROPERTY
_
1270 ## Set all internal used members of DecBuildData to None
1273 self
._PackageName
= None
1275 self
._Version
= None
1276 self
._PkgUniFile
= None
1277 self
._Protocols
= None
1280 self
._Includes
= None
1281 self
._LibraryClasses
= None
1283 self
.__Macros
= None
1285 ## Get current effective macros
1286 def _GetMacros(self
):
1287 if self
.__Macros
== None:
1289 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1290 return self
.__Macros
1298 # Changing the default ARCH to another may affect all other information
1299 # because all information in a platform may be ARCH-related. That's
1300 # why we need to clear all internal used members, in order to cause all
1301 # information to be re-retrieved.
1303 # @param Value The value of ARCH
1305 def _SetArch(self
, Value
):
1306 if self
._Arch
== Value
:
1311 ## Retrieve all information in [Defines] section
1313 # (Retriving all [Defines] information in one-shot is just to save time.)
1315 def _GetHeaderInfo(self
):
1316 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1317 for Record
in RecordList
:
1320 self
[Name
] = Record
[2]
1321 self
._Header
= 'DUMMY'
1323 ## Retrieve package name
1324 def _GetPackageName(self
):
1325 if self
._PackageName
== None:
1326 if self
._Header
== None:
1327 self
._GetHeaderInfo
()
1328 if self
._PackageName
== None:
1329 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1330 return self
._PackageName
1332 ## Retrieve file guid
1333 def _GetFileGuid(self
):
1334 if self
._Guid
== None:
1335 if self
._Header
== None:
1336 self
._GetHeaderInfo
()
1337 if self
._Guid
== None:
1338 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1341 ## Retrieve package version
1342 def _GetVersion(self
):
1343 if self
._Version
== None:
1344 if self
._Header
== None:
1345 self
._GetHeaderInfo
()
1346 if self
._Version
== None:
1348 return self
._Version
1350 ## Retrieve protocol definitions (name/value pairs)
1351 def _GetProtocol(self
):
1352 if self
._Protocols
== None:
1354 # tdict is a special kind of dict, used for selecting correct
1355 # protocol defition for given ARCH
1357 ProtocolDict
= tdict(True)
1359 # find out all protocol definitions for specific and 'common' arch
1360 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1361 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1362 if Name
not in NameList
:
1363 NameList
.append(Name
)
1364 ProtocolDict
[Arch
, Name
] = Guid
1365 # use sdict to keep the order
1366 self
._Protocols
= sdict()
1367 for Name
in NameList
:
1369 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1370 # will automatically turn to 'common' ARCH for trying
1372 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1373 return self
._Protocols
1375 ## Retrieve PPI definitions (name/value pairs)
1377 if self
._Ppis
== None:
1379 # tdict is a special kind of dict, used for selecting correct
1380 # PPI defition for given ARCH
1382 PpiDict
= tdict(True)
1384 # find out all PPI definitions for specific arch and 'common' arch
1385 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1386 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1387 if Name
not in NameList
:
1388 NameList
.append(Name
)
1389 PpiDict
[Arch
, Name
] = Guid
1390 # use sdict to keep the order
1391 self
._Ppis
= sdict()
1392 for Name
in NameList
:
1394 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1395 # will automatically turn to 'common' ARCH for trying
1397 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1400 ## Retrieve GUID definitions (name/value pairs)
1402 if self
._Guids
== None:
1404 # tdict is a special kind of dict, used for selecting correct
1405 # GUID defition for given ARCH
1407 GuidDict
= tdict(True)
1409 # find out all protocol definitions for specific and 'common' arch
1410 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1411 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1412 if Name
not in NameList
:
1413 NameList
.append(Name
)
1414 GuidDict
[Arch
, Name
] = Guid
1415 # use sdict to keep the order
1416 self
._Guids
= sdict()
1417 for Name
in NameList
:
1419 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1420 # will automatically turn to 'common' ARCH for trying
1422 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1425 ## Retrieve public include paths declared in this package
1426 def _GetInclude(self
):
1427 if self
._Includes
== None:
1429 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1430 Macros
= self
._Macros
1431 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1432 for Record
in RecordList
:
1433 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1436 ErrorCode
, ErrorInfo
= File
.Validate()
1438 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1440 # avoid duplicate include path
1441 if File
not in self
._Includes
:
1442 self
._Includes
.append(File
)
1443 return self
._Includes
1445 ## Retrieve library class declarations (not used in build at present)
1446 def _GetLibraryClass(self
):
1447 if self
._LibraryClasses
== None:
1449 # tdict is a special kind of dict, used for selecting correct
1450 # library class declaration for given ARCH
1452 LibraryClassDict
= tdict(True)
1453 LibraryClassSet
= set()
1454 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1455 Macros
= self
._Macros
1456 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1457 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1458 # check the file validation
1459 ErrorCode
, ErrorInfo
= File
.Validate()
1461 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1462 LibraryClassSet
.add(LibraryClass
)
1463 LibraryClassDict
[Arch
, LibraryClass
] = File
1464 self
._LibraryClasses
= sdict()
1465 for LibraryClass
in LibraryClassSet
:
1466 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1467 return self
._LibraryClasses
1469 ## Retrieve PCD declarations
1471 if self
._Pcds
== None:
1472 self
._Pcds
= sdict()
1473 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1474 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1475 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1476 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1477 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1480 ## Retrieve PCD declarations for given type
1481 def _GetPcd(self
, Type
):
1484 # tdict is a special kind of dict, used for selecting correct
1485 # PCD declaration for given ARCH
1487 PcdDict
= tdict(True, 3)
1488 # for summarizing PCD
1490 # find out all PCDs of the 'type'
1491 RecordList
= self
._RawData
[Type
, self
._Arch
]
1492 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1493 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1494 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1496 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1498 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1499 # will automatically turn to 'common' ARCH and try again
1501 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1505 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1507 validateranges
, validlists
, expressions
= self
._RawData
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
1508 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1511 self
._PCD
_TYPE
_STRING
_[Type
],
1519 list(validateranges
),
1526 _Macros
= property(_GetMacros
)
1527 Arch
= property(_GetArch
, _SetArch
)
1528 PackageName
= property(_GetPackageName
)
1529 Guid
= property(_GetFileGuid
)
1530 Version
= property(_GetVersion
)
1532 Protocols
= property(_GetProtocol
)
1533 Ppis
= property(_GetPpi
)
1534 Guids
= property(_GetGuid
)
1535 Includes
= property(_GetInclude
)
1536 LibraryClasses
= property(_GetLibraryClass
)
1537 Pcds
= property(_GetPcds
)
1539 ## Module build information from INF file
1541 # This class is used to retrieve information stored in database and convert them
1542 # into ModuleBuildClassObject form for easier use for AutoGen.
1544 class InfBuildData(ModuleBuildClassObject
):
1545 # dict used to convert PCD type in database to string used by build tool
1546 _PCD_TYPE_STRING_
= {
1547 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1548 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1549 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1550 MODEL_PCD_DYNAMIC
: "Dynamic",
1551 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1552 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1553 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1554 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1555 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1556 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1557 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1560 # dict used to convert part of [Defines] to members of InfBuildData directly
1565 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1566 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1567 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1571 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1572 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1573 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1574 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1575 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1576 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1577 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1578 TAB_INF_DEFINES_VERSION
: "_Version",
1579 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1580 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1582 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1585 # dict used to convert Component type to Module type
1588 "SECURITY_CORE" : "SEC",
1589 "PEI_CORE" : "PEI_CORE",
1590 "COMBINED_PEIM_DRIVER" : "PEIM",
1591 "PIC_PEIM" : "PEIM",
1592 "RELOCATABLE_PEIM" : "PEIM",
1593 "PE32_PEIM" : "PEIM",
1594 "BS_DRIVER" : "DXE_DRIVER",
1595 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1596 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1597 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1598 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1599 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1600 # "BS_DRIVER" : "UEFI_DRIVER",
1601 "APPLICATION" : "UEFI_APPLICATION",
1605 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1606 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1607 # dict used to convert old tool name used in [nmake] section to new ones
1615 ## Constructor of DscBuildData
1617 # Initialize object of DscBuildData
1619 # @param FilePath The path of platform description file
1620 # @param RawData The raw data of DSC file
1621 # @param BuildDataBase Database used to retrieve module/package information
1622 # @param Arch The target architecture
1623 # @param Platform The name of platform employing this module
1624 # @param Macros Macros used for replacement in DSC file
1626 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1627 self
.MetaFile
= FilePath
1628 self
._ModuleDir
= FilePath
.Dir
1629 self
._RawData
= RawData
1630 self
._Bdb
= BuildDatabase
1632 self
._Target
= Target
1633 self
._Toolchain
= Toolchain
1634 self
._Platform
= 'COMMON'
1635 self
._SourceOverridePath
= None
1636 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1637 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1641 def __setitem__(self
, key
, value
):
1642 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1645 def __getitem__(self
, key
):
1646 return self
.__dict
__[self
._PROPERTY
_[key
]]
1648 ## "in" test support
1649 def __contains__(self
, key
):
1650 return key
in self
._PROPERTY
_
1652 ## Set all internal used members of InfBuildData to None
1654 self
._HeaderComments
= None
1655 self
._TailComments
= None
1656 self
._Header
_ = None
1657 self
._AutoGenVersion
= None
1658 self
._BaseName
= None
1659 self
._DxsFile
= None
1660 self
._ModuleType
= None
1661 self
._ComponentType
= None
1662 self
._BuildType
= None
1664 self
._Version
= None
1665 self
._PcdIsDriver
= None
1666 self
._BinaryModule
= None
1668 self
._MakefileName
= None
1669 self
._CustomMakefile
= None
1670 self
._Specification
= None
1671 self
._LibraryClass
= None
1672 self
._ModuleEntryPointList
= None
1673 self
._ModuleUnloadImageList
= None
1674 self
._ConstructorList
= None
1675 self
._DestructorList
= None
1677 self
._Binaries
= None
1678 self
._Sources
= None
1679 self
._LibraryClasses
= None
1680 self
._Libraries
= None
1681 self
._Protocols
= None
1682 self
._ProtocolComments
= None
1684 self
._PpiComments
= None
1686 self
._GuidsUsedByPcd
= sdict()
1687 self
._GuidComments
= None
1688 self
._Includes
= None
1689 self
._Packages
= None
1691 self
._PcdComments
= None
1692 self
._BuildOptions
= None
1694 self
._DepexExpression
= None
1695 self
.__Macros
= None
1697 ## Get current effective macros
1698 def _GetMacros(self
):
1699 if self
.__Macros
== None:
1701 # EDK_GLOBAL defined macros can be applied to EDK module
1702 if self
.AutoGenVersion
< 0x00010005:
1703 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1704 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1705 return self
.__Macros
1713 # Changing the default ARCH to another may affect all other information
1714 # because all information in a platform may be ARCH-related. That's
1715 # why we need to clear all internal used members, in order to cause all
1716 # information to be re-retrieved.
1718 # @param Value The value of ARCH
1720 def _SetArch(self
, Value
):
1721 if self
._Arch
== Value
:
1726 ## Return the name of platform employing this module
1727 def _GetPlatform(self
):
1728 return self
._Platform
1730 ## Change the name of platform employing this module
1732 # Changing the default name of platform to another may affect some information
1733 # because they may be PLATFORM-related. That's why we need to clear all internal
1734 # used members, in order to cause all information to be re-retrieved.
1736 def _SetPlatform(self
, Value
):
1737 if self
._Platform
== Value
:
1739 self
._Platform
= Value
1741 def _GetHeaderComments(self
):
1742 if not self
._HeaderComments
:
1743 self
._HeaderComments
= []
1744 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1745 for Record
in RecordList
:
1746 self
._HeaderComments
.append(Record
[0])
1747 return self
._HeaderComments
1748 def _GetTailComments(self
):
1749 if not self
._TailComments
:
1750 self
._TailComments
= []
1751 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1752 for Record
in RecordList
:
1753 self
._TailComments
.append(Record
[0])
1754 return self
._TailComments
1755 ## Retrieve all information in [Defines] section
1757 # (Retriving all [Defines] information in one-shot is just to save time.)
1759 def _GetHeaderInfo(self
):
1760 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1761 for Record
in RecordList
:
1762 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1763 # items defined _PROPERTY_ don't need additional processing
1766 if self
._Defs
== None:
1767 self
._Defs
= sdict()
1768 self
._Defs
[Name
] = Value
1769 # some special items in [Defines] section need special treatment
1770 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1771 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1772 Name
= 'UEFI_SPECIFICATION_VERSION'
1773 if self
._Specification
== None:
1774 self
._Specification
= sdict()
1775 self
._Specification
[Name
] = GetHexVerValue(Value
)
1776 if self
._Specification
[Name
] == None:
1777 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1778 "'%s' format is not supported for %s" % (Value
, Name
),
1779 File
=self
.MetaFile
, Line
=Record
[-1])
1780 elif Name
== 'LIBRARY_CLASS':
1781 if self
._LibraryClass
== None:
1782 self
._LibraryClass
= []
1783 ValueList
= GetSplitValueList(Value
)
1784 LibraryClass
= ValueList
[0]
1785 if len(ValueList
) > 1:
1786 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1788 SupModuleList
= SUP_MODULE_LIST
1789 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1790 elif Name
== 'ENTRY_POINT':
1791 if self
._ModuleEntryPointList
== None:
1792 self
._ModuleEntryPointList
= []
1793 self
._ModuleEntryPointList
.append(Value
)
1794 elif Name
== 'UNLOAD_IMAGE':
1795 if self
._ModuleUnloadImageList
== None:
1796 self
._ModuleUnloadImageList
= []
1799 self
._ModuleUnloadImageList
.append(Value
)
1800 elif Name
== 'CONSTRUCTOR':
1801 if self
._ConstructorList
== None:
1802 self
._ConstructorList
= []
1805 self
._ConstructorList
.append(Value
)
1806 elif Name
== 'DESTRUCTOR':
1807 if self
._DestructorList
== None:
1808 self
._DestructorList
= []
1811 self
._DestructorList
.append(Value
)
1812 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1813 TokenList
= GetSplitValueList(Value
)
1814 if self
._CustomMakefile
== None:
1815 self
._CustomMakefile
= {}
1816 if len(TokenList
) < 2:
1817 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1818 self
._CustomMakefile
['GCC'] = TokenList
[0]
1820 if TokenList
[0] not in ['MSFT', 'GCC']:
1821 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1822 "No supported family [%s]" % TokenList
[0],
1823 File
=self
.MetaFile
, Line
=Record
[-1])
1824 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1826 if self
._Defs
== None:
1827 self
._Defs
= sdict()
1828 self
._Defs
[Name
] = Value
1831 # Retrieve information in sections specific to Edk.x modules
1833 if self
.AutoGenVersion
>= 0x00010005:
1834 if not self
._ModuleType
:
1835 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1836 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1837 if self
._ModuleType
not in SUP_MODULE_LIST
:
1838 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1839 for Record
in RecordList
:
1841 if Name
== "MODULE_TYPE":
1844 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1845 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1846 File
=self
.MetaFile
, Line
=LineNo
)
1847 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1848 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1849 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
)
1850 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1851 and 'PCI_CLASS_CODE' in self
._Defs
:
1852 self
._BuildType
= 'UEFI_OPTIONROM'
1853 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1854 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1855 self
._BuildType
= 'UEFI_HII'
1857 self
._BuildType
= self
._ModuleType
.upper()
1860 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1861 # check the file validation
1862 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1864 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1865 File
=self
.MetaFile
, Line
=LineNo
)
1866 if self
.Sources
== None:
1868 self
._Sources
.append(File
)
1870 if not self
._ComponentType
:
1871 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1872 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1873 self
._BuildType
= self
._ComponentType
.upper()
1874 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1875 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1876 if self
._ComponentType
== 'LIBRARY':
1877 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1878 # make use some [nmake] section macros
1879 Macros
= self
._Macros
1880 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1881 Macros
['PROCESSOR'] = self
._Arch
1882 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1883 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1884 Value
= ReplaceMacro(Value
, Macros
, True)
1885 if Name
== "IMAGE_ENTRY_POINT":
1886 if self
._ModuleEntryPointList
== None:
1887 self
._ModuleEntryPointList
= []
1888 self
._ModuleEntryPointList
.append(Value
)
1889 elif Name
== "DPX_SOURCE":
1890 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1891 # check the file validation
1892 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1894 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1895 File
=self
.MetaFile
, Line
=LineNo
)
1896 if self
.Sources
== None:
1898 self
._Sources
.append(File
)
1900 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1901 if len(ToolList
) == 0 or len(ToolList
) != 1:
1903 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1904 # File=self.MetaFile, Line=LineNo)
1906 if self
._BuildOptions
== None:
1907 self
._BuildOptions
= sdict()
1909 if ToolList
[0] in self
._TOOL
_CODE
_:
1910 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1913 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1914 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1915 #ignore not replaced macros in value
1916 ValueList
= GetSplitList(' ' + Value
, '/D')
1917 Dummy
= ValueList
[0]
1918 for Index
in range(1, len(ValueList
)):
1919 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1921 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1922 Value
= Dummy
.strip()
1923 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1924 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1926 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1927 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1928 # set _Header to non-None in order to avoid database re-querying
1929 self
._Header
_ = 'DUMMY'
1931 ## Retrieve file version
1932 def _GetInfVersion(self
):
1933 if self
._AutoGenVersion
== None:
1934 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1935 for Record
in RecordList
:
1936 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1937 self
._AutoGenVersion
= int(Record
[2], 0)
1939 if self
._AutoGenVersion
== None:
1940 self
._AutoGenVersion
= 0x00010000
1941 return self
._AutoGenVersion
1943 ## Retrieve BASE_NAME
1944 def _GetBaseName(self
):
1945 if self
._BaseName
== None:
1946 if self
._Header
_ == None:
1947 self
._GetHeaderInfo
()
1948 if self
._BaseName
== None:
1949 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1950 return self
._BaseName
1953 def _GetDxsFile(self
):
1954 if self
._DxsFile
== None:
1955 if self
._Header
_ == None:
1956 self
._GetHeaderInfo
()
1957 if self
._DxsFile
== None:
1959 return self
._DxsFile
1961 ## Retrieve MODULE_TYPE
1962 def _GetModuleType(self
):
1963 if self
._ModuleType
== None:
1964 if self
._Header
_ == None:
1965 self
._GetHeaderInfo
()
1966 if self
._ModuleType
== None:
1967 self
._ModuleType
= 'BASE'
1968 if self
._ModuleType
not in SUP_MODULE_LIST
:
1969 self
._ModuleType
= "USER_DEFINED"
1970 return self
._ModuleType
1972 ## Retrieve COMPONENT_TYPE
1973 def _GetComponentType(self
):
1974 if self
._ComponentType
== None:
1975 if self
._Header
_ == None:
1976 self
._GetHeaderInfo
()
1977 if self
._ComponentType
== None:
1978 self
._ComponentType
= 'USER_DEFINED'
1979 return self
._ComponentType
1981 ## Retrieve "BUILD_TYPE"
1982 def _GetBuildType(self
):
1983 if self
._BuildType
== None:
1984 if self
._Header
_ == None:
1985 self
._GetHeaderInfo
()
1986 if not self
._BuildType
:
1987 self
._BuildType
= "BASE"
1988 return self
._BuildType
1990 ## Retrieve file guid
1991 def _GetFileGuid(self
):
1992 if self
._Guid
== None:
1993 if self
._Header
_ == None:
1994 self
._GetHeaderInfo
()
1995 if self
._Guid
== None:
1996 self
._Guid
= '00000000-0000-0000-000000000000'
1999 ## Retrieve module version
2000 def _GetVersion(self
):
2001 if self
._Version
== None:
2002 if self
._Header
_ == None:
2003 self
._GetHeaderInfo
()
2004 if self
._Version
== None:
2005 self
._Version
= '0.0'
2006 return self
._Version
2008 ## Retrieve PCD_IS_DRIVER
2009 def _GetPcdIsDriver(self
):
2010 if self
._PcdIsDriver
== None:
2011 if self
._Header
_ == None:
2012 self
._GetHeaderInfo
()
2013 if self
._PcdIsDriver
== None:
2014 self
._PcdIsDriver
= ''
2015 return self
._PcdIsDriver
2018 def _GetShadow(self
):
2019 if self
._Shadow
== None:
2020 if self
._Header
_ == None:
2021 self
._GetHeaderInfo
()
2022 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
2025 self
._Shadow
= False
2028 ## Retrieve CUSTOM_MAKEFILE
2029 def _GetMakefile(self
):
2030 if self
._CustomMakefile
== None:
2031 if self
._Header
_ == None:
2032 self
._GetHeaderInfo
()
2033 if self
._CustomMakefile
== None:
2034 self
._CustomMakefile
= {}
2035 return self
._CustomMakefile
2037 ## Retrieve EFI_SPECIFICATION_VERSION
2039 if self
._Specification
== None:
2040 if self
._Header
_ == None:
2041 self
._GetHeaderInfo
()
2042 if self
._Specification
== None:
2043 self
._Specification
= {}
2044 return self
._Specification
2046 ## Retrieve LIBRARY_CLASS
2047 def _GetLibraryClass(self
):
2048 if self
._LibraryClass
== None:
2049 if self
._Header
_ == None:
2050 self
._GetHeaderInfo
()
2051 if self
._LibraryClass
== None:
2052 self
._LibraryClass
= []
2053 return self
._LibraryClass
2055 ## Retrieve ENTRY_POINT
2056 def _GetEntryPoint(self
):
2057 if self
._ModuleEntryPointList
== None:
2058 if self
._Header
_ == None:
2059 self
._GetHeaderInfo
()
2060 if self
._ModuleEntryPointList
== None:
2061 self
._ModuleEntryPointList
= []
2062 return self
._ModuleEntryPointList
2064 ## Retrieve UNLOAD_IMAGE
2065 def _GetUnloadImage(self
):
2066 if self
._ModuleUnloadImageList
== None:
2067 if self
._Header
_ == None:
2068 self
._GetHeaderInfo
()
2069 if self
._ModuleUnloadImageList
== None:
2070 self
._ModuleUnloadImageList
= []
2071 return self
._ModuleUnloadImageList
2073 ## Retrieve CONSTRUCTOR
2074 def _GetConstructor(self
):
2075 if self
._ConstructorList
== None:
2076 if self
._Header
_ == None:
2077 self
._GetHeaderInfo
()
2078 if self
._ConstructorList
== None:
2079 self
._ConstructorList
= []
2080 return self
._ConstructorList
2082 ## Retrieve DESTRUCTOR
2083 def _GetDestructor(self
):
2084 if self
._DestructorList
== None:
2085 if self
._Header
_ == None:
2086 self
._GetHeaderInfo
()
2087 if self
._DestructorList
== None:
2088 self
._DestructorList
= []
2089 return self
._DestructorList
2091 ## Retrieve definies other than above ones
2092 def _GetDefines(self
):
2093 if self
._Defs
== None:
2094 if self
._Header
_ == None:
2095 self
._GetHeaderInfo
()
2096 if self
._Defs
== None:
2097 self
._Defs
= sdict()
2100 ## Retrieve binary files
2101 def _GetBinaries(self
):
2102 if self
._Binaries
== None:
2104 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2105 Macros
= self
._Macros
2106 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2107 Macros
['PROCESSOR'] = self
._Arch
2108 for Record
in RecordList
:
2109 FileType
= Record
[0]
2114 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2116 Target
= TokenList
[0]
2117 if len(TokenList
) > 1:
2118 FeatureFlag
= Record
[1:]
2120 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2121 # check the file validation
2122 ErrorCode
, ErrorInfo
= File
.Validate()
2124 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2125 self
._Binaries
.append(File
)
2126 return self
._Binaries
2128 ## Retrieve binary files with error check.
2129 def _GetBinaryFiles(self
):
2130 Binaries
= self
._GetBinaries
()
2131 if GlobalData
.gIgnoreSource
and Binaries
== []:
2132 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2133 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2136 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2137 def _IsSupportedArch(self
):
2138 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2142 ## Retrieve source files
2143 def _GetSourceFiles(self
):
2144 #Ignore all source files in a binary build mode
2145 if GlobalData
.gIgnoreSource
:
2147 return self
._Sources
2149 if self
._Sources
== None:
2151 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2152 Macros
= self
._Macros
2153 for Record
in RecordList
:
2155 ToolChainFamily
= Record
[1]
2157 ToolCode
= Record
[3]
2158 FeatureFlag
= Record
[4]
2159 if self
.AutoGenVersion
< 0x00010005:
2160 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2161 Macros
['PROCESSOR'] = self
._Arch
2162 # old module source files (Edk)
2163 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
2164 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2165 # check the file validation
2166 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2168 if File
.Ext
.lower() == '.h':
2169 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2170 File
=self
.MetaFile
, Line
=LineNo
)
2173 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2175 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2176 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2177 # check the file validation
2178 ErrorCode
, ErrorInfo
= File
.Validate()
2180 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2182 self
._Sources
.append(File
)
2183 return self
._Sources
2185 ## Retrieve library classes employed by this module
2186 def _GetLibraryClassUses(self
):
2187 if self
._LibraryClasses
== None:
2188 self
._LibraryClasses
= sdict()
2189 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2190 for Record
in RecordList
:
2192 Instance
= Record
[1]
2194 Instance
= NormPath(Instance
, self
._Macros
)
2195 self
._LibraryClasses
[Lib
] = Instance
2196 return self
._LibraryClasses
2198 ## Retrieve library names (for Edk.x style of modules)
2199 def _GetLibraryNames(self
):
2200 if self
._Libraries
== None:
2201 self
._Libraries
= []
2202 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2203 for Record
in RecordList
:
2204 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2205 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2206 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2207 if LibraryName
not in self
._Libraries
:
2208 self
._Libraries
.append(LibraryName
)
2209 return self
._Libraries
2211 def _GetProtocolComments(self
):
2212 self
._GetProtocols
()
2213 return self
._ProtocolComments
2214 ## Retrieve protocols consumed/produced by this module
2215 def _GetProtocols(self
):
2216 if self
._Protocols
== None:
2217 self
._Protocols
= sdict()
2218 self
._ProtocolComments
= sdict()
2219 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2220 for Record
in RecordList
:
2222 Value
= ProtocolValue(CName
, self
.Packages
)
2224 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2225 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2226 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2227 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2228 self
._Protocols
[CName
] = Value
2229 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2231 for CmtRec
in CommentRecords
:
2232 Comments
.append(CmtRec
[0])
2233 self
._ProtocolComments
[CName
] = Comments
2234 return self
._Protocols
2236 def _GetPpiComments(self
):
2238 return self
._PpiComments
2239 ## Retrieve PPIs consumed/produced by this module
2241 if self
._Ppis
== None:
2242 self
._Ppis
= sdict()
2243 self
._PpiComments
= sdict()
2244 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2245 for Record
in RecordList
:
2247 Value
= PpiValue(CName
, self
.Packages
)
2249 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2250 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2251 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2252 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2253 self
._Ppis
[CName
] = Value
2254 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2256 for CmtRec
in CommentRecords
:
2257 Comments
.append(CmtRec
[0])
2258 self
._PpiComments
[CName
] = Comments
2261 def _GetGuidComments(self
):
2263 return self
._GuidComments
2264 ## Retrieve GUIDs consumed/produced by this module
2265 def _GetGuids(self
):
2266 if self
._Guids
== None:
2267 self
._Guids
= sdict()
2268 self
._GuidComments
= sdict()
2269 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2270 for Record
in RecordList
:
2272 Value
= GuidValue(CName
, self
.Packages
)
2274 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2275 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2276 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2277 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2278 self
._Guids
[CName
] = Value
2279 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2281 for CmtRec
in CommentRecords
:
2282 Comments
.append(CmtRec
[0])
2283 self
._GuidComments
[CName
] = Comments
2286 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2287 def _GetIncludes(self
):
2288 if self
._Includes
== None:
2290 if self
._SourceOverridePath
:
2291 self
._Includes
.append(self
._SourceOverridePath
)
2293 Macros
= self
._Macros
2294 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2295 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2297 Macros
['PROCESSOR'] = self
._Arch
2298 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2299 for Record
in RecordList
:
2300 if Record
[0].find('EDK_SOURCE') > -1:
2301 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2302 File
= NormPath(Record
[0], self
._Macros
)
2304 File
= os
.path
.join(self
._ModuleDir
, File
)
2306 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2307 File
= RealPath(os
.path
.normpath(File
))
2309 self
._Includes
.append(File
)
2311 #TRICK: let compiler to choose correct header file
2312 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2313 File
= NormPath(Record
[0], self
._Macros
)
2315 File
= os
.path
.join(self
._ModuleDir
, File
)
2317 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2318 File
= RealPath(os
.path
.normpath(File
))
2320 self
._Includes
.append(File
)
2322 File
= NormPath(Record
[0], Macros
)
2324 File
= os
.path
.join(self
._ModuleDir
, File
)
2326 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2327 File
= RealPath(os
.path
.normpath(File
))
2329 self
._Includes
.append(File
)
2330 return self
._Includes
2332 ## Retrieve packages this module depends on
2333 def _GetPackages(self
):
2334 if self
._Packages
== None:
2336 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2337 Macros
= self
._Macros
2338 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2339 for Record
in RecordList
:
2340 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2342 # check the file validation
2343 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2345 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2346 # parse this package now. we need it to get protocol/ppi/guid value
2347 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2348 self
._Packages
.append(Package
)
2349 return self
._Packages
2351 ## Retrieve PCD comments
2352 def _GetPcdComments(self
):
2354 return self
._PcdComments
2355 ## Retrieve PCDs used in this module
2357 if self
._Pcds
== None:
2358 self
._Pcds
= sdict()
2359 self
._PcdComments
= sdict()
2360 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2361 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2362 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2363 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2364 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2367 ## Retrieve build options specific to this module
2368 def _GetBuildOptions(self
):
2369 if self
._BuildOptions
== None:
2370 self
._BuildOptions
= sdict()
2371 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2372 for Record
in RecordList
:
2373 ToolChainFamily
= Record
[0]
2374 ToolChain
= Record
[1]
2376 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2377 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2379 # concatenate the option string if they're for the same tool
2380 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2381 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2382 return self
._BuildOptions
2384 ## Retrieve dependency expression
2385 def _GetDepex(self
):
2386 if self
._Depex
== None:
2387 self
._Depex
= tdict(False, 2)
2388 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2390 # If the module has only Binaries and no Sources, then ignore [Depex]
2391 if self
.Sources
== None or self
.Sources
== []:
2392 if self
.Binaries
!= None and self
.Binaries
!= []:
2395 # PEIM and DXE drivers must have a valid [Depex] section
2396 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2397 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2398 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2399 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2400 % self
.ModuleType
, File
=self
.MetaFile
)
2402 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2403 for Record
in RecordList
:
2404 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2405 EdkLogger
.error('build', FORMAT_INVALID
,
2406 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2410 for Record
in RecordList
:
2411 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2413 ModuleType
= Record
[4]
2414 TokenList
= DepexStr
.split()
2415 if (Arch
, ModuleType
) not in Depex
:
2416 Depex
[Arch
, ModuleType
] = []
2417 DepexList
= Depex
[Arch
, ModuleType
]
2418 for Token
in TokenList
:
2419 if Token
in DEPEX_SUPPORTED_OPCODE
:
2420 DepexList
.append(Token
)
2421 elif Token
.endswith(".inf"): # module file name
2422 ModuleFile
= os
.path
.normpath(Token
)
2423 Module
= self
.BuildDatabase
[ModuleFile
]
2425 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2426 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2427 DepexList
.append(Module
.Guid
)
2429 # get the GUID value now
2430 Value
= ProtocolValue(Token
, self
.Packages
)
2432 Value
= PpiValue(Token
, self
.Packages
)
2434 Value
= GuidValue(Token
, self
.Packages
)
2436 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2437 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2438 "Value of [%s] is not found in" % Token
,
2439 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2440 DepexList
.append(Value
)
2441 for Arch
, ModuleType
in Depex
:
2442 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2445 ## Retrieve depedency expression
2446 def _GetDepexExpression(self
):
2447 if self
._DepexExpression
== None:
2448 self
._DepexExpression
= tdict(False, 2)
2449 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2450 DepexExpression
= sdict()
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 DepexExpression
:
2457 DepexExpression
[Arch
, ModuleType
] = ''
2458 for Token
in TokenList
:
2459 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2460 for Arch
, ModuleType
in DepexExpression
:
2461 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2462 return self
._DepexExpression
2464 def GetGuidsUsedByPcd(self
):
2465 return self
._GuidsUsedByPcd
2466 ## Retrieve PCD for given type
2467 def _GetPcd(self
, Type
):
2469 PcdDict
= tdict(True, 4)
2471 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2472 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2473 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2474 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2475 # get the guid value
2476 if TokenSpaceGuid
not in self
.Guids
:
2477 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2479 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2480 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2481 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2482 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2483 self
.Guids
[TokenSpaceGuid
] = Value
2484 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2485 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2487 for CmtRec
in CommentRecords
:
2488 Comments
.append(CmtRec
[0])
2489 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2491 # resolve PCD type, value, datum info, etc. by getting its definition from package
2492 for PcdCName
, TokenSpaceGuid
in PcdList
:
2493 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2496 ValueList
= AnalyzePcdData(Setting
)
2497 DefaultValue
= ValueList
[0]
2498 Pcd
= PcdClassObject(
2508 self
.Guids
[TokenSpaceGuid
]
2510 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2511 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2512 Pcd
.Offset
= ValueList
[1]
2514 # get necessary info from package declaring this PCD
2515 for Package
in self
.Packages
:
2517 # 'dynamic' in INF means its type is determined by platform;
2518 # if platform doesn't give its type, use 'lowest' one in the
2519 # following order, if any
2521 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2523 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2524 if Type
== MODEL_PCD_DYNAMIC
:
2526 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2527 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2533 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2534 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2536 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2539 # Check whether the token value exist or not.
2541 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2545 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2546 File
=self
.MetaFile
, Line
=LineNo
,
2550 # Check hexadecimal token value length and format.
2552 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2553 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2554 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2558 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2559 File
=self
.MetaFile
, Line
=LineNo
,
2564 # Check decimal token value length and format.
2568 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2569 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2573 "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
)),
2574 File
=self
.MetaFile
, Line
=LineNo
,
2581 "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
)),
2582 File
=self
.MetaFile
, Line
=LineNo
,
2586 Pcd
.DatumType
= PcdInPackage
.DatumType
2587 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2588 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2589 if Pcd
.DefaultValue
in [None, '']:
2590 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2596 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2597 File
=self
.MetaFile
, Line
=LineNo
,
2598 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2600 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2604 ## check whether current module is binary module
2605 def _IsBinaryModule(self
):
2606 if self
.Binaries
and not self
.Sources
:
2608 elif GlobalData
.gIgnoreSource
:
2613 _Macros
= property(_GetMacros
)
2614 Arch
= property(_GetArch
, _SetArch
)
2615 Platform
= property(_GetPlatform
, _SetPlatform
)
2617 HeaderComments
= property(_GetHeaderComments
)
2618 TailComments
= property(_GetTailComments
)
2619 AutoGenVersion
= property(_GetInfVersion
)
2620 BaseName
= property(_GetBaseName
)
2621 ModuleType
= property(_GetModuleType
)
2622 ComponentType
= property(_GetComponentType
)
2623 BuildType
= property(_GetBuildType
)
2624 Guid
= property(_GetFileGuid
)
2625 Version
= property(_GetVersion
)
2626 PcdIsDriver
= property(_GetPcdIsDriver
)
2627 Shadow
= property(_GetShadow
)
2628 CustomMakefile
= property(_GetMakefile
)
2629 Specification
= property(_GetSpec
)
2630 LibraryClass
= property(_GetLibraryClass
)
2631 ModuleEntryPointList
= property(_GetEntryPoint
)
2632 ModuleUnloadImageList
= property(_GetUnloadImage
)
2633 ConstructorList
= property(_GetConstructor
)
2634 DestructorList
= property(_GetDestructor
)
2635 Defines
= property(_GetDefines
)
2636 DxsFile
= property(_GetDxsFile
)
2638 Binaries
= property(_GetBinaryFiles
)
2639 Sources
= property(_GetSourceFiles
)
2640 LibraryClasses
= property(_GetLibraryClassUses
)
2641 Libraries
= property(_GetLibraryNames
)
2642 Protocols
= property(_GetProtocols
)
2643 ProtocolComments
= property(_GetProtocolComments
)
2644 Ppis
= property(_GetPpis
)
2645 PpiComments
= property(_GetPpiComments
)
2646 Guids
= property(_GetGuids
)
2647 GuidComments
= property(_GetGuidComments
)
2648 Includes
= property(_GetIncludes
)
2649 Packages
= property(_GetPackages
)
2650 Pcds
= property(_GetPcds
)
2651 PcdComments
= property(_GetPcdComments
)
2652 BuildOptions
= property(_GetBuildOptions
)
2653 Depex
= property(_GetDepex
)
2654 DepexExpression
= property(_GetDepexExpression
)
2655 IsBinaryModule
= property(_IsBinaryModule
)
2656 IsSupportedArch
= property(_IsSupportedArch
)
2660 # This class defined the build database for all modules, packages and platform.
2661 # It will call corresponding parser for the given file if it cannot find it in
2664 # @param DbPath Path of database file
2665 # @param GlobalMacros Global macros used for replacement during file parsing
2666 # @prarm RenewDb=False Create new database file if it's already there
2668 class WorkspaceDatabase(object):
2672 # internal class used for call corresponding file parser and caching the result
2673 # to avoid unnecessary re-parsing
2675 class BuildObjectFactory(object):
2678 ".inf" : MODEL_FILE_INF
,
2679 ".dec" : MODEL_FILE_DEC
,
2680 ".dsc" : MODEL_FILE_DSC
,
2685 MODEL_FILE_INF
: InfParser
,
2686 MODEL_FILE_DEC
: DecParser
,
2687 MODEL_FILE_DSC
: DscParser
,
2690 # convert to xxxBuildData object
2692 MODEL_FILE_INF
: InfBuildData
,
2693 MODEL_FILE_DEC
: DecBuildData
,
2694 MODEL_FILE_DSC
: DscBuildData
,
2697 _CACHE_
= {} # (FilePath, Arch) : <object>
2700 def __init__(self
, WorkspaceDb
):
2701 self
.WorkspaceDb
= WorkspaceDb
2703 # key = (FilePath, Arch=None)
2704 def __contains__(self
, Key
):
2710 return (FilePath
, Arch
) in self
._CACHE
_
2712 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2713 def __getitem__(self
, Key
):
2715 KeyLength
= len(Key
)
2729 # if it's generated before, just return the cached one
2730 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2731 if Key
in self
._CACHE
_:
2732 return self
._CACHE
_[Key
]
2736 if Ext
not in self
._FILE
_TYPE
_:
2738 FileType
= self
._FILE
_TYPE
_[Ext
]
2739 if FileType
not in self
._GENERATOR
_:
2742 # get the parser ready for this file
2743 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2746 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2748 # alwasy do post-process, in case of macros change
2749 MetaFile
.DoPostProcess()
2750 # object the build is based on
2751 BuildObject
= self
._GENERATOR
_[FileType
](
2759 self
._CACHE
_[Key
] = BuildObject
2762 # placeholder for file format conversion
2763 class TransformObjectFactory
:
2764 def __init__(self
, WorkspaceDb
):
2765 self
.WorkspaceDb
= WorkspaceDb
2767 # key = FilePath, Arch
2768 def __getitem__(self
, Key
):
2771 ## Constructor of WorkspaceDatabase
2773 # @param DbPath Path of database file
2774 # @param GlobalMacros Global macros used for replacement during file parsing
2775 # @prarm RenewDb=False Create new database file if it's already there
2777 def __init__(self
, DbPath
, RenewDb
=False):
2778 self
._DbClosedFlag
= False
2780 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2782 # don't create necessary path for db in memory
2783 if DbPath
!= ':memory:':
2784 DbDir
= os
.path
.split(DbPath
)[0]
2785 if not os
.path
.exists(DbDir
):
2788 # remove db file in case inconsistency between db and file in file system
2789 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2792 # create db with optimized parameters
2793 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2794 self
.Conn
.execute("PRAGMA synchronous=OFF")
2795 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2796 self
.Conn
.execute("PRAGMA count_changes=OFF")
2797 self
.Conn
.execute("PRAGMA cache_size=8192")
2798 #self.Conn.execute("PRAGMA page_size=8192")
2800 # to avoid non-ascii character conversion issue
2801 self
.Conn
.text_factory
= str
2802 self
.Cur
= self
.Conn
.cursor()
2804 # create table for internal uses
2805 self
.TblDataModel
= TableDataModel(self
.Cur
)
2806 self
.TblFile
= TableFile(self
.Cur
)
2807 self
.Platform
= None
2809 # conversion object for build or file format conversion purpose
2810 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2811 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2813 ## Check whether workspace database need to be renew.
2814 # The renew reason maybe:
2815 # 1) If user force to renew;
2816 # 2) If user do not force renew, and
2817 # a) If the time of last modified python source is newer than database file;
2818 # b) If the time of last modified frozen executable file is newer than database file;
2820 # @param force User force renew database
2821 # @param DbPath The absolute path of workspace database file
2823 # @return Bool value for whether need renew workspace databse
2825 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2826 # if database does not exist, we need do nothing
2827 if not os
.path
.exists(DbPath
): return False
2829 # if user force to renew database, then not check whether database is out of date
2830 if force
: return True
2833 # Check the time of last modified source file or build.exe
2834 # if is newer than time of database, then database need to be re-created.
2836 timeOfToolModified
= 0
2837 if hasattr(sys
, "frozen"):
2838 exePath
= os
.path
.abspath(sys
.executable
)
2839 timeOfToolModified
= os
.stat(exePath
).st_mtime
2841 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2842 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2843 if rootPath
== "" or rootPath
== None:
2844 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2845 determine whether database file is out of date!\n")
2847 # walk the root path of source or build's binary to get the time last modified.
2849 for root
, dirs
, files
in os
.walk (rootPath
):
2851 # bypass source control folder
2852 if dir.lower() in [".svn", "_svn", "cvs"]:
2856 ext
= os
.path
.splitext(file)[1]
2857 if ext
.lower() == ".py": # only check .py files
2858 fd
= os
.stat(os
.path
.join(root
, file))
2859 if timeOfToolModified
< fd
.st_mtime
:
2860 timeOfToolModified
= fd
.st_mtime
2861 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2862 EdkLogger
.verbose("\nWorkspace database is out of data!")
2867 ## Initialize build database
2868 def InitDatabase(self
):
2869 EdkLogger
.verbose("\nInitialize build database started ...")
2874 self
.TblDataModel
.Create(False)
2875 self
.TblFile
.Create(False)
2878 # Initialize table DataModel
2880 self
.TblDataModel
.InitTable()
2881 EdkLogger
.verbose("Initialize build database ... DONE!")
2885 # @param Table: The instance of the table to be queried
2887 def QueryTable(self
, Table
):
2893 ## Close entire database
2896 # Close the connection and cursor
2899 if not self
._DbClosedFlag
:
2903 self
._DbClosedFlag
= True
2905 ## Summarize all packages in the database
2906 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2907 self
.Platform
= Platform
2909 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2911 # Get Package related to Modules
2913 for Module
in Pa
.Modules
:
2914 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2915 for Package
in ModuleObj
.Packages
:
2916 if Package
not in PackageList
:
2917 PackageList
.append(Package
)
2919 # Get Packages related to Libraries
2921 for Lib
in Pa
.LibraryInstances
:
2922 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2923 for Package
in LibObj
.Packages
:
2924 if Package
not in PackageList
:
2925 PackageList
.append(Package
)
2929 ## Summarize all platforms in the database
2930 def _GetPlatformList(self
):
2932 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2934 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2937 if Platform
!= None:
2938 PlatformList
.append(Platform
)
2941 PlatformList
= property(_GetPlatformList
)
2945 # This acts like the main() function for the script, unless it is 'import'ed into another
2948 if __name__
== '__main__':