2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
5 # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 import Common
.LongFilePathOs
as os
23 import Common
.EdkLogger
as EdkLogger
24 import Common
.GlobalData
as GlobalData
25 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
27 from Common
.String
import *
28 from Common
.DataType
import *
29 from Common
.Misc
import *
32 from CommonDataClass
.CommonClass
import SkuInfoClass
34 from MetaDataTable
import *
35 from MetaFileTable
import *
36 from MetaFileParser
import *
37 from BuildClassObject
import *
38 from WorkspaceCommon
import GetDeclaredPcd
39 from Common
.Misc
import AnalyzeDscPcd
40 from Common
.Misc
import ProcessDuplicatedInf
42 from Common
.Parsing
import IsValidWord
43 from Common
.VariableAttributes
import VariableAttributes
44 import Common
.GlobalData
as GlobalData
46 ## Platform build information from DSC file
48 # This class is used to retrieve information stored in database and convert them
49 # into PlatformBuildClassObject form for easier use for AutoGen.
51 class DscBuildData(PlatformBuildClassObject
):
52 # dict used to convert PCD type in database to string used by build tool
54 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
55 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
56 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
57 MODEL_PCD_DYNAMIC
: "Dynamic",
58 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
59 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
60 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
61 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
62 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
63 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
64 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
67 # dict used to convert part of [Defines] to members of DscBuildData directly
72 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
73 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
74 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
75 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
76 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
77 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
78 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
79 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
80 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
81 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
82 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
83 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
84 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
85 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
86 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
89 # used to compose dummy library class name for those forced library instances
90 _NullLibraryNumber
= 0
92 ## Constructor of DscBuildData
94 # Initialize object of DscBuildData
96 # @param FilePath The path of platform description file
97 # @param RawData The raw data of DSC file
98 # @param BuildDataBase Database used to retrieve module/package information
99 # @param Arch The target architecture
100 # @param Platform (not used for DscBuildData)
101 # @param Macros Macros used for replacement in DSC file
103 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
104 self
.MetaFile
= FilePath
105 self
._RawData
= RawData
106 self
._Bdb
= BuildDataBase
108 self
._Target
= Target
109 self
._Toolchain
= Toolchain
111 self
._HandleOverridePath
()
114 def __setitem__(self
, key
, value
):
115 self
.__dict
__[self
._PROPERTY
_[key
]] = value
118 def __getitem__(self
, key
):
119 return self
.__dict
__[self
._PROPERTY
_[key
]]
122 def __contains__(self
, key
):
123 return key
in self
._PROPERTY
_
125 ## Set all internal used members of DscBuildData to None
128 self
._PlatformName
= None
131 self
._DscSpecification
= None
132 self
._OutputDirectory
= None
133 self
._SupArchList
= None
134 self
._BuildTargets
= None
136 self
._SkuIdentifier
= None
137 self
._AvilableSkuIds
= None
138 self
._PcdInfoFlag
= None
139 self
._VarCheckFlag
= None
140 self
._FlashDefinition
= None
141 self
._Prebuild
= None
142 self
._Postbuild
= None
143 self
._BuildNumber
= None
144 self
._MakefileName
= None
145 self
._BsBaseAddress
= None
146 self
._RtBaseAddress
= None
149 self
._LibraryInstances
= None
150 self
._LibraryClasses
= None
153 self
._BuildOptions
= None
154 self
._ModuleTypeOptions
= None
155 self
._LoadFixAddress
= None
156 self
._RFCLanguages
= None
157 self
._ISOLanguages
= None
158 self
._VpdToolGuid
= None
162 ## handle Override Path of Module
163 def _HandleOverridePath(self
):
164 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
165 Macros
= self
._Macros
166 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
167 for Record
in RecordList
:
170 ModuleFile
= PathClass(NormPath(Record
[0]), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
171 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
173 SourceOverridePath
= mws
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0]))
175 # Check if the source override path exists
176 if not os
.path
.isdir(SourceOverridePath
):
177 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
='Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=SourceOverridePath
, Line
=LineNo
)
179 #Add to GlobalData Variables
180 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = SourceOverridePath
182 ## Get current effective macros
183 def _GetMacros(self
):
184 if self
.__Macros
== None:
186 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
187 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
188 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
197 # Changing the default ARCH to another may affect all other information
198 # because all information in a platform may be ARCH-related. That's
199 # why we need to clear all internal used members, in order to cause all
200 # information to be re-retrieved.
202 # @param Value The value of ARCH
204 def _SetArch(self
, Value
):
205 if self
._Arch
== Value
:
210 ## Retrieve all information in [Defines] section
212 # (Retriving all [Defines] information in one-shot is just to save time.)
214 def _GetHeaderInfo(self
):
215 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
216 for Record
in RecordList
:
218 # items defined _PROPERTY_ don't need additional processing
220 # some special items in [Defines] section need special treatment
221 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
222 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
223 if ' ' in self
._OutputDirectory
:
224 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
225 File
=self
.MetaFile
, Line
=Record
[-1],
226 ExtraData
=self
._OutputDirectory
)
227 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
228 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
229 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
231 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
233 elif Name
== TAB_DSC_PREBUILD
:
234 PrebuildValue
= Record
[2]
235 if Record
[2][0] == '"':
236 if Record
[2][-1] != '"':
237 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD
,
238 File
=self
.MetaFile
, Line
=Record
[-1])
239 PrebuildValue
= Record
[2][1:-1]
240 self
._Prebuild
= PathClass(NormPath(PrebuildValue
, self
._Macros
), GlobalData
.gWorkspace
)
241 elif Name
== TAB_DSC_POSTBUILD
:
242 PostbuildValue
= Record
[2]
243 if Record
[2][0] == '"':
244 if Record
[2][-1] != '"':
245 EdkLogger
.error('build', FORMAT_INVALID
, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD
,
246 File
=self
.MetaFile
, Line
=Record
[-1])
247 PostbuildValue
= Record
[2][1:-1]
248 self
._Postbuild
= PathClass(NormPath(PostbuildValue
, self
._Macros
), GlobalData
.gWorkspace
)
249 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
250 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
251 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
252 self
._BuildTargets
= GetSplitValueList(Record
[2])
253 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
254 if self
._SkuName
== None:
255 self
._SkuName
= Record
[2]
256 self
._SkuIdentifier
= Record
[2]
257 self
._AvilableSkuIds
= Record
[2]
258 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
259 self
._PcdInfoFlag
= Record
[2]
260 elif Name
== TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION
:
261 self
._VarCheckFlag
= Record
[2]
262 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
264 self
._LoadFixAddress
= int (Record
[2], 0)
266 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
267 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
268 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
269 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"',
270 File
=self
.MetaFile
, Line
=Record
[-1])
271 LanguageCodes
= Record
[2][1:-1]
272 if not LanguageCodes
:
273 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
274 File
=self
.MetaFile
, Line
=Record
[-1])
275 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
276 # check whether there is empty entries in the list
277 if None in LanguageList
:
278 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
279 File
=self
.MetaFile
, Line
=Record
[-1])
280 self
._RFCLanguages
= LanguageList
281 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
282 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
283 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
284 File
=self
.MetaFile
, Line
=Record
[-1])
285 LanguageCodes
= Record
[2][1:-1]
286 if not LanguageCodes
:
287 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
288 File
=self
.MetaFile
, Line
=Record
[-1])
289 if len(LanguageCodes
)%3:
290 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
291 File
=self
.MetaFile
, Line
=Record
[-1])
293 for i
in range(0, len(LanguageCodes
), 3):
294 LanguageList
.append(LanguageCodes
[i
:i
+3])
295 self
._ISOLanguages
= LanguageList
296 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
298 # try to convert GUID to a real UUID value to see whether the GUID is format
299 # for VPD_TOOL_GUID is correct.
304 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
305 self
._VpdToolGuid
= Record
[2]
307 self
[Name
] = Record
[2]
308 # set _Header to non-None in order to avoid database re-querying
309 self
._Header
= 'DUMMY'
311 ## Retrieve platform name
312 def _GetPlatformName(self
):
313 if self
._PlatformName
== None:
314 if self
._Header
== None:
315 self
._GetHeaderInfo
()
316 if self
._PlatformName
== None:
317 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
318 return self
._PlatformName
320 ## Retrieve file guid
321 def _GetFileGuid(self
):
322 if self
._Guid
== None:
323 if self
._Header
== None:
324 self
._GetHeaderInfo
()
325 if self
._Guid
== None:
326 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
329 ## Retrieve platform version
330 def _GetVersion(self
):
331 if self
._Version
== None:
332 if self
._Header
== None:
333 self
._GetHeaderInfo
()
334 if self
._Version
== None:
335 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
338 ## Retrieve platform description file version
339 def _GetDscSpec(self
):
340 if self
._DscSpecification
== None:
341 if self
._Header
== None:
342 self
._GetHeaderInfo
()
343 if self
._DscSpecification
== None:
344 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
345 return self
._DscSpecification
347 ## Retrieve OUTPUT_DIRECTORY
348 def _GetOutpuDir(self
):
349 if self
._OutputDirectory
== None:
350 if self
._Header
== None:
351 self
._GetHeaderInfo
()
352 if self
._OutputDirectory
== None:
353 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
354 return self
._OutputDirectory
356 ## Retrieve SUPPORTED_ARCHITECTURES
357 def _GetSupArch(self
):
358 if self
._SupArchList
== None:
359 if self
._Header
== None:
360 self
._GetHeaderInfo
()
361 if self
._SupArchList
== None:
362 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
363 return self
._SupArchList
365 ## Retrieve BUILD_TARGETS
366 def _GetBuildTarget(self
):
367 if self
._BuildTargets
== None:
368 if self
._Header
== None:
369 self
._GetHeaderInfo
()
370 if self
._BuildTargets
== None:
371 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
372 return self
._BuildTargets
374 def _GetPcdInfoFlag(self
):
375 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
377 elif self
._PcdInfoFlag
.upper() == 'TRUE':
381 def _GetVarCheckFlag(self
):
382 if self
._VarCheckFlag
== None or self
._VarCheckFlag
.upper() == 'FALSE':
384 elif self
._VarCheckFlag
.upper() == 'TRUE':
388 def _GetAviableSkuIds(self
):
389 if self
._AvilableSkuIds
:
390 return self
._AvilableSkuIds
391 return self
.SkuIdentifier
392 def _GetSkuIdentifier(self
):
395 if self
._SkuIdentifier
== None:
396 if self
._Header
== None:
397 self
._GetHeaderInfo
()
398 return self
._SkuIdentifier
399 ## Retrieve SKUID_IDENTIFIER
400 def _GetSkuName(self
):
401 if self
._SkuName
== None:
402 if self
._Header
== None:
403 self
._GetHeaderInfo
()
404 if (self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
):
405 self
._SkuName
= 'DEFAULT'
408 ## Override SKUID_IDENTIFIER
409 def _SetSkuName(self
, Value
):
410 self
._SkuName
= Value
413 def _GetFdfFile(self
):
414 if self
._FlashDefinition
== None:
415 if self
._Header
== None:
416 self
._GetHeaderInfo
()
417 if self
._FlashDefinition
== None:
418 self
._FlashDefinition
= ''
419 return self
._FlashDefinition
421 def _GetPrebuild(self
):
422 if self
._Prebuild
== None:
423 if self
._Header
== None:
424 self
._GetHeaderInfo
()
425 if self
._Prebuild
== None:
427 return self
._Prebuild
429 def _GetPostbuild(self
):
430 if self
._Postbuild
== None:
431 if self
._Header
== None:
432 self
._GetHeaderInfo
()
433 if self
._Postbuild
== None:
435 return self
._Postbuild
437 ## Retrieve FLASH_DEFINITION
438 def _GetBuildNumber(self
):
439 if self
._BuildNumber
== None:
440 if self
._Header
== None:
441 self
._GetHeaderInfo
()
442 if self
._BuildNumber
== None:
443 self
._BuildNumber
= ''
444 return self
._BuildNumber
446 ## Retrieve MAKEFILE_NAME
447 def _GetMakefileName(self
):
448 if self
._MakefileName
== None:
449 if self
._Header
== None:
450 self
._GetHeaderInfo
()
451 if self
._MakefileName
== None:
452 self
._MakefileName
= ''
453 return self
._MakefileName
455 ## Retrieve BsBaseAddress
456 def _GetBsBaseAddress(self
):
457 if self
._BsBaseAddress
== None:
458 if self
._Header
== None:
459 self
._GetHeaderInfo
()
460 if self
._BsBaseAddress
== None:
461 self
._BsBaseAddress
= ''
462 return self
._BsBaseAddress
464 ## Retrieve RtBaseAddress
465 def _GetRtBaseAddress(self
):
466 if self
._RtBaseAddress
== None:
467 if self
._Header
== None:
468 self
._GetHeaderInfo
()
469 if self
._RtBaseAddress
== None:
470 self
._RtBaseAddress
= ''
471 return self
._RtBaseAddress
473 ## Retrieve the top address for the load fix address
474 def _GetLoadFixAddress(self
):
475 if self
._LoadFixAddress
== None:
476 if self
._Header
== None:
477 self
._GetHeaderInfo
()
479 if self
._LoadFixAddress
== None:
480 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
483 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
485 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
488 # If command line defined, should override the value in DSC file.
490 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
492 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
494 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']))
496 if self
._LoadFixAddress
< 0:
497 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
498 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
499 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
501 return self
._LoadFixAddress
503 ## Retrieve RFCLanguage filter
504 def _GetRFCLanguages(self
):
505 if self
._RFCLanguages
== None:
506 if self
._Header
== None:
507 self
._GetHeaderInfo
()
508 if self
._RFCLanguages
== None:
509 self
._RFCLanguages
= []
510 return self
._RFCLanguages
512 ## Retrieve ISOLanguage filter
513 def _GetISOLanguages(self
):
514 if self
._ISOLanguages
== None:
515 if self
._Header
== None:
516 self
._GetHeaderInfo
()
517 if self
._ISOLanguages
== None:
518 self
._ISOLanguages
= []
519 return self
._ISOLanguages
520 ## Retrieve the GUID string for VPD tool
521 def _GetVpdToolGuid(self
):
522 if self
._VpdToolGuid
== None:
523 if self
._Header
== None:
524 self
._GetHeaderInfo
()
525 if self
._VpdToolGuid
== None:
526 self
._VpdToolGuid
= ''
527 return self
._VpdToolGuid
529 ## Retrieve [SkuIds] section information
530 def _GetSkuIds(self
):
531 if self
._SkuIds
== None:
532 self
._SkuIds
= sdict()
533 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
534 for Record
in RecordList
:
535 if Record
[0] in [None, '']:
536 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
537 File
=self
.MetaFile
, Line
=Record
[-1])
538 if Record
[1] in [None, '']:
539 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
540 File
=self
.MetaFile
, Line
=Record
[-1])
541 self
._SkuIds
[Record
[1]] = Record
[0]
542 if 'DEFAULT' not in self
._SkuIds
:
543 self
._SkuIds
['DEFAULT'] = '0'
544 if 'COMMON' not in self
._SkuIds
:
545 self
._SkuIds
['COMMON'] = '0'
548 ## Retrieve [Components] section information
549 def _GetModules(self
):
550 if self
._Modules
!= None:
553 self
._Modules
= sdict()
554 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
555 Macros
= self
._Macros
556 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
557 for Record
in RecordList
:
558 DuplicatedFile
= False
560 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
564 # check the file validation
565 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
567 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
570 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
571 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
572 DuplicatedFile
= True
574 Module
= ModuleBuildClassObject()
575 Module
.MetaFile
= ModuleFile
577 # get module private library instance
578 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
579 for Record
in RecordList
:
580 LibraryClass
= Record
[0]
581 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
584 # check the file validation
585 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
587 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
590 if LibraryClass
== '' or LibraryClass
== 'NULL':
591 self
._NullLibraryNumber
+= 1
592 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
593 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
594 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
595 if LibraryPath
not in self
.LibraryInstances
:
596 self
.LibraryInstances
.append(LibraryPath
)
598 # get module private PCD setting
599 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
600 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
601 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
602 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
603 TokenList
= GetSplitValueList(Setting
)
604 DefaultValue
= TokenList
[0]
605 if len(TokenList
) > 1:
606 MaxDatumSize
= TokenList
[1]
609 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
610 Pcd
= PcdClassObject(
622 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
624 # get module private build options
625 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
626 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
627 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
628 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
630 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
631 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
633 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, None, ModuleId
]
634 if DuplicatedFile
and not RecordList
:
635 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
637 if len(RecordList
) != 1:
638 EdkLogger
.error('build', OPTION_UNKNOWN
, 'Only FILE_GUID can be listed in <Defines> section.',
639 File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
640 ModuleFile
= ProcessDuplicatedInf(ModuleFile
, RecordList
[0][2], GlobalData
.gWorkspace
)
641 ModuleFile
.Arch
= self
._Arch
643 self
._Modules
[ModuleFile
] = Module
646 ## Retrieve all possible library instances used in this platform
647 def _GetLibraryInstances(self
):
648 if self
._LibraryInstances
== None:
649 self
._GetLibraryClasses
()
650 return self
._LibraryInstances
652 ## Retrieve [LibraryClasses] information
653 def _GetLibraryClasses(self
):
654 if self
._LibraryClasses
== None:
655 self
._LibraryInstances
= []
657 # tdict is a special dict kind of type, used for selecting correct
658 # library instance for given library class and module type
660 LibraryClassDict
= tdict(True, 3)
661 # track all library class names
662 LibraryClassSet
= set()
663 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
664 Macros
= self
._Macros
665 for Record
in RecordList
:
666 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
667 if LibraryClass
== '' or LibraryClass
== 'NULL':
668 self
._NullLibraryNumber
+= 1
669 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
670 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
671 LibraryClassSet
.add(LibraryClass
)
672 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
673 # check the file validation
674 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
676 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
679 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
680 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
681 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
682 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
683 if LibraryInstance
not in self
._LibraryInstances
:
684 self
._LibraryInstances
.append(LibraryInstance
)
686 # resolve the specific library instance for each class and each module type
687 self
._LibraryClasses
= tdict(True)
688 for LibraryClass
in LibraryClassSet
:
689 # try all possible module types
690 for ModuleType
in SUP_MODULE_LIST
:
691 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
692 if LibraryInstance
== None:
694 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
696 # for Edk style library instances, which are listed in different section
697 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
698 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
699 for Record
in RecordList
:
700 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
702 # check the file validation
703 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
705 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
707 if File
not in self
._LibraryInstances
:
708 self
._LibraryInstances
.append(File
)
710 # we need the module name as the library class name, so we have
711 # to parse it here. (self._Bdb[] will trigger a file parse if it
712 # hasn't been parsed)
714 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
715 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
716 return self
._LibraryClasses
718 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
719 if self
._DecPcds
== None:
720 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
722 if GlobalData
.gFdfParser
:
723 FdfInfList
= GlobalData
.gFdfParser
.Profile
.InfList
726 for Inf
in FdfInfList
:
727 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
728 if ModuleFile
in self
._Modules
:
730 ModuleData
= self
._Bdb
[ModuleFile
, self
._Arch
, self
._Target
, self
._Toolchain
]
731 PkgSet
.update(ModuleData
.Packages
)
735 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
736 self
._DecPcds
.update(DecPcds
)
738 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
739 EdkLogger
.error('build', PARSER_ERROR
,
740 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid
, PcdCName
, self
._Arch
),
741 File
=self
.MetaFile
, Line
=LineNo
)
742 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
743 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
744 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
745 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
746 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
748 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
749 except WrnExpression
, Value
:
750 ValueList
[Index
] = Value
.result
751 except EvaluationException
, Excpt
:
752 if hasattr(Excpt
, 'Pcd'):
753 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
754 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
755 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
756 " of the DSC file" % Excpt
.Pcd
,
757 File
=self
.MetaFile
, Line
=LineNo
)
759 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
760 File
=self
.MetaFile
, Line
=LineNo
)
762 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
763 File
=self
.MetaFile
, Line
=LineNo
)
764 if ValueList
[Index
] == 'True':
765 ValueList
[Index
] = '1'
766 elif ValueList
[Index
] == 'False':
767 ValueList
[Index
] = '0'
769 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
771 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
772 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
775 ## Retrieve all PCD settings in platform
777 if self
._Pcds
== None:
779 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
780 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
781 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
782 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
783 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
784 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
785 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
786 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
787 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
790 ## Retrieve [BuildOptions]
791 def _GetBuildOptions(self
):
792 if self
._BuildOptions
== None:
793 self
._BuildOptions
= sdict()
795 # Retrieve build option for EDKII and EDK style module
797 for CodeBase
in (EDKII_NAME
, EDK_NAME
):
798 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, CodeBase
]
799 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
800 CurKey
= (ToolChainFamily
, ToolChain
, CodeBase
)
802 # Only flags can be appended
804 if CurKey
not in self
._BuildOptions
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
805 self
._BuildOptions
[CurKey
] = Option
807 self
._BuildOptions
[CurKey
] += ' ' + Option
808 return self
._BuildOptions
810 def GetBuildOptionsByModuleType(self
, Edk
, ModuleType
):
811 if self
._ModuleTypeOptions
== None:
812 self
._ModuleTypeOptions
= sdict()
813 if (Edk
, ModuleType
) not in self
._ModuleTypeOptions
:
815 self
._ModuleTypeOptions
[Edk
, ModuleType
] = options
816 DriverType
= '%s.%s' % (Edk
, ModuleType
)
817 CommonDriverType
= '%s.%s' % ('COMMON', ModuleType
)
818 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, DriverType
]
819 for ToolChainFamily
, ToolChain
, Option
, Arch
, Type
, Dummy3
, Dummy4
in RecordList
:
820 if Type
== DriverType
or Type
== CommonDriverType
:
821 Key
= (ToolChainFamily
, ToolChain
, Edk
)
822 if Key
not in options
or not ToolChain
.endswith('_FLAGS') or Option
.startswith('='):
823 options
[Key
] = Option
825 options
[Key
] += ' ' + Option
826 return self
._ModuleTypeOptions
[Edk
, ModuleType
]
828 ## Retrieve non-dynamic PCD settings
830 # @param Type PCD type
832 # @retval a dict object contains settings of given PCD type
834 def _GetPcd(self
, Type
):
837 # tdict is a special dict kind of type, used for selecting correct
838 # PCD settings for certain ARCH
841 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
843 PcdDict
= tdict(True, 3)
845 # Find out all possible PCD candidates for self._Arch
846 RecordList
= self
._RawData
[Type
, self
._Arch
]
847 PcdValueDict
= sdict()
848 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
849 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
850 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
851 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
853 #handle pcd value override
854 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
855 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
858 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
859 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
860 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
862 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
864 PcdsKeys
= PcdValueDict
.keys()
865 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
867 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
871 if 'COMMON' in PcdSetting
:
872 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
873 if 'DEFAULT' in PcdSetting
:
874 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
875 if SkuObj
.SystemSkuId
in PcdSetting
:
876 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
878 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
881 self
._PCD
_TYPE
_STRING
_[Type
],
892 ## Retrieve dynamic PCD settings
894 # @param Type PCD type
896 # @retval a dict object contains settings of given PCD type
898 def _GetDynamicPcd(self
, Type
):
900 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
904 # tdict is a special dict kind of type, used for selecting correct
905 # PCD settings for certain ARCH and SKU
907 PcdDict
= tdict(True, 4)
909 # Find out all possible PCD candidates for self._Arch
910 RecordList
= self
._RawData
[Type
, self
._Arch
]
911 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
913 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
914 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
915 if SkuName
not in AvailableSkuIdSet
:
918 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
919 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
920 # Remove redundant PCD candidates, per the ARCH and SKU
921 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
923 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
927 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
928 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
929 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
930 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
931 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
932 if MaxDatumSize
.strip():
933 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
936 if pcdObject
.MaxDatumSize
:
937 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
940 if CurrentMaxSize
> PcdMaxSize
:
941 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
943 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
946 self
._PCD
_TYPE
_STRING
_[Type
],
956 for pcd
in Pcds
.values():
957 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
958 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
959 valuefromDec
= pcdDecObject
.DefaultValue
960 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
961 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
962 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
963 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
964 del(pcd
.SkuInfoList
['COMMON'])
965 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
966 del(pcd
.SkuInfoList
['COMMON'])
967 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
968 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
969 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
970 del(pcd
.SkuInfoList
['DEFAULT'])
974 def CompareVarAttr(self
, Attr1
, Attr2
):
975 if not Attr1
or not Attr2
: # for empty string
977 Attr1s
= [attr
.strip() for attr
in Attr1
.split(",")]
978 Attr1Set
= set(Attr1s
)
979 Attr2s
= [attr
.strip() for attr
in Attr2
.split(",")]
980 Attr2Set
= set(Attr2s
)
981 if Attr2Set
== Attr1Set
:
985 ## Retrieve dynamic HII PCD settings
987 # @param Type PCD type
989 # @retval a dict object contains settings of given PCD type
991 def _GetDynamicHiiPcd(self
, Type
):
993 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
998 # tdict is a special dict kind of type, used for selecting correct
999 # PCD settings for certain ARCH and SKU
1001 PcdDict
= tdict(True, 4)
1003 RecordList
= self
._RawData
[Type
, self
._Arch
]
1004 # Find out all possible PCD candidates for self._Arch
1005 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1007 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1008 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1009 if SkuName
not in AvailableSkuIdSet
:
1011 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
1012 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1013 # Remove redundant PCD candidates, per the ARCH and SKU
1014 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
1016 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1019 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VarAttribute
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1021 rt
, Msg
= VariableAttributes
.ValidateVarAttributes(VarAttribute
)
1023 EdkLogger
.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR
, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid
, PcdCName
)), Msg
),
1024 ExtraData
= "[%s]" % VarAttribute
)
1026 FormatCorrect
= True
1027 if VariableOffset
.isdigit():
1028 if int(VariableOffset
,10) > 0xFFFF:
1030 elif re
.match(r
'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset
):
1031 if int(VariableOffset
,16) > 0xFFFF:
1033 # For Offset written in "A.B"
1034 elif VariableOffset
.find('.') > -1:
1035 VariableOffsetList
= VariableOffset
.split(".")
1036 if not (len(VariableOffsetList
) == 2
1037 and IsValidWord(VariableOffsetList
[0])
1038 and IsValidWord(VariableOffsetList
[1])):
1039 FormatCorrect
= False
1041 FormatCorrect
= False
1042 if not FormatCorrect
:
1043 EdkLogger
.error('Build', FORMAT_INVALID
, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1046 EdkLogger
.error('Build', OPTION_VALUE_INVALID
, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid
,PcdCName
)))
1047 if (VariableName
, VariableGuid
) not in VariableAttrs
:
1048 VariableAttrs
[(VariableName
, VariableGuid
)] = VarAttribute
1050 if not self
.CompareVarAttr(VariableAttrs
[(VariableName
, VariableGuid
)], VarAttribute
):
1051 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
)]))
1053 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
, VariableAttribute
= VarAttribute
)
1054 pcdDecObject
= self
._DecPcds
[PcdCName
, TokenSpaceGuid
]
1055 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1056 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1057 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1059 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1062 self
._PCD
_TYPE
_STRING
_[Type
],
1067 {SkuName
: SkuInfo
},
1070 pcdDecObject
.validateranges
,
1071 pcdDecObject
.validlists
,
1072 pcdDecObject
.expressions
1076 for pcd
in Pcds
.values():
1077 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1078 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1079 # Only fix the value while no value provided in DSC file.
1080 for sku
in pcd
.SkuInfoList
.values():
1081 if (sku
.HiiDefaultValue
== "" or sku
.HiiDefaultValue
==None):
1082 sku
.HiiDefaultValue
= pcdDecObject
.DefaultValue
1083 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1084 valuefromDec
= pcdDecObject
.DefaultValue
1085 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
1086 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1087 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1088 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1089 del(pcd
.SkuInfoList
['COMMON'])
1090 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1091 del(pcd
.SkuInfoList
['COMMON'])
1093 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1094 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1095 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1096 del(pcd
.SkuInfoList
['DEFAULT'])
1099 if pcd
.MaxDatumSize
.strip():
1100 MaxSize
= int(pcd
.MaxDatumSize
,0)
1103 if pcdDecObject
.DatumType
== 'VOID*':
1104 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1106 if skuobj
.HiiDefaultValue
.startswith("L"):
1107 datalen
= (len(skuobj
.HiiDefaultValue
)- 3 + 1) * 2
1108 elif skuobj
.HiiDefaultValue
.startswith("{"):
1109 datalen
= len(skuobj
.HiiDefaultValue
.split(","))
1111 datalen
= len(skuobj
.HiiDefaultValue
) -2 + 1
1114 pcd
.MaxDatumSize
= str(MaxSize
)
1117 ## Retrieve dynamic VPD PCD settings
1119 # @param Type PCD type
1121 # @retval a dict object contains settings of given PCD type
1123 def _GetDynamicVpdPcd(self
, Type
):
1125 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
1129 # tdict is a special dict kind of type, used for selecting correct
1130 # PCD settings for certain ARCH and SKU
1132 PcdDict
= tdict(True, 4)
1134 # Find out all possible PCD candidates for self._Arch
1135 RecordList
= self
._RawData
[Type
, self
._Arch
]
1136 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
1138 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
1139 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
1140 if SkuName
not in AvailableSkuIdSet
:
1143 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
1144 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
1145 # Remove redundant PCD candidates, per the ARCH and SKU
1146 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
1147 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
1151 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
1152 # For the Integer & Boolean type, the optional data can only be InitialValue.
1153 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
1154 # until the DEC parser has been called.
1156 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
1157 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
1158 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
1159 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
1160 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
1161 if MaxDatumSize
.strip():
1162 CurrentMaxSize
= int(MaxDatumSize
.strip(),0)
1165 if pcdObject
.MaxDatumSize
:
1166 PcdMaxSize
= int(pcdObject
.MaxDatumSize
,0)
1169 if CurrentMaxSize
> PcdMaxSize
:
1170 pcdObject
.MaxDatumSize
= str(CurrentMaxSize
)
1172 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
1175 self
._PCD
_TYPE
_STRING
_[Type
],
1180 {SkuName
: SkuInfo
},
1184 for pcd
in Pcds
.values():
1185 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
1186 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
1187 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
1188 valuefromDec
= pcdDecObject
.DefaultValue
1189 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
1190 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
1191 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1192 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1193 del(pcd
.SkuInfoList
['COMMON'])
1194 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1195 del(pcd
.SkuInfoList
['COMMON'])
1196 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1197 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1198 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1199 del(pcd
.SkuInfoList
['DEFAULT'])
1203 ## Add external modules
1205 # The external modules are mostly those listed in FDF file, which don't
1208 # @param FilePath The path of module description file
1210 def AddModule(self
, FilePath
):
1211 FilePath
= NormPath(FilePath
)
1212 if FilePath
not in self
.Modules
:
1213 Module
= ModuleBuildClassObject()
1214 Module
.MetaFile
= FilePath
1215 self
.Modules
.append(Module
)
1217 ## Add external PCDs
1219 # The external PCDs are mostly those listed in FDF file to specify address
1220 # or offset information.
1222 # @param Name Name of the PCD
1223 # @param Guid Token space guid of the PCD
1224 # @param Value Value of the PCD
1226 def AddPcd(self
, Name
, Guid
, Value
):
1227 if (Name
, Guid
) not in self
.Pcds
:
1228 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1229 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1231 _Macros
= property(_GetMacros
)
1232 Arch
= property(_GetArch
, _SetArch
)
1233 Platform
= property(_GetPlatformName
)
1234 PlatformName
= property(_GetPlatformName
)
1235 Guid
= property(_GetFileGuid
)
1236 Version
= property(_GetVersion
)
1237 DscSpecification
= property(_GetDscSpec
)
1238 OutputDirectory
= property(_GetOutpuDir
)
1239 SupArchList
= property(_GetSupArch
)
1240 BuildTargets
= property(_GetBuildTarget
)
1241 SkuName
= property(_GetSkuName
, _SetSkuName
)
1242 SkuIdentifier
= property(_GetSkuIdentifier
)
1243 AvilableSkuIds
= property(_GetAviableSkuIds
)
1244 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1245 VarCheckFlag
= property(_GetVarCheckFlag
)
1246 FlashDefinition
= property(_GetFdfFile
)
1247 Prebuild
= property(_GetPrebuild
)
1248 Postbuild
= property(_GetPostbuild
)
1249 BuildNumber
= property(_GetBuildNumber
)
1250 MakefileName
= property(_GetMakefileName
)
1251 BsBaseAddress
= property(_GetBsBaseAddress
)
1252 RtBaseAddress
= property(_GetRtBaseAddress
)
1253 LoadFixAddress
= property(_GetLoadFixAddress
)
1254 RFCLanguages
= property(_GetRFCLanguages
)
1255 ISOLanguages
= property(_GetISOLanguages
)
1256 VpdToolGuid
= property(_GetVpdToolGuid
)
1257 SkuIds
= property(_GetSkuIds
)
1258 Modules
= property(_GetModules
)
1259 LibraryInstances
= property(_GetLibraryInstances
)
1260 LibraryClasses
= property(_GetLibraryClasses
)
1261 Pcds
= property(_GetPcds
)
1262 BuildOptions
= property(_GetBuildOptions
)
1264 ## Platform build information from DEC file
1266 # This class is used to retrieve information stored in database and convert them
1267 # into PackageBuildClassObject form for easier use for AutoGen.
1269 class DecBuildData(PackageBuildClassObject
):
1270 # dict used to convert PCD type in database to string used by build tool
1271 _PCD_TYPE_STRING_
= {
1272 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1273 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1274 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1275 MODEL_PCD_DYNAMIC
: "Dynamic",
1276 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1277 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1278 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1279 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1280 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1281 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1282 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1285 # dict used to convert part of [Defines] to members of DecBuildData directly
1290 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1291 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1292 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1293 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1297 ## Constructor of DecBuildData
1299 # Initialize object of DecBuildData
1301 # @param FilePath The path of package description file
1302 # @param RawData The raw data of DEC file
1303 # @param BuildDataBase Database used to retrieve module information
1304 # @param Arch The target architecture
1305 # @param Platform (not used for DecBuildData)
1306 # @param Macros Macros used for replacement in DSC file
1308 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1309 self
.MetaFile
= File
1310 self
._PackageDir
= File
.Dir
1311 self
._RawData
= RawData
1312 self
._Bdb
= BuildDataBase
1314 self
._Target
= Target
1315 self
._Toolchain
= Toolchain
1319 def __setitem__(self
, key
, value
):
1320 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1323 def __getitem__(self
, key
):
1324 return self
.__dict
__[self
._PROPERTY
_[key
]]
1326 ## "in" test support
1327 def __contains__(self
, key
):
1328 return key
in self
._PROPERTY
_
1330 ## Set all internal used members of DecBuildData to None
1333 self
._PackageName
= None
1335 self
._Version
= None
1336 self
._PkgUniFile
= None
1337 self
._Protocols
= None
1340 self
._Includes
= None
1341 self
._LibraryClasses
= None
1343 self
.__Macros
= None
1344 self
._PrivateProtocols
= None
1345 self
._PrivatePpis
= None
1346 self
._PrivateGuids
= None
1347 self
._PrivateIncludes
= None
1349 ## Get current effective macros
1350 def _GetMacros(self
):
1351 if self
.__Macros
== None:
1353 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1354 return self
.__Macros
1362 # Changing the default ARCH to another may affect all other information
1363 # because all information in a platform may be ARCH-related. That's
1364 # why we need to clear all internal used members, in order to cause all
1365 # information to be re-retrieved.
1367 # @param Value The value of ARCH
1369 def _SetArch(self
, Value
):
1370 if self
._Arch
== Value
:
1375 ## Retrieve all information in [Defines] section
1377 # (Retriving all [Defines] information in one-shot is just to save time.)
1379 def _GetHeaderInfo(self
):
1380 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1381 for Record
in RecordList
:
1384 self
[Name
] = Record
[2]
1385 self
._Header
= 'DUMMY'
1387 ## Retrieve package name
1388 def _GetPackageName(self
):
1389 if self
._PackageName
== None:
1390 if self
._Header
== None:
1391 self
._GetHeaderInfo
()
1392 if self
._PackageName
== None:
1393 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1394 return self
._PackageName
1396 ## Retrieve file guid
1397 def _GetFileGuid(self
):
1398 if self
._Guid
== None:
1399 if self
._Header
== None:
1400 self
._GetHeaderInfo
()
1401 if self
._Guid
== None:
1402 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1405 ## Retrieve package version
1406 def _GetVersion(self
):
1407 if self
._Version
== None:
1408 if self
._Header
== None:
1409 self
._GetHeaderInfo
()
1410 if self
._Version
== None:
1412 return self
._Version
1414 ## Retrieve protocol definitions (name/value pairs)
1415 def _GetProtocol(self
):
1416 if self
._Protocols
== None:
1418 # tdict is a special kind of dict, used for selecting correct
1419 # protocol defition for given ARCH
1421 ProtocolDict
= tdict(True)
1422 PrivateProtocolDict
= tdict(True)
1424 PrivateNameList
= []
1426 # find out all protocol definitions for specific and 'common' arch
1427 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1428 for Name
, Guid
, Dummy
, Arch
, PrivateFlag
, ID
, LineNo
in RecordList
:
1429 if PrivateFlag
== 'PRIVATE':
1430 if Name
not in PrivateNameList
:
1431 PrivateNameList
.append(Name
)
1432 PrivateProtocolDict
[Arch
, Name
] = Guid
1433 if Name
in PublicNameList
:
1434 EdkLogger
.error('build', OPTION_CONFLICT
, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name
, File
=self
.MetaFile
, Line
=LineNo
)
1436 if Name
not in PublicNameList
:
1437 PublicNameList
.append(Name
)
1438 if Name
in PrivateNameList
:
1439 EdkLogger
.error('build', OPTION_CONFLICT
, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name
, File
=self
.MetaFile
, Line
=LineNo
)
1440 if Name
not in NameList
:
1441 NameList
.append(Name
)
1442 ProtocolDict
[Arch
, Name
] = Guid
1443 # use sdict to keep the order
1444 self
._Protocols
= sdict()
1445 self
._PrivateProtocols
= sdict()
1446 for Name
in NameList
:
1448 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1449 # will automatically turn to 'common' ARCH for trying
1451 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1452 for Name
in PrivateNameList
:
1453 self
._PrivateProtocols
[Name
] = PrivateProtocolDict
[self
._Arch
, Name
]
1454 return self
._Protocols
1456 ## Retrieve PPI definitions (name/value pairs)
1458 if self
._Ppis
== None:
1460 # tdict is a special kind of dict, used for selecting correct
1461 # PPI defition for given ARCH
1463 PpiDict
= tdict(True)
1464 PrivatePpiDict
= tdict(True)
1466 PrivateNameList
= []
1468 # find out all PPI definitions for specific arch and 'common' arch
1469 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1470 for Name
, Guid
, Dummy
, Arch
, PrivateFlag
, ID
, LineNo
in RecordList
:
1471 if PrivateFlag
== 'PRIVATE':
1472 if Name
not in PrivateNameList
:
1473 PrivateNameList
.append(Name
)
1474 PrivatePpiDict
[Arch
, Name
] = Guid
1475 if Name
in PublicNameList
:
1476 EdkLogger
.error('build', OPTION_CONFLICT
, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name
, File
=self
.MetaFile
, Line
=LineNo
)
1478 if Name
not in PublicNameList
:
1479 PublicNameList
.append(Name
)
1480 if Name
in PrivateNameList
:
1481 EdkLogger
.error('build', OPTION_CONFLICT
, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name
, File
=self
.MetaFile
, Line
=LineNo
)
1482 if Name
not in NameList
:
1483 NameList
.append(Name
)
1484 PpiDict
[Arch
, Name
] = Guid
1485 # use sdict to keep the order
1486 self
._Ppis
= sdict()
1487 self
._PrivatePpis
= sdict()
1488 for Name
in NameList
:
1490 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1491 # will automatically turn to 'common' ARCH for trying
1493 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1494 for Name
in PrivateNameList
:
1495 self
._PrivatePpis
[Name
] = PrivatePpiDict
[self
._Arch
, Name
]
1498 ## Retrieve GUID definitions (name/value pairs)
1500 if self
._Guids
== None:
1502 # tdict is a special kind of dict, used for selecting correct
1503 # GUID defition for given ARCH
1505 GuidDict
= tdict(True)
1506 PrivateGuidDict
= tdict(True)
1508 PrivateNameList
= []
1510 # find out all protocol definitions for specific and 'common' arch
1511 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1512 for Name
, Guid
, Dummy
, Arch
, PrivateFlag
, ID
, LineNo
in RecordList
:
1513 if PrivateFlag
== 'PRIVATE':
1514 if Name
not in PrivateNameList
:
1515 PrivateNameList
.append(Name
)
1516 PrivateGuidDict
[Arch
, Name
] = Guid
1517 if Name
in PublicNameList
:
1518 EdkLogger
.error('build', OPTION_CONFLICT
, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name
, File
=self
.MetaFile
, Line
=LineNo
)
1520 if Name
not in PublicNameList
:
1521 PublicNameList
.append(Name
)
1522 if Name
in PrivateNameList
:
1523 EdkLogger
.error('build', OPTION_CONFLICT
, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name
, File
=self
.MetaFile
, Line
=LineNo
)
1524 if Name
not in NameList
:
1525 NameList
.append(Name
)
1526 GuidDict
[Arch
, Name
] = Guid
1527 # use sdict to keep the order
1528 self
._Guids
= sdict()
1529 self
._PrivateGuids
= sdict()
1530 for Name
in NameList
:
1532 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1533 # will automatically turn to 'common' ARCH for trying
1535 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1536 for Name
in PrivateNameList
:
1537 self
._PrivateGuids
[Name
] = PrivateGuidDict
[self
._Arch
, Name
]
1540 ## Retrieve public include paths declared in this package
1541 def _GetInclude(self
):
1542 if self
._Includes
== None:
1544 self
._PrivateIncludes
= []
1546 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1547 Macros
= self
._Macros
1548 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1549 for Record
in RecordList
:
1550 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1553 ErrorCode
, ErrorInfo
= File
.Validate()
1555 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1557 # avoid duplicate include path
1558 if File
not in self
._Includes
:
1559 self
._Includes
.append(File
)
1560 if Record
[4] == 'PRIVATE':
1561 if File
not in self
._PrivateIncludes
:
1562 self
._PrivateIncludes
.append(File
)
1563 if File
in PublicInclues
:
1564 EdkLogger
.error('build', OPTION_CONFLICT
, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File
, File
=self
.MetaFile
, Line
=LineNo
)
1566 if File
not in PublicInclues
:
1567 PublicInclues
.append(File
)
1568 if File
in self
._PrivateIncludes
:
1569 EdkLogger
.error('build', OPTION_CONFLICT
, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File
, File
=self
.MetaFile
, Line
=LineNo
)
1571 return self
._Includes
1573 ## Retrieve library class declarations (not used in build at present)
1574 def _GetLibraryClass(self
):
1575 if self
._LibraryClasses
== None:
1577 # tdict is a special kind of dict, used for selecting correct
1578 # library class declaration for given ARCH
1580 LibraryClassDict
= tdict(True)
1581 LibraryClassSet
= set()
1582 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1583 Macros
= self
._Macros
1584 for LibraryClass
, File
, Dummy
, Arch
, PrivateFlag
, ID
, LineNo
in RecordList
:
1585 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1586 # check the file validation
1587 ErrorCode
, ErrorInfo
= File
.Validate()
1589 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1590 LibraryClassSet
.add(LibraryClass
)
1591 LibraryClassDict
[Arch
, LibraryClass
] = File
1592 self
._LibraryClasses
= sdict()
1593 for LibraryClass
in LibraryClassSet
:
1594 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1595 return self
._LibraryClasses
1597 ## Retrieve PCD declarations
1599 if self
._Pcds
== None:
1600 self
._Pcds
= sdict()
1601 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1602 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1603 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1604 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1605 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1608 ## Retrieve PCD declarations for given type
1609 def _GetPcd(self
, Type
):
1612 # tdict is a special kind of dict, used for selecting correct
1613 # PCD declaration for given ARCH
1615 PcdDict
= tdict(True, 3)
1616 # for summarizing PCD
1618 # find out all PCDs of the 'type'
1619 RecordList
= self
._RawData
[Type
, self
._Arch
]
1620 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, PrivateFlag
, Dummy1
, Dummy2
in RecordList
:
1621 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1622 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1624 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1626 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1627 # will automatically turn to 'common' ARCH and try again
1629 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1633 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1635 validateranges
, validlists
, expressions
= self
._RawData
.GetValidExpression(TokenSpaceGuid
, PcdCName
)
1636 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1639 self
._PCD
_TYPE
_STRING
_[Type
],
1647 list(validateranges
),
1654 _Macros
= property(_GetMacros
)
1655 Arch
= property(_GetArch
, _SetArch
)
1656 PackageName
= property(_GetPackageName
)
1657 Guid
= property(_GetFileGuid
)
1658 Version
= property(_GetVersion
)
1660 Protocols
= property(_GetProtocol
)
1661 Ppis
= property(_GetPpi
)
1662 Guids
= property(_GetGuid
)
1663 Includes
= property(_GetInclude
)
1664 LibraryClasses
= property(_GetLibraryClass
)
1665 Pcds
= property(_GetPcds
)
1667 ## Module build information from INF file
1669 # This class is used to retrieve information stored in database and convert them
1670 # into ModuleBuildClassObject form for easier use for AutoGen.
1672 class InfBuildData(ModuleBuildClassObject
):
1673 # dict used to convert PCD type in database to string used by build tool
1674 _PCD_TYPE_STRING_
= {
1675 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1676 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1677 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1678 MODEL_PCD_DYNAMIC
: "Dynamic",
1679 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1680 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1681 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1682 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1683 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1684 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1685 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1688 # dict used to convert part of [Defines] to members of InfBuildData directly
1693 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1694 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1695 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1699 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1700 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1701 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1702 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1703 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1704 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1705 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1706 TAB_INF_DEFINES_VERSION
: "_Version",
1707 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1708 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1710 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1713 # dict used to convert Component type to Module type
1716 "SECURITY_CORE" : "SEC",
1717 "PEI_CORE" : "PEI_CORE",
1718 "COMBINED_PEIM_DRIVER" : "PEIM",
1719 "PIC_PEIM" : "PEIM",
1720 "RELOCATABLE_PEIM" : "PEIM",
1721 "PE32_PEIM" : "PEIM",
1722 "BS_DRIVER" : "DXE_DRIVER",
1723 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1724 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1725 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1726 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1727 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1728 # "BS_DRIVER" : "UEFI_DRIVER",
1729 "APPLICATION" : "UEFI_APPLICATION",
1733 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1734 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1735 # dict used to convert old tool name used in [nmake] section to new ones
1743 ## Constructor of DscBuildData
1745 # Initialize object of DscBuildData
1747 # @param FilePath The path of platform description file
1748 # @param RawData The raw data of DSC file
1749 # @param BuildDataBase Database used to retrieve module/package information
1750 # @param Arch The target architecture
1751 # @param Platform The name of platform employing this module
1752 # @param Macros Macros used for replacement in DSC file
1754 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1755 self
.MetaFile
= FilePath
1756 self
._ModuleDir
= FilePath
.Dir
1757 self
._RawData
= RawData
1758 self
._Bdb
= BuildDatabase
1760 self
._Target
= Target
1761 self
._Toolchain
= Toolchain
1762 self
._Platform
= 'COMMON'
1763 self
._SourceOverridePath
= None
1764 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1765 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1769 def __setitem__(self
, key
, value
):
1770 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1773 def __getitem__(self
, key
):
1774 return self
.__dict
__[self
._PROPERTY
_[key
]]
1776 ## "in" test support
1777 def __contains__(self
, key
):
1778 return key
in self
._PROPERTY
_
1780 ## Set all internal used members of InfBuildData to None
1782 self
._HeaderComments
= None
1783 self
._TailComments
= None
1784 self
._Header
_ = None
1785 self
._AutoGenVersion
= None
1786 self
._BaseName
= None
1787 self
._DxsFile
= None
1788 self
._ModuleType
= None
1789 self
._ComponentType
= None
1790 self
._BuildType
= None
1792 self
._Version
= None
1793 self
._PcdIsDriver
= None
1794 self
._BinaryModule
= None
1796 self
._MakefileName
= None
1797 self
._CustomMakefile
= None
1798 self
._Specification
= None
1799 self
._LibraryClass
= None
1800 self
._ModuleEntryPointList
= None
1801 self
._ModuleUnloadImageList
= None
1802 self
._ConstructorList
= None
1803 self
._DestructorList
= None
1805 self
._Binaries
= None
1806 self
._Sources
= None
1807 self
._LibraryClasses
= None
1808 self
._Libraries
= None
1809 self
._Protocols
= None
1810 self
._ProtocolComments
= None
1812 self
._PpiComments
= None
1814 self
._GuidsUsedByPcd
= sdict()
1815 self
._GuidComments
= None
1816 self
._Includes
= None
1817 self
._Packages
= None
1819 self
._PcdComments
= None
1820 self
._BuildOptions
= None
1822 self
._DepexExpression
= None
1823 self
.__Macros
= None
1825 ## Get current effective macros
1826 def _GetMacros(self
):
1827 if self
.__Macros
== None:
1829 # EDK_GLOBAL defined macros can be applied to EDK module
1830 if self
.AutoGenVersion
< 0x00010005:
1831 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1832 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1833 return self
.__Macros
1841 # Changing the default ARCH to another may affect all other information
1842 # because all information in a platform may be ARCH-related. That's
1843 # why we need to clear all internal used members, in order to cause all
1844 # information to be re-retrieved.
1846 # @param Value The value of ARCH
1848 def _SetArch(self
, Value
):
1849 if self
._Arch
== Value
:
1854 ## Return the name of platform employing this module
1855 def _GetPlatform(self
):
1856 return self
._Platform
1858 ## Change the name of platform employing this module
1860 # Changing the default name of platform to another may affect some information
1861 # because they may be PLATFORM-related. That's why we need to clear all internal
1862 # used members, in order to cause all information to be re-retrieved.
1864 def _SetPlatform(self
, Value
):
1865 if self
._Platform
== Value
:
1867 self
._Platform
= Value
1869 def _GetHeaderComments(self
):
1870 if not self
._HeaderComments
:
1871 self
._HeaderComments
= []
1872 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1873 for Record
in RecordList
:
1874 self
._HeaderComments
.append(Record
[0])
1875 return self
._HeaderComments
1876 def _GetTailComments(self
):
1877 if not self
._TailComments
:
1878 self
._TailComments
= []
1879 RecordList
= self
._RawData
[MODEL_META_DATA_TAIL_COMMENT
]
1880 for Record
in RecordList
:
1881 self
._TailComments
.append(Record
[0])
1882 return self
._TailComments
1883 ## Retrieve all information in [Defines] section
1885 # (Retriving all [Defines] information in one-shot is just to save time.)
1887 def _GetHeaderInfo(self
):
1888 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1889 for Record
in RecordList
:
1890 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1891 # items defined _PROPERTY_ don't need additional processing
1894 if self
._Defs
== None:
1895 self
._Defs
= sdict()
1896 self
._Defs
[Name
] = Value
1897 self
._Macros
[Name
] = Value
1898 # some special items in [Defines] section need special treatment
1899 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1900 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1901 Name
= 'UEFI_SPECIFICATION_VERSION'
1902 if self
._Specification
== None:
1903 self
._Specification
= sdict()
1904 self
._Specification
[Name
] = GetHexVerValue(Value
)
1905 if self
._Specification
[Name
] == None:
1906 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1907 "'%s' format is not supported for %s" % (Value
, Name
),
1908 File
=self
.MetaFile
, Line
=Record
[-1])
1909 elif Name
== 'LIBRARY_CLASS':
1910 if self
._LibraryClass
== None:
1911 self
._LibraryClass
= []
1912 ValueList
= GetSplitValueList(Value
)
1913 LibraryClass
= ValueList
[0]
1914 if len(ValueList
) > 1:
1915 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1917 SupModuleList
= SUP_MODULE_LIST
1918 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1919 elif Name
== 'ENTRY_POINT':
1920 if self
._ModuleEntryPointList
== None:
1921 self
._ModuleEntryPointList
= []
1922 self
._ModuleEntryPointList
.append(Value
)
1923 elif Name
== 'UNLOAD_IMAGE':
1924 if self
._ModuleUnloadImageList
== None:
1925 self
._ModuleUnloadImageList
= []
1928 self
._ModuleUnloadImageList
.append(Value
)
1929 elif Name
== 'CONSTRUCTOR':
1930 if self
._ConstructorList
== None:
1931 self
._ConstructorList
= []
1934 self
._ConstructorList
.append(Value
)
1935 elif Name
== 'DESTRUCTOR':
1936 if self
._DestructorList
== None:
1937 self
._DestructorList
= []
1940 self
._DestructorList
.append(Value
)
1941 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1942 TokenList
= GetSplitValueList(Value
)
1943 if self
._CustomMakefile
== None:
1944 self
._CustomMakefile
= {}
1945 if len(TokenList
) < 2:
1946 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1947 self
._CustomMakefile
['GCC'] = TokenList
[0]
1949 if TokenList
[0] not in ['MSFT', 'GCC']:
1950 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1951 "No supported family [%s]" % TokenList
[0],
1952 File
=self
.MetaFile
, Line
=Record
[-1])
1953 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1955 if self
._Defs
== None:
1956 self
._Defs
= sdict()
1957 self
._Defs
[Name
] = Value
1958 self
._Macros
[Name
] = Value
1961 # Retrieve information in sections specific to Edk.x modules
1963 if self
.AutoGenVersion
>= 0x00010005:
1964 if not self
._ModuleType
:
1965 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1966 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1967 if self
._ModuleType
not in SUP_MODULE_LIST
:
1968 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1969 for Record
in RecordList
:
1971 if Name
== "MODULE_TYPE":
1974 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1975 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
, ' '.join(l
for l
in SUP_MODULE_LIST
)),
1976 File
=self
.MetaFile
, Line
=LineNo
)
1977 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1978 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1979 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
)
1980 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1981 and 'PCI_CLASS_CODE' in self
._Defs
and 'PCI_REVISION' in self
._Defs
:
1982 self
._BuildType
= 'UEFI_OPTIONROM'
1983 if 'PCI_COMPRESS' in self
._Defs
:
1984 if self
._Defs
['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):
1985 EdkLogger
.error("build", FORMAT_INVALID
, "Expected TRUE/FALSE for PCI_COMPRESS: %s" %self
.MetaFile
)
1987 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1988 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1989 self
._BuildType
= 'UEFI_HII'
1991 self
._BuildType
= self
._ModuleType
.upper()
1994 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1995 # check the file validation
1996 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1998 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1999 File
=self
.MetaFile
, Line
=LineNo
)
2000 if self
.Sources
== None:
2002 self
._Sources
.append(File
)
2004 if not self
._ComponentType
:
2005 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
2006 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
2007 self
._BuildType
= self
._ComponentType
.upper()
2008 if self
._ComponentType
in self
._MODULE
_TYPE
_:
2009 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
2010 if self
._ComponentType
== 'LIBRARY':
2011 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
2012 # make use some [nmake] section macros
2013 Macros
= self
._Macros
2014 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2015 Macros
['PROCESSOR'] = self
._Arch
2016 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
2017 for Name
, Value
, Dummy
, Arch
, Platform
, ID
, LineNo
in RecordList
:
2018 Value
= ReplaceMacro(Value
, Macros
, True)
2019 if Name
== "IMAGE_ENTRY_POINT":
2020 if self
._ModuleEntryPointList
== None:
2021 self
._ModuleEntryPointList
= []
2022 self
._ModuleEntryPointList
.append(Value
)
2023 elif Name
== "DPX_SOURCE":
2024 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
2025 # check the file validation
2026 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
2028 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
2029 File
=self
.MetaFile
, Line
=LineNo
)
2030 if self
.Sources
== None:
2032 self
._Sources
.append(File
)
2034 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
2035 if len(ToolList
) == 0 or len(ToolList
) != 1:
2037 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
2038 # File=self.MetaFile, Line=LineNo)
2040 if self
._BuildOptions
== None:
2041 self
._BuildOptions
= sdict()
2043 if ToolList
[0] in self
._TOOL
_CODE
_:
2044 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
2047 ToolChain
= "*_*_*_%s_FLAGS" % Tool
2048 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
2049 #ignore not replaced macros in value
2050 ValueList
= GetSplitList(' ' + Value
, '/D')
2051 Dummy
= ValueList
[0]
2052 for Index
in range(1, len(ValueList
)):
2053 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
2055 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
2056 Value
= Dummy
.strip()
2057 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2058 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
2060 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2061 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
2062 # set _Header to non-None in order to avoid database re-querying
2063 self
._Header
_ = 'DUMMY'
2065 ## Retrieve file version
2066 def _GetInfVersion(self
):
2067 if self
._AutoGenVersion
== None:
2068 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
2069 for Record
in RecordList
:
2070 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
2071 if '.' in Record
[2]:
2072 ValueList
= Record
[2].split('.')
2073 Major
= '%04o' % int(ValueList
[0], 0)
2074 Minor
= '%04o' % int(ValueList
[1], 0)
2075 self
._AutoGenVersion
= int('0x' + Major
+ Minor
, 0)
2077 self
._AutoGenVersion
= int(Record
[2], 0)
2079 if self
._AutoGenVersion
== None:
2080 self
._AutoGenVersion
= 0x00010000
2081 return self
._AutoGenVersion
2083 ## Retrieve BASE_NAME
2084 def _GetBaseName(self
):
2085 if self
._BaseName
== None:
2086 if self
._Header
_ == None:
2087 self
._GetHeaderInfo
()
2088 if self
._BaseName
== None:
2089 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
2090 return self
._BaseName
2093 def _GetDxsFile(self
):
2094 if self
._DxsFile
== None:
2095 if self
._Header
_ == None:
2096 self
._GetHeaderInfo
()
2097 if self
._DxsFile
== None:
2099 return self
._DxsFile
2101 ## Retrieve MODULE_TYPE
2102 def _GetModuleType(self
):
2103 if self
._ModuleType
== None:
2104 if self
._Header
_ == None:
2105 self
._GetHeaderInfo
()
2106 if self
._ModuleType
== None:
2107 self
._ModuleType
= 'BASE'
2108 if self
._ModuleType
not in SUP_MODULE_LIST
:
2109 self
._ModuleType
= "USER_DEFINED"
2110 return self
._ModuleType
2112 ## Retrieve COMPONENT_TYPE
2113 def _GetComponentType(self
):
2114 if self
._ComponentType
== None:
2115 if self
._Header
_ == None:
2116 self
._GetHeaderInfo
()
2117 if self
._ComponentType
== None:
2118 self
._ComponentType
= 'USER_DEFINED'
2119 return self
._ComponentType
2121 ## Retrieve "BUILD_TYPE"
2122 def _GetBuildType(self
):
2123 if self
._BuildType
== None:
2124 if self
._Header
_ == None:
2125 self
._GetHeaderInfo
()
2126 if not self
._BuildType
:
2127 self
._BuildType
= "BASE"
2128 return self
._BuildType
2130 ## Retrieve file guid
2131 def _GetFileGuid(self
):
2132 if self
._Guid
== None:
2133 if self
._Header
_ == None:
2134 self
._GetHeaderInfo
()
2135 if self
._Guid
== None:
2136 self
._Guid
= '00000000-0000-0000-0000-000000000000'
2139 ## Retrieve module version
2140 def _GetVersion(self
):
2141 if self
._Version
== None:
2142 if self
._Header
_ == None:
2143 self
._GetHeaderInfo
()
2144 if self
._Version
== None:
2145 self
._Version
= '0.0'
2146 return self
._Version
2148 ## Retrieve PCD_IS_DRIVER
2149 def _GetPcdIsDriver(self
):
2150 if self
._PcdIsDriver
== None:
2151 if self
._Header
_ == None:
2152 self
._GetHeaderInfo
()
2153 if self
._PcdIsDriver
== None:
2154 self
._PcdIsDriver
= ''
2155 return self
._PcdIsDriver
2158 def _GetShadow(self
):
2159 if self
._Shadow
== None:
2160 if self
._Header
_ == None:
2161 self
._GetHeaderInfo
()
2162 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
2165 self
._Shadow
= False
2168 ## Retrieve CUSTOM_MAKEFILE
2169 def _GetMakefile(self
):
2170 if self
._CustomMakefile
== None:
2171 if self
._Header
_ == None:
2172 self
._GetHeaderInfo
()
2173 if self
._CustomMakefile
== None:
2174 self
._CustomMakefile
= {}
2175 return self
._CustomMakefile
2177 ## Retrieve EFI_SPECIFICATION_VERSION
2179 if self
._Specification
== None:
2180 if self
._Header
_ == None:
2181 self
._GetHeaderInfo
()
2182 if self
._Specification
== None:
2183 self
._Specification
= {}
2184 return self
._Specification
2186 ## Retrieve LIBRARY_CLASS
2187 def _GetLibraryClass(self
):
2188 if self
._LibraryClass
== None:
2189 if self
._Header
_ == None:
2190 self
._GetHeaderInfo
()
2191 if self
._LibraryClass
== None:
2192 self
._LibraryClass
= []
2193 return self
._LibraryClass
2195 ## Retrieve ENTRY_POINT
2196 def _GetEntryPoint(self
):
2197 if self
._ModuleEntryPointList
== None:
2198 if self
._Header
_ == None:
2199 self
._GetHeaderInfo
()
2200 if self
._ModuleEntryPointList
== None:
2201 self
._ModuleEntryPointList
= []
2202 return self
._ModuleEntryPointList
2204 ## Retrieve UNLOAD_IMAGE
2205 def _GetUnloadImage(self
):
2206 if self
._ModuleUnloadImageList
== None:
2207 if self
._Header
_ == None:
2208 self
._GetHeaderInfo
()
2209 if self
._ModuleUnloadImageList
== None:
2210 self
._ModuleUnloadImageList
= []
2211 return self
._ModuleUnloadImageList
2213 ## Retrieve CONSTRUCTOR
2214 def _GetConstructor(self
):
2215 if self
._ConstructorList
== None:
2216 if self
._Header
_ == None:
2217 self
._GetHeaderInfo
()
2218 if self
._ConstructorList
== None:
2219 self
._ConstructorList
= []
2220 return self
._ConstructorList
2222 ## Retrieve DESTRUCTOR
2223 def _GetDestructor(self
):
2224 if self
._DestructorList
== None:
2225 if self
._Header
_ == None:
2226 self
._GetHeaderInfo
()
2227 if self
._DestructorList
== None:
2228 self
._DestructorList
= []
2229 return self
._DestructorList
2231 ## Retrieve definies other than above ones
2232 def _GetDefines(self
):
2233 if self
._Defs
== None:
2234 if self
._Header
_ == None:
2235 self
._GetHeaderInfo
()
2236 if self
._Defs
== None:
2237 self
._Defs
= sdict()
2240 ## Retrieve binary files
2241 def _GetBinaries(self
):
2242 if self
._Binaries
== None:
2244 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
2245 Macros
= self
._Macros
2246 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2247 Macros
['PROCESSOR'] = self
._Arch
2248 for Record
in RecordList
:
2249 FileType
= Record
[0]
2254 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
2256 Target
= TokenList
[0]
2257 if len(TokenList
) > 1:
2258 FeatureFlag
= Record
[1:]
2260 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
2261 # check the file validation
2262 ErrorCode
, ErrorInfo
= File
.Validate()
2264 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2265 self
._Binaries
.append(File
)
2266 return self
._Binaries
2268 ## Retrieve binary files with error check.
2269 def _GetBinaryFiles(self
):
2270 Binaries
= self
._GetBinaries
()
2271 if GlobalData
.gIgnoreSource
and Binaries
== []:
2272 ErrorInfo
= "The INF file does not contain any Binaries to use in creating the image\n"
2273 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
)
2276 ## Check whether it exists the binaries with current ARCH in AsBuild INF
2277 def _IsSupportedArch(self
):
2278 if self
._GetBinaries
() and not self
._GetSourceFiles
():
2282 ## Retrieve source files
2283 def _GetSourceFiles(self
):
2284 #Ignore all source files in a binary build mode
2285 if GlobalData
.gIgnoreSource
:
2287 return self
._Sources
2289 if self
._Sources
== None:
2291 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
2292 Macros
= self
._Macros
2293 for Record
in RecordList
:
2295 ToolChainFamily
= Record
[1]
2297 ToolCode
= Record
[3]
2298 FeatureFlag
= Record
[4]
2299 if self
.AutoGenVersion
< 0x00010005:
2300 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2301 Macros
['PROCESSOR'] = self
._Arch
2302 SourceFile
= NormPath(Record
[0], Macros
)
2303 if SourceFile
[0] == os
.path
.sep
:
2304 SourceFile
= mws
.join(GlobalData
.gWorkspace
, SourceFile
[1:])
2305 # old module source files (Edk)
2306 File
= PathClass(SourceFile
, self
._ModuleDir
, self
._SourceOverridePath
,
2307 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2308 # check the file validation
2309 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2311 if File
.Ext
.lower() == '.h':
2312 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2313 File
=self
.MetaFile
, Line
=LineNo
)
2316 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2318 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2319 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2320 # check the file validation
2321 ErrorCode
, ErrorInfo
= File
.Validate()
2323 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2325 self
._Sources
.append(File
)
2326 return self
._Sources
2328 ## Retrieve library classes employed by this module
2329 def _GetLibraryClassUses(self
):
2330 if self
._LibraryClasses
== None:
2331 self
._LibraryClasses
= sdict()
2332 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2333 for Record
in RecordList
:
2335 Instance
= Record
[1]
2337 Instance
= NormPath(Instance
, self
._Macros
)
2338 self
._LibraryClasses
[Lib
] = Instance
2339 return self
._LibraryClasses
2341 ## Retrieve library names (for Edk.x style of modules)
2342 def _GetLibraryNames(self
):
2343 if self
._Libraries
== None:
2344 self
._Libraries
= []
2345 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2346 for Record
in RecordList
:
2347 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2348 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2349 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2350 if LibraryName
not in self
._Libraries
:
2351 self
._Libraries
.append(LibraryName
)
2352 return self
._Libraries
2354 def _GetProtocolComments(self
):
2355 self
._GetProtocols
()
2356 return self
._ProtocolComments
2357 ## Retrieve protocols consumed/produced by this module
2358 def _GetProtocols(self
):
2359 if self
._Protocols
== None:
2360 self
._Protocols
= sdict()
2361 self
._ProtocolComments
= sdict()
2362 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2363 for Record
in RecordList
:
2365 Value
= ProtocolValue(CName
, self
.Packages
, self
.MetaFile
.Path
)
2367 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2368 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2369 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2370 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2371 self
._Protocols
[CName
] = Value
2372 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2374 for CmtRec
in CommentRecords
:
2375 Comments
.append(CmtRec
[0])
2376 self
._ProtocolComments
[CName
] = Comments
2377 return self
._Protocols
2379 def _GetPpiComments(self
):
2381 return self
._PpiComments
2382 ## Retrieve PPIs consumed/produced by this module
2384 if self
._Ppis
== None:
2385 self
._Ppis
= sdict()
2386 self
._PpiComments
= sdict()
2387 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2388 for Record
in RecordList
:
2390 Value
= PpiValue(CName
, self
.Packages
, self
.MetaFile
.Path
)
2392 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2393 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2394 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2395 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2396 self
._Ppis
[CName
] = Value
2397 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2399 for CmtRec
in CommentRecords
:
2400 Comments
.append(CmtRec
[0])
2401 self
._PpiComments
[CName
] = Comments
2404 def _GetGuidComments(self
):
2406 return self
._GuidComments
2407 ## Retrieve GUIDs consumed/produced by this module
2408 def _GetGuids(self
):
2409 if self
._Guids
== None:
2410 self
._Guids
= sdict()
2411 self
._GuidComments
= sdict()
2412 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2413 for Record
in RecordList
:
2415 Value
= GuidValue(CName
, self
.Packages
, self
.MetaFile
.Path
)
2417 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2418 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2419 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2420 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2421 self
._Guids
[CName
] = Value
2422 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2424 for CmtRec
in CommentRecords
:
2425 Comments
.append(CmtRec
[0])
2426 self
._GuidComments
[CName
] = Comments
2429 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2430 def _GetIncludes(self
):
2431 if self
._Includes
== None:
2433 if self
._SourceOverridePath
:
2434 self
._Includes
.append(self
._SourceOverridePath
)
2436 Macros
= self
._Macros
2437 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2438 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2440 Macros
['PROCESSOR'] = self
._Arch
2441 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2442 for Record
in RecordList
:
2443 if Record
[0].find('EDK_SOURCE') > -1:
2444 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2445 File
= NormPath(Record
[0], self
._Macros
)
2447 File
= os
.path
.join(self
._ModuleDir
, File
)
2449 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2450 File
= RealPath(os
.path
.normpath(File
))
2452 self
._Includes
.append(File
)
2454 #TRICK: let compiler to choose correct header file
2455 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2456 File
= NormPath(Record
[0], self
._Macros
)
2458 File
= os
.path
.join(self
._ModuleDir
, File
)
2460 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2461 File
= RealPath(os
.path
.normpath(File
))
2463 self
._Includes
.append(File
)
2465 File
= NormPath(Record
[0], Macros
)
2467 File
= os
.path
.join(self
._ModuleDir
, File
)
2469 File
= mws
.join(GlobalData
.gWorkspace
, File
)
2470 File
= RealPath(os
.path
.normpath(File
))
2472 self
._Includes
.append(File
)
2473 if not File
and Record
[0].find('EFI_SOURCE') > -1:
2474 # tricky to regard WorkSpace as EFI_SOURCE
2475 Macros
['EFI_SOURCE'] = GlobalData
.gWorkspace
2476 File
= NormPath(Record
[0], Macros
)
2478 File
= os
.path
.join(self
._ModuleDir
, File
)
2480 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2481 File
= RealPath(os
.path
.normpath(File
))
2483 self
._Includes
.append(File
)
2484 return self
._Includes
2486 ## Retrieve packages this module depends on
2487 def _GetPackages(self
):
2488 if self
._Packages
== None:
2490 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2491 Macros
= self
._Macros
2492 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2493 for Record
in RecordList
:
2494 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2496 # check the file validation
2497 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2499 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2500 # parse this package now. we need it to get protocol/ppi/guid value
2501 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2502 self
._Packages
.append(Package
)
2503 return self
._Packages
2505 ## Retrieve PCD comments
2506 def _GetPcdComments(self
):
2508 return self
._PcdComments
2509 ## Retrieve PCDs used in this module
2511 if self
._Pcds
== None:
2512 self
._Pcds
= sdict()
2513 self
._PcdComments
= sdict()
2514 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2515 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2516 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2517 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2518 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2521 ## Retrieve build options specific to this module
2522 def _GetBuildOptions(self
):
2523 if self
._BuildOptions
== None:
2524 self
._BuildOptions
= sdict()
2525 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2526 for Record
in RecordList
:
2527 ToolChainFamily
= Record
[0]
2528 ToolChain
= Record
[1]
2530 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
or Option
.startswith('='):
2531 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2533 # concatenate the option string if they're for the same tool
2534 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2535 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2536 return self
._BuildOptions
2538 ## Retrieve dependency expression
2539 def _GetDepex(self
):
2540 if self
._Depex
== None:
2541 self
._Depex
= tdict(False, 2)
2542 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2544 # If the module has only Binaries and no Sources, then ignore [Depex]
2545 if self
.Sources
== None or self
.Sources
== []:
2546 if self
.Binaries
!= None and self
.Binaries
!= []:
2549 # PEIM and DXE drivers must have a valid [Depex] section
2550 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2551 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2552 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2553 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2554 % self
.ModuleType
, File
=self
.MetaFile
)
2556 if len(RecordList
) != 0 and self
.ModuleType
== 'USER_DEFINED':
2557 for Record
in RecordList
:
2558 if Record
[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
2559 EdkLogger
.error('build', FORMAT_INVALID
,
2560 "'%s' module must specify the type of [Depex] section" % self
.ModuleType
,
2564 for Record
in RecordList
:
2565 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2567 ModuleType
= Record
[4]
2568 TokenList
= DepexStr
.split()
2569 if (Arch
, ModuleType
) not in Depex
:
2570 Depex
[Arch
, ModuleType
] = []
2571 DepexList
= Depex
[Arch
, ModuleType
]
2572 for Token
in TokenList
:
2573 if Token
in DEPEX_SUPPORTED_OPCODE
:
2574 DepexList
.append(Token
)
2575 elif Token
.endswith(".inf"): # module file name
2576 ModuleFile
= os
.path
.normpath(Token
)
2577 Module
= self
.BuildDatabase
[ModuleFile
]
2579 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2580 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2581 DepexList
.append(Module
.Guid
)
2583 # get the GUID value now
2584 Value
= ProtocolValue(Token
, self
.Packages
, self
.MetaFile
.Path
)
2586 Value
= PpiValue(Token
, self
.Packages
, self
.MetaFile
.Path
)
2588 Value
= GuidValue(Token
, self
.Packages
, self
.MetaFile
.Path
)
2590 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2591 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2592 "Value of [%s] is not found in" % Token
,
2593 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2594 DepexList
.append(Value
)
2595 for Arch
, ModuleType
in Depex
:
2596 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2599 ## Retrieve depedency expression
2600 def _GetDepexExpression(self
):
2601 if self
._DepexExpression
== None:
2602 self
._DepexExpression
= tdict(False, 2)
2603 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2604 DepexExpression
= sdict()
2605 for Record
in RecordList
:
2606 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2608 ModuleType
= Record
[4]
2609 TokenList
= DepexStr
.split()
2610 if (Arch
, ModuleType
) not in DepexExpression
:
2611 DepexExpression
[Arch
, ModuleType
] = ''
2612 for Token
in TokenList
:
2613 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2614 for Arch
, ModuleType
in DepexExpression
:
2615 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2616 return self
._DepexExpression
2618 def GetGuidsUsedByPcd(self
):
2619 return self
._GuidsUsedByPcd
2620 ## Retrieve PCD for given type
2621 def _GetPcd(self
, Type
):
2623 PcdDict
= tdict(True, 4)
2625 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2626 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2627 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2628 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2629 # get the guid value
2630 if TokenSpaceGuid
not in self
.Guids
:
2631 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
, self
.MetaFile
.Path
)
2633 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2634 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2635 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2636 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2637 self
.Guids
[TokenSpaceGuid
] = Value
2638 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2639 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2641 for CmtRec
in CommentRecords
:
2642 Comments
.append(CmtRec
[0])
2643 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2645 # resolve PCD type, value, datum info, etc. by getting its definition from package
2646 for PcdCName
, TokenSpaceGuid
in PcdList
:
2647 PcdRealName
= PcdCName
2648 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2651 ValueList
= AnalyzePcdData(Setting
)
2652 DefaultValue
= ValueList
[0]
2653 Pcd
= PcdClassObject(
2663 self
.Guids
[TokenSpaceGuid
]
2665 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2666 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2667 Pcd
.Offset
= ValueList
[1]
2669 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
2670 for Package
in self
.Packages
:
2671 for key
in Package
.Pcds
:
2672 if (Package
.Pcds
[key
].TokenCName
, Package
.Pcds
[key
].TokenSpaceGuidCName
) == (PcdRealName
, TokenSpaceGuid
):
2673 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
2674 Pcd_Type
= item
[0].split('_')[-1]
2675 if Pcd_Type
== Package
.Pcds
[key
].Type
:
2676 Value
= Package
.Pcds
[key
]
2677 Value
.TokenCName
= Package
.Pcds
[key
].TokenCName
+ '_' + Pcd_Type
2679 newkey
= (Value
.TokenCName
, key
[1])
2681 newkey
= (Value
.TokenCName
, key
[1], key
[2])
2682 del Package
.Pcds
[key
]
2683 Package
.Pcds
[newkey
] = Value
2690 # get necessary info from package declaring this PCD
2691 for Package
in self
.Packages
:
2693 # 'dynamic' in INF means its type is determined by platform;
2694 # if platform doesn't give its type, use 'lowest' one in the
2695 # following order, if any
2697 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2699 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2700 if Type
== MODEL_PCD_DYNAMIC
:
2702 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2703 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
2704 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
2705 if str(item
[0]).endswith(T
) and (item
[0], item
[1], T
) in Package
.Pcds
:
2713 if (PcdRealName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2719 if (PcdRealName
, TokenSpaceGuid
) in GlobalData
.MixedPcd
:
2720 for item
in GlobalData
.MixedPcd
[(PcdRealName
, TokenSpaceGuid
)]:
2721 Pcd_Type
= item
[0].split('_')[-1]
2722 if Pcd_Type
== PcdType
:
2730 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2731 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2733 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2736 # Check whether the token value exist or not.
2738 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2742 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdRealName
, str(Package
)),
2743 File
=self
.MetaFile
, Line
=LineNo
,
2747 # Check hexadecimal token value length and format.
2749 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2750 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2751 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2755 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdRealName
, str(Package
)),
2756 File
=self
.MetaFile
, Line
=LineNo
,
2761 # Check decimal token value length and format.
2765 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2766 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2770 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdRealName
, str(Package
)),
2771 File
=self
.MetaFile
, Line
=LineNo
,
2778 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdRealName
, str(Package
)),
2779 File
=self
.MetaFile
, Line
=LineNo
,
2783 Pcd
.DatumType
= PcdInPackage
.DatumType
2784 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2785 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2786 if Pcd
.DefaultValue
in [None, '']:
2787 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2793 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdRealName
, self
.MetaFile
),
2794 File
=self
.MetaFile
, Line
=LineNo
,
2795 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2797 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2801 ## check whether current module is binary module
2802 def _IsBinaryModule(self
):
2803 if self
.Binaries
and not self
.Sources
:
2805 elif GlobalData
.gIgnoreSource
:
2810 _Macros
= property(_GetMacros
)
2811 Arch
= property(_GetArch
, _SetArch
)
2812 Platform
= property(_GetPlatform
, _SetPlatform
)
2814 HeaderComments
= property(_GetHeaderComments
)
2815 TailComments
= property(_GetTailComments
)
2816 AutoGenVersion
= property(_GetInfVersion
)
2817 BaseName
= property(_GetBaseName
)
2818 ModuleType
= property(_GetModuleType
)
2819 ComponentType
= property(_GetComponentType
)
2820 BuildType
= property(_GetBuildType
)
2821 Guid
= property(_GetFileGuid
)
2822 Version
= property(_GetVersion
)
2823 PcdIsDriver
= property(_GetPcdIsDriver
)
2824 Shadow
= property(_GetShadow
)
2825 CustomMakefile
= property(_GetMakefile
)
2826 Specification
= property(_GetSpec
)
2827 LibraryClass
= property(_GetLibraryClass
)
2828 ModuleEntryPointList
= property(_GetEntryPoint
)
2829 ModuleUnloadImageList
= property(_GetUnloadImage
)
2830 ConstructorList
= property(_GetConstructor
)
2831 DestructorList
= property(_GetDestructor
)
2832 Defines
= property(_GetDefines
)
2833 DxsFile
= property(_GetDxsFile
)
2835 Binaries
= property(_GetBinaryFiles
)
2836 Sources
= property(_GetSourceFiles
)
2837 LibraryClasses
= property(_GetLibraryClassUses
)
2838 Libraries
= property(_GetLibraryNames
)
2839 Protocols
= property(_GetProtocols
)
2840 ProtocolComments
= property(_GetProtocolComments
)
2841 Ppis
= property(_GetPpis
)
2842 PpiComments
= property(_GetPpiComments
)
2843 Guids
= property(_GetGuids
)
2844 GuidComments
= property(_GetGuidComments
)
2845 Includes
= property(_GetIncludes
)
2846 Packages
= property(_GetPackages
)
2847 Pcds
= property(_GetPcds
)
2848 PcdComments
= property(_GetPcdComments
)
2849 BuildOptions
= property(_GetBuildOptions
)
2850 Depex
= property(_GetDepex
)
2851 DepexExpression
= property(_GetDepexExpression
)
2852 IsBinaryModule
= property(_IsBinaryModule
)
2853 IsSupportedArch
= property(_IsSupportedArch
)
2857 # This class defined the build database for all modules, packages and platform.
2858 # It will call corresponding parser for the given file if it cannot find it in
2861 # @param DbPath Path of database file
2862 # @param GlobalMacros Global macros used for replacement during file parsing
2863 # @prarm RenewDb=False Create new database file if it's already there
2865 class WorkspaceDatabase(object):
2869 # internal class used for call corresponding file parser and caching the result
2870 # to avoid unnecessary re-parsing
2872 class BuildObjectFactory(object):
2875 ".inf" : MODEL_FILE_INF
,
2876 ".dec" : MODEL_FILE_DEC
,
2877 ".dsc" : MODEL_FILE_DSC
,
2882 MODEL_FILE_INF
: InfParser
,
2883 MODEL_FILE_DEC
: DecParser
,
2884 MODEL_FILE_DSC
: DscParser
,
2887 # convert to xxxBuildData object
2889 MODEL_FILE_INF
: InfBuildData
,
2890 MODEL_FILE_DEC
: DecBuildData
,
2891 MODEL_FILE_DSC
: DscBuildData
,
2894 _CACHE_
= {} # (FilePath, Arch) : <object>
2897 def __init__(self
, WorkspaceDb
):
2898 self
.WorkspaceDb
= WorkspaceDb
2900 # key = (FilePath, Arch=None)
2901 def __contains__(self
, Key
):
2907 return (FilePath
, Arch
) in self
._CACHE
_
2909 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2910 def __getitem__(self
, Key
):
2912 KeyLength
= len(Key
)
2926 # if it's generated before, just return the cached one
2927 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2928 if Key
in self
._CACHE
_:
2929 return self
._CACHE
_[Key
]
2933 if Ext
not in self
._FILE
_TYPE
_:
2935 FileType
= self
._FILE
_TYPE
_[Ext
]
2936 if FileType
not in self
._GENERATOR
_:
2939 # get the parser ready for this file
2940 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2944 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2946 # alwasy do post-process, in case of macros change
2947 MetaFile
.DoPostProcess()
2948 # object the build is based on
2949 BuildObject
= self
._GENERATOR
_[FileType
](
2957 self
._CACHE
_[Key
] = BuildObject
2960 # placeholder for file format conversion
2961 class TransformObjectFactory
:
2962 def __init__(self
, WorkspaceDb
):
2963 self
.WorkspaceDb
= WorkspaceDb
2965 # key = FilePath, Arch
2966 def __getitem__(self
, Key
):
2969 ## Constructor of WorkspaceDatabase
2971 # @param DbPath Path of database file
2972 # @param GlobalMacros Global macros used for replacement during file parsing
2973 # @prarm RenewDb=False Create new database file if it's already there
2975 def __init__(self
, DbPath
, RenewDb
=False):
2976 self
._DbClosedFlag
= False
2978 DbPath
= os
.path
.normpath(mws
.join(GlobalData
.gWorkspace
, 'Conf', GlobalData
.gDatabasePath
))
2980 # don't create necessary path for db in memory
2981 if DbPath
!= ':memory:':
2982 DbDir
= os
.path
.split(DbPath
)[0]
2983 if not os
.path
.exists(DbDir
):
2986 # remove db file in case inconsistency between db and file in file system
2987 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2990 # create db with optimized parameters
2991 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2992 self
.Conn
.execute("PRAGMA synchronous=OFF")
2993 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2994 self
.Conn
.execute("PRAGMA count_changes=OFF")
2995 self
.Conn
.execute("PRAGMA cache_size=8192")
2996 #self.Conn.execute("PRAGMA page_size=8192")
2998 # to avoid non-ascii character conversion issue
2999 self
.Conn
.text_factory
= str
3000 self
.Cur
= self
.Conn
.cursor()
3002 # create table for internal uses
3003 self
.TblDataModel
= TableDataModel(self
.Cur
)
3004 self
.TblFile
= TableFile(self
.Cur
)
3005 self
.Platform
= None
3007 # conversion object for build or file format conversion purpose
3008 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
3009 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
3011 ## Check whether workspace database need to be renew.
3012 # The renew reason maybe:
3013 # 1) If user force to renew;
3014 # 2) If user do not force renew, and
3015 # a) If the time of last modified python source is newer than database file;
3016 # b) If the time of last modified frozen executable file is newer than database file;
3018 # @param force User force renew database
3019 # @param DbPath The absolute path of workspace database file
3021 # @return Bool value for whether need renew workspace databse
3023 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
3024 # if database does not exist, we need do nothing
3025 if not os
.path
.exists(DbPath
): return False
3027 # if user force to renew database, then not check whether database is out of date
3028 if force
: return True
3031 # Check the time of last modified source file or build.exe
3032 # if is newer than time of database, then database need to be re-created.
3034 timeOfToolModified
= 0
3035 if hasattr(sys
, "frozen"):
3036 exePath
= os
.path
.abspath(sys
.executable
)
3037 timeOfToolModified
= os
.stat(exePath
).st_mtime
3039 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
3040 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
3041 if rootPath
== "" or rootPath
== None:
3042 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
3043 determine whether database file is out of date!\n")
3045 # walk the root path of source or build's binary to get the time last modified.
3047 for root
, dirs
, files
in os
.walk (rootPath
):
3049 # bypass source control folder
3050 if dir.lower() in [".svn", "_svn", "cvs"]:
3054 ext
= os
.path
.splitext(file)[1]
3055 if ext
.lower() == ".py": # only check .py files
3056 fd
= os
.stat(os
.path
.join(root
, file))
3057 if timeOfToolModified
< fd
.st_mtime
:
3058 timeOfToolModified
= fd
.st_mtime
3059 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
3060 EdkLogger
.verbose("\nWorkspace database is out of data!")
3065 ## Initialize build database
3066 def InitDatabase(self
):
3067 EdkLogger
.verbose("\nInitialize build database started ...")
3072 self
.TblDataModel
.Create(False)
3073 self
.TblFile
.Create(False)
3076 # Initialize table DataModel
3078 self
.TblDataModel
.InitTable()
3079 EdkLogger
.verbose("Initialize build database ... DONE!")
3083 # @param Table: The instance of the table to be queried
3085 def QueryTable(self
, Table
):
3091 ## Close entire database
3094 # Close the connection and cursor
3097 if not self
._DbClosedFlag
:
3101 self
._DbClosedFlag
= True
3103 ## Summarize all packages in the database
3104 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
3105 self
.Platform
= Platform
3107 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
3109 # Get Package related to Modules
3111 for Module
in Pa
.Modules
:
3112 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
3113 for Package
in ModuleObj
.Packages
:
3114 if Package
not in PackageList
:
3115 PackageList
.append(Package
)
3117 # Get Packages related to Libraries
3119 for Lib
in Pa
.LibraryInstances
:
3120 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
3121 for Package
in LibObj
.Packages
:
3122 if Package
not in PackageList
:
3123 PackageList
.append(Package
)
3127 ## Summarize all platforms in the database
3128 def _GetPlatformList(self
):
3130 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
3132 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
3135 if Platform
!= None:
3136 PlatformList
.append(Platform
)
3139 def _MapPlatform(self
, Dscfile
):
3140 Platform
= self
.BuildObject
[PathClass(Dscfile
), 'COMMON']
3141 if Platform
== None:
3142 EdkLogger
.error('build', PARSER_ERROR
, "Failed to parser DSC file: %s" % Dscfile
)
3145 PlatformList
= property(_GetPlatformList
)
3149 # This acts like the main() function for the script, unless it is 'import'ed into another
3152 if __name__
== '__main__':