2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 import Common
.EdkLogger
as EdkLogger
24 import Common
.GlobalData
as GlobalData
26 from Common
.String
import *
27 from Common
.DataType
import *
28 from Common
.Misc
import *
31 from CommonDataClass
.CommonClass
import SkuInfoClass
33 from MetaDataTable
import *
34 from MetaFileTable
import *
35 from MetaFileParser
import *
36 from BuildClassObject
import *
37 from WorkspaceCommon
import GetDeclaredPcd
38 from Common
.Misc
import AnalyzeDscPcd
40 ## Platform build information from DSC file
42 # This class is used to retrieve information stored in database and convert them
43 # into PlatformBuildClassObject form for easier use for AutoGen.
45 class DscBuildData(PlatformBuildClassObject
):
46 # dict used to convert PCD type in database to string used by build tool
48 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
49 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
50 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
51 MODEL_PCD_DYNAMIC
: "Dynamic",
52 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
53 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
54 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
55 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
56 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
57 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
58 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
61 # dict used to convert part of [Defines] to members of DscBuildData directly
66 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
67 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
68 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
69 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
70 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
71 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
72 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
73 TAB_DSC_DEFINES_SKUID_IDENTIFIER
: "_SkuName",
74 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
75 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
76 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
77 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
78 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
79 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
80 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
83 # used to compose dummy library class name for those forced library instances
84 _NullLibraryNumber
= 0
86 ## Constructor of DscBuildData
88 # Initialize object of DscBuildData
90 # @param FilePath The path of platform description file
91 # @param RawData The raw data of DSC file
92 # @param BuildDataBase Database used to retrieve module/package information
93 # @param Arch The target architecture
94 # @param Platform (not used for DscBuildData)
95 # @param Macros Macros used for replacement in DSC file
97 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
98 self
.MetaFile
= FilePath
99 self
._RawData
= RawData
100 self
._Bdb
= BuildDataBase
102 self
._Target
= Target
103 self
._Toolchain
= Toolchain
107 def __setitem__(self
, key
, value
):
108 self
.__dict
__[self
._PROPERTY
_[key
]] = value
111 def __getitem__(self
, key
):
112 return self
.__dict
__[self
._PROPERTY
_[key
]]
115 def __contains__(self
, key
):
116 return key
in self
._PROPERTY
_
118 ## Set all internal used members of DscBuildData to None
121 self
._PlatformName
= None
124 self
._DscSpecification
= None
125 self
._OutputDirectory
= None
126 self
._SupArchList
= None
127 self
._BuildTargets
= None
129 self
._SkuIdentifier
= None
130 self
._PcdInfoFlag
= None
131 self
._FlashDefinition
= None
132 self
._BuildNumber
= None
133 self
._MakefileName
= None
134 self
._BsBaseAddress
= None
135 self
._RtBaseAddress
= None
138 self
._LibraryInstances
= None
139 self
._LibraryClasses
= None
142 self
._BuildOptions
= None
143 self
._LoadFixAddress
= None
144 self
._RFCLanguages
= None
145 self
._ISOLanguages
= None
146 self
._VpdToolGuid
= None
149 ## Get current effective macros
150 def _GetMacros(self
):
151 if self
.__Macros
== None:
153 self
.__Macros
.update(GlobalData
.gPlatformDefines
)
154 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
155 self
.__Macros
.update(GlobalData
.gCommandLineDefines
)
164 # Changing the default ARCH to another may affect all other information
165 # because all information in a platform may be ARCH-related. That's
166 # why we need to clear all internal used members, in order to cause all
167 # information to be re-retrieved.
169 # @param Value The value of ARCH
171 def _SetArch(self
, Value
):
172 if self
._Arch
== Value
:
177 ## Retrieve all information in [Defines] section
179 # (Retriving all [Defines] information in one-shot is just to save time.)
181 def _GetHeaderInfo(self
):
182 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
183 for Record
in RecordList
:
185 # items defined _PROPERTY_ don't need additional processing
187 # some special items in [Defines] section need special treatment
188 if Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
189 self
._OutputDirectory
= NormPath(Record
[2], self
._Macros
)
190 if ' ' in self
._OutputDirectory
:
191 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
192 File
=self
.MetaFile
, Line
=Record
[-1],
193 ExtraData
=self
._OutputDirectory
)
194 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
195 self
._FlashDefinition
= PathClass(NormPath(Record
[2], self
._Macros
), GlobalData
.gWorkspace
)
196 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
198 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
200 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
201 self
._SupArchList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
202 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
203 self
._BuildTargets
= GetSplitValueList(Record
[2])
204 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
205 if self
._SkuName
== None:
206 self
._SkuName
= Record
[2]
207 self
._SkuIdentifier
= Record
[2]
208 elif Name
== TAB_DSC_DEFINES_PCD_INFO_GENERATION
:
209 self
._PcdInfoFlag
= Record
[2]
210 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
212 self
._LoadFixAddress
= int (Record
[2], 0)
214 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record
[2]))
215 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
216 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
217 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"',
218 File
=self
.MetaFile
, Line
=Record
[-1])
219 LanguageCodes
= Record
[2][1:-1]
220 if not LanguageCodes
:
221 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
222 File
=self
.MetaFile
, Line
=Record
[-1])
223 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
224 # check whether there is empty entries in the list
225 if None in LanguageList
:
226 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
227 File
=self
.MetaFile
, Line
=Record
[-1])
228 self
._RFCLanguages
= LanguageList
229 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
230 if not Record
[2] or Record
[2][0] != '"' or Record
[2][-1] != '"' or len(Record
[2]) == 1:
231 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
232 File
=self
.MetaFile
, Line
=Record
[-1])
233 LanguageCodes
= Record
[2][1:-1]
234 if not LanguageCodes
:
235 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
236 File
=self
.MetaFile
, Line
=Record
[-1])
237 if len(LanguageCodes
)%3:
238 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
239 File
=self
.MetaFile
, Line
=Record
[-1])
241 for i
in range(0, len(LanguageCodes
), 3):
242 LanguageList
.append(LanguageCodes
[i
:i
+3])
243 self
._ISOLanguages
= LanguageList
244 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
246 # try to convert GUID to a real UUID value to see whether the GUID is format
247 # for VPD_TOOL_GUID is correct.
252 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
253 self
._VpdToolGuid
= Record
[2]
255 self
[Name
] = Record
[2]
256 # set _Header to non-None in order to avoid database re-querying
257 self
._Header
= 'DUMMY'
259 ## Retrieve platform name
260 def _GetPlatformName(self
):
261 if self
._PlatformName
== None:
262 if self
._Header
== None:
263 self
._GetHeaderInfo
()
264 if self
._PlatformName
== None:
265 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
266 return self
._PlatformName
268 ## Retrieve file guid
269 def _GetFileGuid(self
):
270 if self
._Guid
== None:
271 if self
._Header
== None:
272 self
._GetHeaderInfo
()
273 if self
._Guid
== None:
274 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_GUID", File
=self
.MetaFile
)
277 ## Retrieve platform version
278 def _GetVersion(self
):
279 if self
._Version
== None:
280 if self
._Header
== None:
281 self
._GetHeaderInfo
()
282 if self
._Version
== None:
283 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_VERSION", File
=self
.MetaFile
)
286 ## Retrieve platform description file version
287 def _GetDscSpec(self
):
288 if self
._DscSpecification
== None:
289 if self
._Header
== None:
290 self
._GetHeaderInfo
()
291 if self
._DscSpecification
== None:
292 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No DSC_SPECIFICATION", File
=self
.MetaFile
)
293 return self
._DscSpecification
295 ## Retrieve OUTPUT_DIRECTORY
296 def _GetOutpuDir(self
):
297 if self
._OutputDirectory
== None:
298 if self
._Header
== None:
299 self
._GetHeaderInfo
()
300 if self
._OutputDirectory
== None:
301 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
302 return self
._OutputDirectory
304 ## Retrieve SUPPORTED_ARCHITECTURES
305 def _GetSupArch(self
):
306 if self
._SupArchList
== None:
307 if self
._Header
== None:
308 self
._GetHeaderInfo
()
309 if self
._SupArchList
== None:
310 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No SUPPORTED_ARCHITECTURES", File
=self
.MetaFile
)
311 return self
._SupArchList
313 ## Retrieve BUILD_TARGETS
314 def _GetBuildTarget(self
):
315 if self
._BuildTargets
== None:
316 if self
._Header
== None:
317 self
._GetHeaderInfo
()
318 if self
._BuildTargets
== None:
319 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BUILD_TARGETS", File
=self
.MetaFile
)
320 return self
._BuildTargets
322 def _GetPcdInfoFlag(self
):
323 if self
._PcdInfoFlag
== None or self
._PcdInfoFlag
.upper() == 'FALSE':
325 elif self
._PcdInfoFlag
.upper() == 'TRUE':
330 def _GetSkuIdentifier(self
):
331 if self
._SkuIdentifier
== None:
332 if self
._Header
== None:
333 self
._GetHeaderInfo
()
334 return self
._SkuIdentifier
335 ## Retrieve SKUID_IDENTIFIER
336 def _GetSkuName(self
):
337 if self
._SkuName
== None:
338 if self
._Header
== None:
339 self
._GetHeaderInfo
()
340 if self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
:
341 self
._SkuName
= 'DEFAULT'
344 ## Override SKUID_IDENTIFIER
345 def _SetSkuName(self
, Value
):
346 if Value
in self
.SkuIds
:
347 self
._SkuName
= Value
348 # Needs to re-retrieve the PCD information
351 def _GetFdfFile(self
):
352 if self
._FlashDefinition
== None:
353 if self
._Header
== None:
354 self
._GetHeaderInfo
()
355 if self
._FlashDefinition
== None:
356 self
._FlashDefinition
= ''
357 return self
._FlashDefinition
359 ## Retrieve FLASH_DEFINITION
360 def _GetBuildNumber(self
):
361 if self
._BuildNumber
== None:
362 if self
._Header
== None:
363 self
._GetHeaderInfo
()
364 if self
._BuildNumber
== None:
365 self
._BuildNumber
= ''
366 return self
._BuildNumber
368 ## Retrieve MAKEFILE_NAME
369 def _GetMakefileName(self
):
370 if self
._MakefileName
== None:
371 if self
._Header
== None:
372 self
._GetHeaderInfo
()
373 if self
._MakefileName
== None:
374 self
._MakefileName
= ''
375 return self
._MakefileName
377 ## Retrieve BsBaseAddress
378 def _GetBsBaseAddress(self
):
379 if self
._BsBaseAddress
== None:
380 if self
._Header
== None:
381 self
._GetHeaderInfo
()
382 if self
._BsBaseAddress
== None:
383 self
._BsBaseAddress
= ''
384 return self
._BsBaseAddress
386 ## Retrieve RtBaseAddress
387 def _GetRtBaseAddress(self
):
388 if self
._RtBaseAddress
== None:
389 if self
._Header
== None:
390 self
._GetHeaderInfo
()
391 if self
._RtBaseAddress
== None:
392 self
._RtBaseAddress
= ''
393 return self
._RtBaseAddress
395 ## Retrieve the top address for the load fix address
396 def _GetLoadFixAddress(self
):
397 if self
._LoadFixAddress
== None:
398 if self
._Header
== None:
399 self
._GetHeaderInfo
()
401 if self
._LoadFixAddress
== None:
402 self
._LoadFixAddress
= self
._Macros
.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
, '0')
405 self
._LoadFixAddress
= int (self
._LoadFixAddress
, 0)
407 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self
._LoadFixAddress
))
410 # If command line defined, should override the value in DSC file.
412 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData
.gCommandLineDefines
.keys():
414 self
._LoadFixAddress
= int(GlobalData
.gCommandLineDefines
['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
416 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']))
418 if self
._LoadFixAddress
< 0:
419 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self
._LoadFixAddress
))
420 if self
._LoadFixAddress
!= 0xFFFFFFFFFFFFFFFF and self
._LoadFixAddress
% 0x1000 != 0:
421 EdkLogger
.error("build", PARAMETER_INVALID
, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self
._LoadFixAddress
))
423 return self
._LoadFixAddress
425 ## Retrieve RFCLanguage filter
426 def _GetRFCLanguages(self
):
427 if self
._RFCLanguages
== None:
428 if self
._Header
== None:
429 self
._GetHeaderInfo
()
430 if self
._RFCLanguages
== None:
431 self
._RFCLanguages
= []
432 return self
._RFCLanguages
434 ## Retrieve ISOLanguage filter
435 def _GetISOLanguages(self
):
436 if self
._ISOLanguages
== None:
437 if self
._Header
== None:
438 self
._GetHeaderInfo
()
439 if self
._ISOLanguages
== None:
440 self
._ISOLanguages
= []
441 return self
._ISOLanguages
442 ## Retrieve the GUID string for VPD tool
443 def _GetVpdToolGuid(self
):
444 if self
._VpdToolGuid
== None:
445 if self
._Header
== None:
446 self
._GetHeaderInfo
()
447 if self
._VpdToolGuid
== None:
448 self
._VpdToolGuid
= ''
449 return self
._VpdToolGuid
451 ## Retrieve [SkuIds] section information
452 def _GetSkuIds(self
):
453 if self
._SkuIds
== None:
454 self
._SkuIds
= sdict()
455 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
, self
._Arch
]
456 for Record
in RecordList
:
457 if Record
[0] in [None, '']:
458 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
459 File
=self
.MetaFile
, Line
=Record
[-1])
460 if Record
[1] in [None, '']:
461 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
462 File
=self
.MetaFile
, Line
=Record
[-1])
463 self
._SkuIds
[Record
[1].upper()] = Record
[0]
464 if 'DEFAULT' not in self
._SkuIds
:
465 self
._SkuIds
['DEFAULT'] = '0'
466 if 'COMMON' not in self
._SkuIds
:
467 self
._SkuIds
['COMMON'] = '0'
470 ## Retrieve [Components] section information
471 def _GetModules(self
):
472 if self
._Modules
!= None:
475 self
._Modules
= sdict()
476 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
477 Macros
= self
._Macros
478 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
479 for Record
in RecordList
:
480 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
484 # check the file validation
485 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
487 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
490 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
491 if self
._Arch
!= 'COMMON' and ModuleFile
in self
._Modules
:
492 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
494 Module
= ModuleBuildClassObject()
495 Module
.MetaFile
= ModuleFile
497 # get module override path
498 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
500 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
502 # Check if the source override path exists
503 if not os
.path
.isdir(Module
.SourceOverridePath
):
504 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
506 #Add to GlobalData Variables
507 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
509 # get module private library instance
510 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
511 for Record
in RecordList
:
512 LibraryClass
= Record
[0]
513 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
516 # check the file validation
517 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
519 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
522 if LibraryClass
== '' or LibraryClass
== 'NULL':
523 self
._NullLibraryNumber
+= 1
524 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
525 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
526 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
527 if LibraryPath
not in self
.LibraryInstances
:
528 self
.LibraryInstances
.append(LibraryPath
)
530 # get module private PCD setting
531 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
532 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
533 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
534 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
535 TokenList
= GetSplitValueList(Setting
)
536 DefaultValue
= TokenList
[0]
537 if len(TokenList
) > 1:
538 MaxDatumSize
= TokenList
[1]
541 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
542 Pcd
= PcdClassObject(
554 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
556 # get module private build options
557 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
558 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
559 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
560 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
562 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
563 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
565 self
._Modules
[ModuleFile
] = Module
568 ## Retrieve all possible library instances used in this platform
569 def _GetLibraryInstances(self
):
570 if self
._LibraryInstances
== None:
571 self
._GetLibraryClasses
()
572 return self
._LibraryInstances
574 ## Retrieve [LibraryClasses] information
575 def _GetLibraryClasses(self
):
576 if self
._LibraryClasses
== None:
577 self
._LibraryInstances
= []
579 # tdict is a special dict kind of type, used for selecting correct
580 # library instance for given library class and module type
582 LibraryClassDict
= tdict(True, 3)
583 # track all library class names
584 LibraryClassSet
= set()
585 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, -1]
586 Macros
= self
._Macros
587 for Record
in RecordList
:
588 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
589 if LibraryClass
== '' or LibraryClass
== 'NULL':
590 self
._NullLibraryNumber
+= 1
591 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
592 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
593 LibraryClassSet
.add(LibraryClass
)
594 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
595 # check the file validation
596 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
598 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
601 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
602 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
603 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
604 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
605 if LibraryInstance
not in self
._LibraryInstances
:
606 self
._LibraryInstances
.append(LibraryInstance
)
608 # resolve the specific library instance for each class and each module type
609 self
._LibraryClasses
= tdict(True)
610 for LibraryClass
in LibraryClassSet
:
611 # try all possible module types
612 for ModuleType
in SUP_MODULE_LIST
:
613 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
614 if LibraryInstance
== None:
616 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
618 # for Edk style library instances, which are listed in different section
619 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
620 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
621 for Record
in RecordList
:
622 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
624 # check the file validation
625 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
627 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
629 if File
not in self
._LibraryInstances
:
630 self
._LibraryInstances
.append(File
)
632 # we need the module name as the library class name, so we have
633 # to parse it here. (self._Bdb[] will trigger a file parse if it
634 # hasn't been parsed)
636 Library
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
637 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
638 return self
._LibraryClasses
640 def _ValidatePcd(self
, PcdCName
, TokenSpaceGuid
, Setting
, PcdType
, LineNo
):
641 if self
._DecPcds
== None:
642 self
._DecPcds
= GetDeclaredPcd(self
, self
._Bdb
, self
._Arch
, self
._Target
, self
._Toolchain
)
643 if (PcdCName
, TokenSpaceGuid
) not in self
._DecPcds
:
644 EdkLogger
.error('build', PARSER_ERROR
,
645 "Pcd (%s.%s) defined in DSC is not declared in DEC files." % (TokenSpaceGuid
, PcdCName
),
646 File
=self
.MetaFile
, Line
=LineNo
)
647 ValueList
, IsValid
, Index
= AnalyzeDscPcd(Setting
, PcdType
, self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
)
648 if not IsValid
and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
649 EdkLogger
.error('build', FORMAT_INVALID
, "Pcd format incorrect.", File
=self
.MetaFile
, Line
=LineNo
,
650 ExtraData
="%s.%s|%s" % (TokenSpaceGuid
, PcdCName
, Setting
))
651 if ValueList
[Index
] and PcdType
not in [MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_FIXED_AT_BUILD
]:
653 ValueList
[Index
] = ValueExpression(ValueList
[Index
], GlobalData
.gPlatformPcds
)(True)
654 except WrnExpression
, Value
:
655 ValueList
[Index
] = Value
.result
656 except EvaluationException
, Excpt
:
657 if hasattr(Excpt
, 'Pcd'):
658 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
659 EdkLogger
.error('Parser', FORMAT_INVALID
, "Cannot use this PCD (%s) in an expression as"
660 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
661 " of the DSC file" % Excpt
.Pcd
,
662 File
=self
.MetaFile
, Line
=LineNo
)
664 EdkLogger
.error('Parser', FORMAT_INVALID
, "PCD (%s) is not defined in DSC file" % Excpt
.Pcd
,
665 File
=self
.MetaFile
, Line
=LineNo
)
667 EdkLogger
.error('Parser', FORMAT_INVALID
, "Invalid expression: %s" % str(Excpt
),
668 File
=self
.MetaFile
, Line
=LineNo
)
669 if ValueList
[Index
] == 'True':
670 ValueList
[Index
] = '1'
671 elif ValueList
[Index
] == 'False':
672 ValueList
[Index
] = '0'
674 Valid
, ErrStr
= CheckPcdDatum(self
._DecPcds
[PcdCName
, TokenSpaceGuid
].DatumType
, ValueList
[Index
])
676 EdkLogger
.error('build', FORMAT_INVALID
, ErrStr
, File
=self
.MetaFile
, Line
=LineNo
,
677 ExtraData
="%s.%s" % (TokenSpaceGuid
, PcdCName
))
680 ## Retrieve all PCD settings in platform
682 if self
._Pcds
== None:
684 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
685 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
686 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
687 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
688 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
689 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
690 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
691 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
692 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
695 ## Retrieve [BuildOptions]
696 def _GetBuildOptions(self
):
697 if self
._BuildOptions
== None:
698 self
._BuildOptions
= sdict()
700 # Retrieve build option for EDKII style module
702 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDKII_NAME
]
703 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
704 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
706 # Retrieve build option for EDK style module
708 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, EDK_NAME
]
709 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
710 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
711 return self
._BuildOptions
713 ## Retrieve non-dynamic PCD settings
715 # @param Type PCD type
717 # @retval a dict object contains settings of given PCD type
719 def _GetPcd(self
, Type
):
722 # tdict is a special dict kind of type, used for selecting correct
723 # PCD settings for certain ARCH
726 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
728 PcdDict
= tdict(True, 3)
730 # Find out all possible PCD candidates for self._Arch
731 RecordList
= self
._RawData
[Type
, self
._Arch
]
732 PcdValueDict
= sdict()
733 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
734 SkuName
= SkuName
.upper()
735 if SkuName
in (SkuObj
.SystemSkuId
,'DEFAULT','COMMON'):
736 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
737 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
,SkuName
] = Setting
739 #handle pcd value override
740 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdSet
:
741 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
,SkuName
]
744 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
745 if (PcdCName
, TokenSpaceGuid
) in PcdValueDict
:
746 PcdValueDict
[PcdCName
, TokenSpaceGuid
][SkuName
] = (PcdValue
,DatumType
,MaxDatumSize
)
748 PcdValueDict
[PcdCName
, TokenSpaceGuid
] = {SkuName
:(PcdValue
,DatumType
,MaxDatumSize
)}
750 PcdsKeys
= PcdValueDict
.keys()
751 for PcdCName
,TokenSpaceGuid
in PcdsKeys
:
753 PcdSetting
= PcdValueDict
[PcdCName
, TokenSpaceGuid
]
757 if 'COMMON' in PcdSetting
:
758 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['COMMON']
759 if 'DEFAULT' in PcdSetting
:
760 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
['DEFAULT']
761 if SkuObj
.SystemSkuId
in PcdSetting
:
762 PcdValue
,DatumType
,MaxDatumSize
= PcdSetting
[SkuObj
.SystemSkuId
]
764 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
767 self
._PCD
_TYPE
_STRING
_[Type
],
778 ## Retrieve dynamic PCD settings
780 # @param Type PCD type
782 # @retval a dict object contains settings of given PCD type
784 def _GetDynamicPcd(self
, Type
):
786 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
790 # tdict is a special dict kind of type, used for selecting correct
791 # PCD settings for certain ARCH and SKU
793 PcdDict
= tdict(True, 4)
795 # Find out all possible PCD candidates for self._Arch
796 RecordList
= self
._RawData
[Type
, self
._Arch
]
797 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
799 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
800 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
801 SkuName
= SkuName
.upper()
802 if SkuName
not in AvailableSkuIdSet
:
805 PcdList
.append((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
806 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
807 # Remove redundant PCD candidates, per the ARCH and SKU
808 for PcdCName
, TokenSpaceGuid
, SkuName
, Dummy4
in PcdList
:
810 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
814 PcdValue
, DatumType
, MaxDatumSize
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
815 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', '', PcdValue
)
816 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
817 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
818 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
820 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
823 self
._PCD
_TYPE
_STRING
_[Type
],
833 for pcd
in Pcds
.values():
834 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
835 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
836 valuefromDec
= pcdDecObject
.DefaultValue
837 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec
)
838 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
839 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
840 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
841 del(pcd
.SkuInfoList
['COMMON'])
842 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
843 del(pcd
.SkuInfoList
['COMMON'])
844 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
845 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
846 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
847 del(pcd
.SkuInfoList
['DEFAULT'])
849 if SkuObj
.SkuUsageType
== SkuObj
.MULTIPLE
:
850 if pcd
.DatumType
== "VOID*":
851 MaxSize
= int(pcd
.MaxDatumSize
,0)
852 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
853 datalen
= len(skuobj
.DefaultValue
)
856 pcd
.MaxDatumSize
= str(MaxSize
)
861 ## Retrieve dynamic HII PCD settings
863 # @param Type PCD type
865 # @retval a dict object contains settings of given PCD type
867 def _GetDynamicHiiPcd(self
, Type
):
869 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
873 # tdict is a special dict kind of type, used for selecting correct
874 # PCD settings for certain ARCH and SKU
876 PcdDict
= tdict(True, 4)
878 RecordList
= self
._RawData
[Type
, self
._Arch
]
879 # Find out all possible PCD candidates for self._Arch
880 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
882 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
883 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
884 SkuName
= SkuName
.upper()
885 if SkuName
not in AvailableSkuIdSet
:
887 PcdSet
.add((PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
))
888 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
889 # Remove redundant PCD candidates, per the ARCH and SKU
890 for PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
in PcdSet
:
892 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
895 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
896 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
897 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
898 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
899 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
901 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
904 self
._PCD
_TYPE
_STRING
_[Type
],
915 for pcd
in Pcds
.values():
916 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
917 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
918 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
919 valuefromDec
= pcdDecObject
.DefaultValue
920 SkuInfo
= SkuInfoClass('DEFAULT', '0', SkuInfoObj
.VariableName
, SkuInfoObj
.VariableGuid
, SkuInfoObj
.VariableOffset
, valuefromDec
)
921 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
922 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
923 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
924 del(pcd
.SkuInfoList
['COMMON'])
925 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
926 del(pcd
.SkuInfoList
['COMMON'])
928 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
929 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
930 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
931 del(pcd
.SkuInfoList
['DEFAULT'])
934 ## Retrieve dynamic VPD PCD settings
936 # @param Type PCD type
938 # @retval a dict object contains settings of given PCD type
940 def _GetDynamicVpdPcd(self
, Type
):
942 SkuObj
= SkuClass(self
.SkuIdentifier
,self
.SkuIds
)
946 # tdict is a special dict kind of type, used for selecting correct
947 # PCD settings for certain ARCH and SKU
949 PcdDict
= tdict(True, 4)
951 # Find out all possible PCD candidates for self._Arch
952 RecordList
= self
._RawData
[Type
, self
._Arch
]
953 AvailableSkuIdSet
= SkuObj
.AvailableSkuIdSet
.copy()
955 AvailableSkuIdSet
.update({'DEFAULT':0,'COMMON':0})
956 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
957 SkuName
= SkuName
.upper()
958 if SkuName
not in AvailableSkuIdSet
:
961 PcdList
.append((PcdCName
, TokenSpaceGuid
,SkuName
, Dummy4
))
962 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
963 # Remove redundant PCD candidates, per the ARCH and SKU
964 for PcdCName
, TokenSpaceGuid
, SkuName
,Dummy4
in PcdList
:
965 Setting
= PcdDict
[self
._Arch
, SkuName
, PcdCName
, TokenSpaceGuid
]
969 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
970 # For the Integer & Boolean type, the optional data can only be InitialValue.
971 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
972 # until the DEC parser has been called.
974 VpdOffset
, MaxDatumSize
, InitialValue
= self
._ValidatePcd
(PcdCName
, TokenSpaceGuid
, Setting
, Type
, Dummy4
)
975 SkuInfo
= SkuInfoClass(SkuName
, self
.SkuIds
[SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
976 if (PcdCName
,TokenSpaceGuid
) in Pcds
.keys():
977 pcdObject
= Pcds
[PcdCName
,TokenSpaceGuid
]
978 pcdObject
.SkuInfoList
[SkuName
] = SkuInfo
980 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
983 self
._PCD
_TYPE
_STRING
_[Type
],
992 for pcd
in Pcds
.values():
993 SkuInfoObj
= pcd
.SkuInfoList
.values()[0]
994 if 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' not in pcd
.SkuInfoList
.keys():
995 pcdDecObject
= self
._DecPcds
[pcd
.TokenCName
,pcd
.TokenSpaceGuidCName
]
996 valuefromDec
= pcdDecObject
.DefaultValue
997 SkuInfo
= SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj
.VpdOffset
, valuefromDec
)
998 pcd
.SkuInfoList
['DEFAULT'] = SkuInfo
999 elif 'DEFAULT' not in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1000 pcd
.SkuInfoList
['DEFAULT'] = pcd
.SkuInfoList
['COMMON']
1001 del(pcd
.SkuInfoList
['COMMON'])
1002 elif 'DEFAULT' in pcd
.SkuInfoList
.keys() and 'COMMON' in pcd
.SkuInfoList
.keys():
1003 del(pcd
.SkuInfoList
['COMMON'])
1004 if SkuObj
.SkuUsageType
== SkuObj
.SINGLE
:
1005 if 'DEFAULT' in pcd
.SkuInfoList
.keys() and SkuObj
.SystemSkuId
not in pcd
.SkuInfoList
.keys():
1006 pcd
.SkuInfoList
[SkuObj
.SystemSkuId
] = pcd
.SkuInfoList
['DEFAULT']
1007 del(pcd
.SkuInfoList
['DEFAULT'])
1009 if SkuObj
.SkuUsageType
== SkuObj
.MULTIPLE
:
1010 if pcd
.MaxDatumSize
.strip():
1011 MaxSize
= int(pcd
.MaxDatumSize
,0)
1012 for (skuname
,skuobj
) in pcd
.SkuInfoList
.items():
1013 datalen
= len(skuobj
.DefaultValue
)
1016 pcd
.MaxDatumSize
= str(MaxSize
)
1019 ## Add external modules
1021 # The external modules are mostly those listed in FDF file, which don't
1024 # @param FilePath The path of module description file
1026 def AddModule(self
, FilePath
):
1027 FilePath
= NormPath(FilePath
)
1028 if FilePath
not in self
.Modules
:
1029 Module
= ModuleBuildClassObject()
1030 Module
.MetaFile
= FilePath
1031 self
.Modules
.append(Module
)
1033 ## Add external PCDs
1035 # The external PCDs are mostly those listed in FDF file to specify address
1036 # or offset information.
1038 # @param Name Name of the PCD
1039 # @param Guid Token space guid of the PCD
1040 # @param Value Value of the PCD
1042 def AddPcd(self
, Name
, Guid
, Value
):
1043 if (Name
, Guid
) not in self
.Pcds
:
1044 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
1045 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
1047 _Macros
= property(_GetMacros
)
1048 Arch
= property(_GetArch
, _SetArch
)
1049 Platform
= property(_GetPlatformName
)
1050 PlatformName
= property(_GetPlatformName
)
1051 Guid
= property(_GetFileGuid
)
1052 Version
= property(_GetVersion
)
1053 DscSpecification
= property(_GetDscSpec
)
1054 OutputDirectory
= property(_GetOutpuDir
)
1055 SupArchList
= property(_GetSupArch
)
1056 BuildTargets
= property(_GetBuildTarget
)
1057 SkuName
= property(_GetSkuName
, _SetSkuName
)
1058 SkuIdentifier
= property(_GetSkuIdentifier
)
1059 PcdInfoFlag
= property(_GetPcdInfoFlag
)
1060 FlashDefinition
= property(_GetFdfFile
)
1061 BuildNumber
= property(_GetBuildNumber
)
1062 MakefileName
= property(_GetMakefileName
)
1063 BsBaseAddress
= property(_GetBsBaseAddress
)
1064 RtBaseAddress
= property(_GetRtBaseAddress
)
1065 LoadFixAddress
= property(_GetLoadFixAddress
)
1066 RFCLanguages
= property(_GetRFCLanguages
)
1067 ISOLanguages
= property(_GetISOLanguages
)
1068 VpdToolGuid
= property(_GetVpdToolGuid
)
1069 SkuIds
= property(_GetSkuIds
)
1070 Modules
= property(_GetModules
)
1071 LibraryInstances
= property(_GetLibraryInstances
)
1072 LibraryClasses
= property(_GetLibraryClasses
)
1073 Pcds
= property(_GetPcds
)
1074 BuildOptions
= property(_GetBuildOptions
)
1076 ## Platform build information from DEC file
1078 # This class is used to retrieve information stored in database and convert them
1079 # into PackageBuildClassObject form for easier use for AutoGen.
1081 class DecBuildData(PackageBuildClassObject
):
1082 # dict used to convert PCD type in database to string used by build tool
1083 _PCD_TYPE_STRING_
= {
1084 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1085 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1086 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1087 MODEL_PCD_DYNAMIC
: "Dynamic",
1088 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1089 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1090 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1091 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1092 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1093 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1094 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1097 # dict used to convert part of [Defines] to members of DecBuildData directly
1102 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
1103 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
1104 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
1105 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
1109 ## Constructor of DecBuildData
1111 # Initialize object of DecBuildData
1113 # @param FilePath The path of package description file
1114 # @param RawData The raw data of DEC file
1115 # @param BuildDataBase Database used to retrieve module information
1116 # @param Arch The target architecture
1117 # @param Platform (not used for DecBuildData)
1118 # @param Macros Macros used for replacement in DSC file
1120 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1121 self
.MetaFile
= File
1122 self
._PackageDir
= File
.Dir
1123 self
._RawData
= RawData
1124 self
._Bdb
= BuildDataBase
1126 self
._Target
= Target
1127 self
._Toolchain
= Toolchain
1131 def __setitem__(self
, key
, value
):
1132 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1135 def __getitem__(self
, key
):
1136 return self
.__dict
__[self
._PROPERTY
_[key
]]
1138 ## "in" test support
1139 def __contains__(self
, key
):
1140 return key
in self
._PROPERTY
_
1142 ## Set all internal used members of DecBuildData to None
1145 self
._PackageName
= None
1147 self
._Version
= None
1148 self
._PkgUniFile
= None
1149 self
._Protocols
= None
1152 self
._Includes
= None
1153 self
._LibraryClasses
= None
1155 self
.__Macros
= None
1157 ## Get current effective macros
1158 def _GetMacros(self
):
1159 if self
.__Macros
== None:
1161 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1162 return self
.__Macros
1170 # Changing the default ARCH to another may affect all other information
1171 # because all information in a platform may be ARCH-related. That's
1172 # why we need to clear all internal used members, in order to cause all
1173 # information to be re-retrieved.
1175 # @param Value The value of ARCH
1177 def _SetArch(self
, Value
):
1178 if self
._Arch
== Value
:
1183 ## Retrieve all information in [Defines] section
1185 # (Retriving all [Defines] information in one-shot is just to save time.)
1187 def _GetHeaderInfo(self
):
1188 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
1189 for Record
in RecordList
:
1192 self
[Name
] = Record
[2]
1193 self
._Header
= 'DUMMY'
1195 ## Retrieve package name
1196 def _GetPackageName(self
):
1197 if self
._PackageName
== None:
1198 if self
._Header
== None:
1199 self
._GetHeaderInfo
()
1200 if self
._PackageName
== None:
1201 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
1202 return self
._PackageName
1204 ## Retrieve file guid
1205 def _GetFileGuid(self
):
1206 if self
._Guid
== None:
1207 if self
._Header
== None:
1208 self
._GetHeaderInfo
()
1209 if self
._Guid
== None:
1210 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
1213 ## Retrieve package version
1214 def _GetVersion(self
):
1215 if self
._Version
== None:
1216 if self
._Header
== None:
1217 self
._GetHeaderInfo
()
1218 if self
._Version
== None:
1220 return self
._Version
1222 ## Retrieve protocol definitions (name/value pairs)
1223 def _GetProtocol(self
):
1224 if self
._Protocols
== None:
1226 # tdict is a special kind of dict, used for selecting correct
1227 # protocol defition for given ARCH
1229 ProtocolDict
= tdict(True)
1231 # find out all protocol definitions for specific and 'common' arch
1232 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
1233 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1234 if Name
not in NameList
:
1235 NameList
.append(Name
)
1236 ProtocolDict
[Arch
, Name
] = Guid
1237 # use sdict to keep the order
1238 self
._Protocols
= sdict()
1239 for Name
in NameList
:
1241 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1242 # will automatically turn to 'common' ARCH for trying
1244 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1245 return self
._Protocols
1247 ## Retrieve PPI definitions (name/value pairs)
1249 if self
._Ppis
== None:
1251 # tdict is a special kind of dict, used for selecting correct
1252 # PPI defition for given ARCH
1254 PpiDict
= tdict(True)
1256 # find out all PPI definitions for specific arch and 'common' arch
1257 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1258 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1259 if Name
not in NameList
:
1260 NameList
.append(Name
)
1261 PpiDict
[Arch
, Name
] = Guid
1262 # use sdict to keep the order
1263 self
._Ppis
= sdict()
1264 for Name
in NameList
:
1266 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1267 # will automatically turn to 'common' ARCH for trying
1269 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1272 ## Retrieve GUID definitions (name/value pairs)
1274 if self
._Guids
== None:
1276 # tdict is a special kind of dict, used for selecting correct
1277 # GUID defition for given ARCH
1279 GuidDict
= tdict(True)
1281 # find out all protocol definitions for specific and 'common' arch
1282 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1283 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1284 if Name
not in NameList
:
1285 NameList
.append(Name
)
1286 GuidDict
[Arch
, Name
] = Guid
1287 # use sdict to keep the order
1288 self
._Guids
= sdict()
1289 for Name
in NameList
:
1291 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1292 # will automatically turn to 'common' ARCH for trying
1294 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1297 ## Retrieve public include paths declared in this package
1298 def _GetInclude(self
):
1299 if self
._Includes
== None:
1301 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1302 Macros
= self
._Macros
1303 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1304 for Record
in RecordList
:
1305 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1308 ErrorCode
, ErrorInfo
= File
.Validate()
1310 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1312 # avoid duplicate include path
1313 if File
not in self
._Includes
:
1314 self
._Includes
.append(File
)
1315 return self
._Includes
1317 ## Retrieve library class declarations (not used in build at present)
1318 def _GetLibraryClass(self
):
1319 if self
._LibraryClasses
== None:
1321 # tdict is a special kind of dict, used for selecting correct
1322 # library class declaration for given ARCH
1324 LibraryClassDict
= tdict(True)
1325 LibraryClassSet
= set()
1326 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1327 Macros
= self
._Macros
1328 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1329 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1330 # check the file validation
1331 ErrorCode
, ErrorInfo
= File
.Validate()
1333 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1334 LibraryClassSet
.add(LibraryClass
)
1335 LibraryClassDict
[Arch
, LibraryClass
] = File
1336 self
._LibraryClasses
= sdict()
1337 for LibraryClass
in LibraryClassSet
:
1338 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1339 return self
._LibraryClasses
1341 ## Retrieve PCD declarations
1343 if self
._Pcds
== None:
1344 self
._Pcds
= sdict()
1345 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1346 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1347 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1348 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1349 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1352 ## Retrieve PCD declarations for given type
1353 def _GetPcd(self
, Type
):
1356 # tdict is a special kind of dict, used for selecting correct
1357 # PCD declaration for given ARCH
1359 PcdDict
= tdict(True, 3)
1360 # for summarizing PCD
1362 # find out all PCDs of the 'type'
1363 RecordList
= self
._RawData
[Type
, self
._Arch
]
1364 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1365 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1366 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1368 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1370 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1371 # will automatically turn to 'common' ARCH and try again
1373 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1377 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1379 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1382 self
._PCD
_TYPE
_STRING
_[Type
],
1394 _Macros
= property(_GetMacros
)
1395 Arch
= property(_GetArch
, _SetArch
)
1396 PackageName
= property(_GetPackageName
)
1397 Guid
= property(_GetFileGuid
)
1398 Version
= property(_GetVersion
)
1400 Protocols
= property(_GetProtocol
)
1401 Ppis
= property(_GetPpi
)
1402 Guids
= property(_GetGuid
)
1403 Includes
= property(_GetInclude
)
1404 LibraryClasses
= property(_GetLibraryClass
)
1405 Pcds
= property(_GetPcds
)
1407 ## Module build information from INF file
1409 # This class is used to retrieve information stored in database and convert them
1410 # into ModuleBuildClassObject form for easier use for AutoGen.
1412 class InfBuildData(ModuleBuildClassObject
):
1413 # dict used to convert PCD type in database to string used by build tool
1414 _PCD_TYPE_STRING_
= {
1415 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1416 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1417 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1418 MODEL_PCD_DYNAMIC
: "Dynamic",
1419 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1420 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1421 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1422 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1423 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1424 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1425 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1428 # dict used to convert part of [Defines] to members of InfBuildData directly
1433 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1434 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1435 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1439 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
1440 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1441 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1442 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1443 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1444 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1445 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1446 TAB_INF_DEFINES_VERSION
: "_Version",
1447 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1448 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1450 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1453 # dict used to convert Component type to Module type
1456 "SECURITY_CORE" : "SEC",
1457 "PEI_CORE" : "PEI_CORE",
1458 "COMBINED_PEIM_DRIVER" : "PEIM",
1459 "PIC_PEIM" : "PEIM",
1460 "RELOCATABLE_PEIM" : "PEIM",
1461 "PE32_PEIM" : "PEIM",
1462 "BS_DRIVER" : "DXE_DRIVER",
1463 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1464 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1465 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1466 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1467 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1468 # "BS_DRIVER" : "UEFI_DRIVER",
1469 "APPLICATION" : "UEFI_APPLICATION",
1473 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1474 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1475 # dict used to convert old tool name used in [nmake] section to new ones
1483 ## Constructor of DscBuildData
1485 # Initialize object of DscBuildData
1487 # @param FilePath The path of platform description file
1488 # @param RawData The raw data of DSC file
1489 # @param BuildDataBase Database used to retrieve module/package information
1490 # @param Arch The target architecture
1491 # @param Platform The name of platform employing this module
1492 # @param Macros Macros used for replacement in DSC file
1494 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Target
=None, Toolchain
=None):
1495 self
.MetaFile
= FilePath
1496 self
._ModuleDir
= FilePath
.Dir
1497 self
._RawData
= RawData
1498 self
._Bdb
= BuildDatabase
1500 self
._Target
= Target
1501 self
._Toolchain
= Toolchain
1502 self
._Platform
= 'COMMON'
1503 self
._SourceOverridePath
= None
1504 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1505 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1509 def __setitem__(self
, key
, value
):
1510 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1513 def __getitem__(self
, key
):
1514 return self
.__dict
__[self
._PROPERTY
_[key
]]
1516 ## "in" test support
1517 def __contains__(self
, key
):
1518 return key
in self
._PROPERTY
_
1520 ## Set all internal used members of InfBuildData to None
1522 self
._HeaderComments
= None
1523 self
._Header
_ = None
1524 self
._AutoGenVersion
= None
1525 self
._BaseName
= None
1526 self
._DxsFile
= None
1527 self
._ModuleType
= None
1528 self
._ComponentType
= None
1529 self
._BuildType
= None
1531 self
._Version
= None
1532 self
._PcdIsDriver
= None
1533 self
._BinaryModule
= None
1535 self
._MakefileName
= None
1536 self
._CustomMakefile
= None
1537 self
._Specification
= None
1538 self
._LibraryClass
= None
1539 self
._ModuleEntryPointList
= None
1540 self
._ModuleUnloadImageList
= None
1541 self
._ConstructorList
= None
1542 self
._DestructorList
= None
1544 self
._Binaries
= None
1545 self
._Sources
= None
1546 self
._LibraryClasses
= None
1547 self
._Libraries
= None
1548 self
._Protocols
= None
1549 self
._ProtocolComments
= None
1551 self
._PpiComments
= None
1553 self
._GuidsUsedByPcd
= sdict()
1554 self
._GuidComments
= None
1555 self
._Includes
= None
1556 self
._Packages
= None
1558 self
._PcdComments
= None
1559 self
._BuildOptions
= None
1561 self
._DepexExpression
= None
1562 self
.__Macros
= None
1564 ## Get current effective macros
1565 def _GetMacros(self
):
1566 if self
.__Macros
== None:
1568 # EDK_GLOBAL defined macros can be applied to EDK module
1569 if self
.AutoGenVersion
< 0x00010005:
1570 self
.__Macros
.update(GlobalData
.gEdkGlobal
)
1571 self
.__Macros
.update(GlobalData
.gGlobalDefines
)
1572 return self
.__Macros
1580 # Changing the default ARCH to another may affect all other information
1581 # because all information in a platform may be ARCH-related. That's
1582 # why we need to clear all internal used members, in order to cause all
1583 # information to be re-retrieved.
1585 # @param Value The value of ARCH
1587 def _SetArch(self
, Value
):
1588 if self
._Arch
== Value
:
1593 ## Return the name of platform employing this module
1594 def _GetPlatform(self
):
1595 return self
._Platform
1597 ## Change the name of platform employing this module
1599 # Changing the default name of platform to another may affect some information
1600 # because they may be PLATFORM-related. That's why we need to clear all internal
1601 # used members, in order to cause all information to be re-retrieved.
1603 def _SetPlatform(self
, Value
):
1604 if self
._Platform
== Value
:
1606 self
._Platform
= Value
1608 def _GetHeaderComments(self
):
1609 if not self
._HeaderComments
:
1610 self
._HeaderComments
= []
1611 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER_COMMENT
]
1612 for Record
in RecordList
:
1613 self
._HeaderComments
.append(Record
[0])
1614 return self
._HeaderComments
1616 ## Retrieve all information in [Defines] section
1618 # (Retriving all [Defines] information in one-shot is just to save time.)
1620 def _GetHeaderInfo(self
):
1621 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1622 for Record
in RecordList
:
1623 Name
, Value
= Record
[1], ReplaceMacro(Record
[2], self
._Macros
, False)
1624 # items defined _PROPERTY_ don't need additional processing
1627 # some special items in [Defines] section need special treatment
1628 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1629 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1630 Name
= 'UEFI_SPECIFICATION_VERSION'
1631 if self
._Specification
== None:
1632 self
._Specification
= sdict()
1633 self
._Specification
[Name
] = GetHexVerValue(Value
)
1634 if self
._Specification
[Name
] == None:
1635 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1636 "'%s' format is not supported for %s" % (Value
, Name
),
1637 File
=self
.MetaFile
, Line
=Record
[-1])
1638 elif Name
== 'LIBRARY_CLASS':
1639 if self
._LibraryClass
== None:
1640 self
._LibraryClass
= []
1641 ValueList
= GetSplitValueList(Value
)
1642 LibraryClass
= ValueList
[0]
1643 if len(ValueList
) > 1:
1644 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1646 SupModuleList
= SUP_MODULE_LIST
1647 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1648 elif Name
== 'ENTRY_POINT':
1649 if self
._ModuleEntryPointList
== None:
1650 self
._ModuleEntryPointList
= []
1651 self
._ModuleEntryPointList
.append(Value
)
1652 elif Name
== 'UNLOAD_IMAGE':
1653 if self
._ModuleUnloadImageList
== None:
1654 self
._ModuleUnloadImageList
= []
1657 self
._ModuleUnloadImageList
.append(Value
)
1658 elif Name
== 'CONSTRUCTOR':
1659 if self
._ConstructorList
== None:
1660 self
._ConstructorList
= []
1663 self
._ConstructorList
.append(Value
)
1664 elif Name
== 'DESTRUCTOR':
1665 if self
._DestructorList
== None:
1666 self
._DestructorList
= []
1669 self
._DestructorList
.append(Value
)
1670 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1671 TokenList
= GetSplitValueList(Value
)
1672 if self
._CustomMakefile
== None:
1673 self
._CustomMakefile
= {}
1674 if len(TokenList
) < 2:
1675 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1676 self
._CustomMakefile
['GCC'] = TokenList
[0]
1678 if TokenList
[0] not in ['MSFT', 'GCC']:
1679 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1680 "No supported family [%s]" % TokenList
[0],
1681 File
=self
.MetaFile
, Line
=Record
[-1])
1682 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1684 if self
._Defs
== None:
1685 self
._Defs
= sdict()
1686 self
._Defs
[Name
] = Value
1689 # Retrieve information in sections specific to Edk.x modules
1691 if self
.AutoGenVersion
>= 0x00010005:
1692 if not self
._ModuleType
:
1693 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1694 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1695 if self
._ModuleType
not in SUP_MODULE_LIST
:
1696 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1697 for Record
in RecordList
:
1699 if Name
== "MODULE_TYPE":
1702 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1703 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1704 File
=self
.MetaFile
, Line
=LineNo
)
1705 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1706 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1707 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
)
1708 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1709 and 'PCI_CLASS_CODE' in self
._Defs
:
1710 self
._BuildType
= 'UEFI_OPTIONROM'
1711 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1712 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1713 self
._BuildType
= 'UEFI_HII'
1715 self
._BuildType
= self
._ModuleType
.upper()
1718 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1719 # check the file validation
1720 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1722 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1723 File
=self
.MetaFile
, Line
=LineNo
)
1724 if self
.Sources
== None:
1726 self
._Sources
.append(File
)
1728 if not self
._ComponentType
:
1729 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1730 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1731 self
._BuildType
= self
._ComponentType
.upper()
1732 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1733 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1734 if self
._ComponentType
== 'LIBRARY':
1735 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1736 # make use some [nmake] section macros
1737 Macros
= self
._Macros
1738 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1739 Macros
['PROCESSOR'] = self
._Arch
1740 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1741 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1742 Value
= ReplaceMacro(Value
, Macros
, True)
1743 if Name
== "IMAGE_ENTRY_POINT":
1744 if self
._ModuleEntryPointList
== None:
1745 self
._ModuleEntryPointList
= []
1746 self
._ModuleEntryPointList
.append(Value
)
1747 elif Name
== "DPX_SOURCE":
1748 File
= PathClass(NormPath(Value
), self
._ModuleDir
, Arch
=self
._Arch
)
1749 # check the file validation
1750 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1752 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1753 File
=self
.MetaFile
, Line
=LineNo
)
1754 if self
.Sources
== None:
1756 self
._Sources
.append(File
)
1758 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1759 if len(ToolList
) == 0 or len(ToolList
) != 1:
1761 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1762 # File=self.MetaFile, Line=LineNo)
1764 if self
._BuildOptions
== None:
1765 self
._BuildOptions
= sdict()
1767 if ToolList
[0] in self
._TOOL
_CODE
_:
1768 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1771 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1772 ToolChainFamily
= 'MSFT' # Edk.x only support MSFT tool chain
1773 #ignore not replaced macros in value
1774 ValueList
= GetSplitList(' ' + Value
, '/D')
1775 Dummy
= ValueList
[0]
1776 for Index
in range(1, len(ValueList
)):
1777 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1779 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1780 Value
= Dummy
.strip()
1781 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1782 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1784 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1785 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1786 # set _Header to non-None in order to avoid database re-querying
1787 self
._Header
_ = 'DUMMY'
1789 ## Retrieve file version
1790 def _GetInfVersion(self
):
1791 if self
._AutoGenVersion
== None:
1792 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1793 for Record
in RecordList
:
1794 if Record
[1] == TAB_INF_DEFINES_INF_VERSION
:
1795 self
._AutoGenVersion
= int(Record
[2], 0)
1797 if self
._AutoGenVersion
== None:
1798 self
._AutoGenVersion
= 0x00010000
1799 return self
._AutoGenVersion
1801 ## Retrieve BASE_NAME
1802 def _GetBaseName(self
):
1803 if self
._BaseName
== None:
1804 if self
._Header
_ == None:
1805 self
._GetHeaderInfo
()
1806 if self
._BaseName
== None:
1807 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1808 return self
._BaseName
1811 def _GetDxsFile(self
):
1812 if self
._DxsFile
== None:
1813 if self
._Header
_ == None:
1814 self
._GetHeaderInfo
()
1815 if self
._DxsFile
== None:
1817 return self
._DxsFile
1819 ## Retrieve MODULE_TYPE
1820 def _GetModuleType(self
):
1821 if self
._ModuleType
== None:
1822 if self
._Header
_ == None:
1823 self
._GetHeaderInfo
()
1824 if self
._ModuleType
== None:
1825 self
._ModuleType
= 'BASE'
1826 if self
._ModuleType
not in SUP_MODULE_LIST
:
1827 self
._ModuleType
= "USER_DEFINED"
1828 return self
._ModuleType
1830 ## Retrieve COMPONENT_TYPE
1831 def _GetComponentType(self
):
1832 if self
._ComponentType
== None:
1833 if self
._Header
_ == None:
1834 self
._GetHeaderInfo
()
1835 if self
._ComponentType
== None:
1836 self
._ComponentType
= 'USER_DEFINED'
1837 return self
._ComponentType
1839 ## Retrieve "BUILD_TYPE"
1840 def _GetBuildType(self
):
1841 if self
._BuildType
== None:
1842 if self
._Header
_ == None:
1843 self
._GetHeaderInfo
()
1844 if not self
._BuildType
:
1845 self
._BuildType
= "BASE"
1846 return self
._BuildType
1848 ## Retrieve file guid
1849 def _GetFileGuid(self
):
1850 if self
._Guid
== None:
1851 if self
._Header
_ == None:
1852 self
._GetHeaderInfo
()
1853 if self
._Guid
== None:
1854 self
._Guid
= '00000000-0000-0000-000000000000'
1857 ## Retrieve module version
1858 def _GetVersion(self
):
1859 if self
._Version
== None:
1860 if self
._Header
_ == None:
1861 self
._GetHeaderInfo
()
1862 if self
._Version
== None:
1863 self
._Version
= '0.0'
1864 return self
._Version
1866 ## Retrieve PCD_IS_DRIVER
1867 def _GetPcdIsDriver(self
):
1868 if self
._PcdIsDriver
== None:
1869 if self
._Header
_ == None:
1870 self
._GetHeaderInfo
()
1871 if self
._PcdIsDriver
== None:
1872 self
._PcdIsDriver
= ''
1873 return self
._PcdIsDriver
1876 def _GetShadow(self
):
1877 if self
._Shadow
== None:
1878 if self
._Header
_ == None:
1879 self
._GetHeaderInfo
()
1880 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1883 self
._Shadow
= False
1886 ## Retrieve CUSTOM_MAKEFILE
1887 def _GetMakefile(self
):
1888 if self
._CustomMakefile
== None:
1889 if self
._Header
_ == None:
1890 self
._GetHeaderInfo
()
1891 if self
._CustomMakefile
== None:
1892 self
._CustomMakefile
= {}
1893 return self
._CustomMakefile
1895 ## Retrieve EFI_SPECIFICATION_VERSION
1897 if self
._Specification
== None:
1898 if self
._Header
_ == None:
1899 self
._GetHeaderInfo
()
1900 if self
._Specification
== None:
1901 self
._Specification
= {}
1902 return self
._Specification
1904 ## Retrieve LIBRARY_CLASS
1905 def _GetLibraryClass(self
):
1906 if self
._LibraryClass
== None:
1907 if self
._Header
_ == None:
1908 self
._GetHeaderInfo
()
1909 if self
._LibraryClass
== None:
1910 self
._LibraryClass
= []
1911 return self
._LibraryClass
1913 ## Retrieve ENTRY_POINT
1914 def _GetEntryPoint(self
):
1915 if self
._ModuleEntryPointList
== None:
1916 if self
._Header
_ == None:
1917 self
._GetHeaderInfo
()
1918 if self
._ModuleEntryPointList
== None:
1919 self
._ModuleEntryPointList
= []
1920 return self
._ModuleEntryPointList
1922 ## Retrieve UNLOAD_IMAGE
1923 def _GetUnloadImage(self
):
1924 if self
._ModuleUnloadImageList
== None:
1925 if self
._Header
_ == None:
1926 self
._GetHeaderInfo
()
1927 if self
._ModuleUnloadImageList
== None:
1928 self
._ModuleUnloadImageList
= []
1929 return self
._ModuleUnloadImageList
1931 ## Retrieve CONSTRUCTOR
1932 def _GetConstructor(self
):
1933 if self
._ConstructorList
== None:
1934 if self
._Header
_ == None:
1935 self
._GetHeaderInfo
()
1936 if self
._ConstructorList
== None:
1937 self
._ConstructorList
= []
1938 return self
._ConstructorList
1940 ## Retrieve DESTRUCTOR
1941 def _GetDestructor(self
):
1942 if self
._DestructorList
== None:
1943 if self
._Header
_ == None:
1944 self
._GetHeaderInfo
()
1945 if self
._DestructorList
== None:
1946 self
._DestructorList
= []
1947 return self
._DestructorList
1949 ## Retrieve definies other than above ones
1950 def _GetDefines(self
):
1951 if self
._Defs
== None:
1952 if self
._Header
_ == None:
1953 self
._GetHeaderInfo
()
1954 if self
._Defs
== None:
1955 self
._Defs
= sdict()
1958 ## Retrieve binary files
1959 def _GetBinaryFiles(self
):
1960 if self
._Binaries
== None:
1962 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
1963 Macros
= self
._Macros
1964 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
1965 Macros
['PROCESSOR'] = self
._Arch
1966 for Record
in RecordList
:
1967 FileType
= Record
[0]
1972 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
1974 Target
= TokenList
[0]
1975 if len(TokenList
) > 1:
1976 FeatureFlag
= Record
[1:]
1978 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
1979 # check the file validation
1980 ErrorCode
, ErrorInfo
= File
.Validate()
1982 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1983 self
._Binaries
.append(File
)
1984 return self
._Binaries
1986 ## Retrieve source files
1987 def _GetSourceFiles(self
):
1988 if self
._Sources
== None:
1990 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
1991 Macros
= self
._Macros
1992 for Record
in RecordList
:
1994 ToolChainFamily
= Record
[1]
1996 ToolCode
= Record
[3]
1997 FeatureFlag
= Record
[4]
1998 if self
.AutoGenVersion
< 0x00010005:
1999 Macros
["EDK_SOURCE"] = GlobalData
.gEcpSource
2000 Macros
['PROCESSOR'] = self
._Arch
2001 # old module source files (Edk)
2002 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
2003 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2004 # check the file validation
2005 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
2007 if File
.Ext
.lower() == '.h':
2008 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
2009 File
=self
.MetaFile
, Line
=LineNo
)
2012 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
2014 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
2015 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
2016 # check the file validation
2017 ErrorCode
, ErrorInfo
= File
.Validate()
2019 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2021 self
._Sources
.append(File
)
2022 return self
._Sources
2024 ## Retrieve library classes employed by this module
2025 def _GetLibraryClassUses(self
):
2026 if self
._LibraryClasses
== None:
2027 self
._LibraryClasses
= sdict()
2028 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
2029 for Record
in RecordList
:
2031 Instance
= Record
[1]
2033 Instance
= NormPath(Instance
, self
._Macros
)
2034 self
._LibraryClasses
[Lib
] = Instance
2035 return self
._LibraryClasses
2037 ## Retrieve library names (for Edk.x style of modules)
2038 def _GetLibraryNames(self
):
2039 if self
._Libraries
== None:
2040 self
._Libraries
= []
2041 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
2042 for Record
in RecordList
:
2043 LibraryName
= ReplaceMacro(Record
[0], self
._Macros
, False)
2044 # in case of name with '.lib' extension, which is unusual in Edk.x inf
2045 LibraryName
= os
.path
.splitext(LibraryName
)[0]
2046 if LibraryName
not in self
._Libraries
:
2047 self
._Libraries
.append(LibraryName
)
2048 return self
._Libraries
2050 def _GetProtocolComments(self
):
2051 self
._GetProtocols
()
2052 return self
._ProtocolComments
2053 ## Retrieve protocols consumed/produced by this module
2054 def _GetProtocols(self
):
2055 if self
._Protocols
== None:
2056 self
._Protocols
= sdict()
2057 self
._ProtocolComments
= sdict()
2058 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
2059 for Record
in RecordList
:
2061 Value
= ProtocolValue(CName
, self
.Packages
)
2063 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2064 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2065 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
2066 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2067 self
._Protocols
[CName
] = Value
2068 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2070 for CmtRec
in CommentRecords
:
2071 Comments
.append(CmtRec
[0])
2072 self
._ProtocolComments
[CName
] = Comments
2073 return self
._Protocols
2075 def _GetPpiComments(self
):
2077 return self
._PpiComments
2078 ## Retrieve PPIs consumed/produced by this module
2080 if self
._Ppis
== None:
2081 self
._Ppis
= sdict()
2082 self
._PpiComments
= sdict()
2083 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
2084 for Record
in RecordList
:
2086 Value
= PpiValue(CName
, self
.Packages
)
2088 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2089 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2090 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
2091 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2092 self
._Ppis
[CName
] = Value
2093 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2095 for CmtRec
in CommentRecords
:
2096 Comments
.append(CmtRec
[0])
2097 self
._PpiComments
[CName
] = Comments
2100 def _GetGuidComments(self
):
2102 return self
._GuidComments
2103 ## Retrieve GUIDs consumed/produced by this module
2104 def _GetGuids(self
):
2105 if self
._Guids
== None:
2106 self
._Guids
= sdict()
2107 self
._GuidComments
= sdict()
2108 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
2109 for Record
in RecordList
:
2111 Value
= GuidValue(CName
, self
.Packages
)
2113 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2114 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2115 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
2116 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2117 self
._Guids
[CName
] = Value
2118 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Record
[5]]
2120 for CmtRec
in CommentRecords
:
2121 Comments
.append(CmtRec
[0])
2122 self
._GuidComments
[CName
] = Comments
2125 ## Retrieve include paths necessary for this module (for Edk.x style of modules)
2126 def _GetIncludes(self
):
2127 if self
._Includes
== None:
2129 if self
._SourceOverridePath
:
2130 self
._Includes
.append(self
._SourceOverridePath
)
2132 Macros
= self
._Macros
2133 if 'PROCESSOR' in GlobalData
.gEdkGlobal
.keys():
2134 Macros
['PROCESSOR'] = GlobalData
.gEdkGlobal
['PROCESSOR']
2136 Macros
['PROCESSOR'] = self
._Arch
2137 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
2138 for Record
in RecordList
:
2139 if Record
[0].find('EDK_SOURCE') > -1:
2140 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2141 File
= NormPath(Record
[0], self
._Macros
)
2143 File
= os
.path
.join(self
._ModuleDir
, File
)
2145 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2146 File
= RealPath(os
.path
.normpath(File
))
2148 self
._Includes
.append(File
)
2150 #TRICK: let compiler to choose correct header file
2151 Macros
['EDK_SOURCE'] = GlobalData
.gEdkSource
2152 File
= NormPath(Record
[0], self
._Macros
)
2154 File
= os
.path
.join(self
._ModuleDir
, File
)
2156 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2157 File
= RealPath(os
.path
.normpath(File
))
2159 self
._Includes
.append(File
)
2161 File
= NormPath(Record
[0], Macros
)
2163 File
= os
.path
.join(self
._ModuleDir
, File
)
2165 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
2166 File
= RealPath(os
.path
.normpath(File
))
2168 self
._Includes
.append(File
)
2169 return self
._Includes
2171 ## Retrieve packages this module depends on
2172 def _GetPackages(self
):
2173 if self
._Packages
== None:
2175 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
2176 Macros
= self
._Macros
2177 Macros
['EDK_SOURCE'] = GlobalData
.gEcpSource
2178 for Record
in RecordList
:
2179 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
2181 # check the file validation
2182 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
2184 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
2185 # parse this package now. we need it to get protocol/ppi/guid value
2186 Package
= self
._Bdb
[File
, self
._Arch
, self
._Target
, self
._Toolchain
]
2187 self
._Packages
.append(Package
)
2188 return self
._Packages
2190 ## Retrieve PCD comments
2191 def _GetPcdComments(self
):
2193 return self
._PcdComments
2194 ## Retrieve PCDs used in this module
2196 if self
._Pcds
== None:
2197 self
._Pcds
= sdict()
2198 self
._PcdComments
= sdict()
2199 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
2200 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
2201 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
2202 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
2203 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
2206 ## Retrieve build options specific to this module
2207 def _GetBuildOptions(self
):
2208 if self
._BuildOptions
== None:
2209 self
._BuildOptions
= sdict()
2210 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
2211 for Record
in RecordList
:
2212 ToolChainFamily
= Record
[0]
2213 ToolChain
= Record
[1]
2215 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
2216 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
2218 # concatenate the option string if they're for the same tool
2219 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
2220 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
2221 return self
._BuildOptions
2223 ## Retrieve dependency expression
2224 def _GetDepex(self
):
2225 if self
._Depex
== None:
2226 self
._Depex
= tdict(False, 2)
2227 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2229 # If the module has only Binaries and no Sources, then ignore [Depex]
2230 if self
.Sources
== None or self
.Sources
== []:
2231 if self
.Binaries
!= None and self
.Binaries
!= []:
2234 # PEIM and DXE drivers must have a valid [Depex] section
2235 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
2236 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
2237 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
2238 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
2239 % self
.ModuleType
, File
=self
.MetaFile
)
2242 for Record
in RecordList
:
2243 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2245 ModuleType
= Record
[4]
2246 TokenList
= DepexStr
.split()
2247 if (Arch
, ModuleType
) not in Depex
:
2248 Depex
[Arch
, ModuleType
] = []
2249 DepexList
= Depex
[Arch
, ModuleType
]
2250 for Token
in TokenList
:
2251 if Token
in DEPEX_SUPPORTED_OPCODE
:
2252 DepexList
.append(Token
)
2253 elif Token
.endswith(".inf"): # module file name
2254 ModuleFile
= os
.path
.normpath(Token
)
2255 Module
= self
.BuildDatabase
[ModuleFile
]
2257 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
2258 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
2259 DepexList
.append(Module
.Guid
)
2261 # get the GUID value now
2262 Value
= ProtocolValue(Token
, self
.Packages
)
2264 Value
= PpiValue(Token
, self
.Packages
)
2266 Value
= GuidValue(Token
, self
.Packages
)
2268 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2269 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2270 "Value of [%s] is not found in" % Token
,
2271 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
2272 DepexList
.append(Value
)
2273 for Arch
, ModuleType
in Depex
:
2274 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
2277 ## Retrieve depedency expression
2278 def _GetDepexExpression(self
):
2279 if self
._DepexExpression
== None:
2280 self
._DepexExpression
= tdict(False, 2)
2281 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
2282 DepexExpression
= sdict()
2283 for Record
in RecordList
:
2284 DepexStr
= ReplaceMacro(Record
[0], self
._Macros
, False)
2286 ModuleType
= Record
[4]
2287 TokenList
= DepexStr
.split()
2288 if (Arch
, ModuleType
) not in DepexExpression
:
2289 DepexExpression
[Arch
, ModuleType
] = ''
2290 for Token
in TokenList
:
2291 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
2292 for Arch
, ModuleType
in DepexExpression
:
2293 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
2294 return self
._DepexExpression
2296 def GetGuidsUsedByPcd(self
):
2297 return self
._GuidsUsedByPcd
2298 ## Retrieve PCD for given type
2299 def _GetPcd(self
, Type
):
2301 PcdDict
= tdict(True, 4)
2303 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2304 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Id
, LineNo
in RecordList
:
2305 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2306 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2307 # get the guid value
2308 if TokenSpaceGuid
not in self
.Guids
:
2309 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2311 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2312 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2313 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2314 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2315 self
.Guids
[TokenSpaceGuid
] = Value
2316 self
._GuidsUsedByPcd
[TokenSpaceGuid
] = Value
2317 CommentRecords
= self
._RawData
[MODEL_META_DATA_COMMENT
, self
._Arch
, self
._Platform
, Id
]
2319 for CmtRec
in CommentRecords
:
2320 Comments
.append(CmtRec
[0])
2321 self
._PcdComments
[TokenSpaceGuid
, PcdCName
] = Comments
2323 # resolve PCD type, value, datum info, etc. by getting its definition from package
2324 for PcdCName
, TokenSpaceGuid
in PcdList
:
2325 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2328 ValueList
= AnalyzePcdData(Setting
)
2329 DefaultValue
= ValueList
[0]
2330 Pcd
= PcdClassObject(
2340 self
.Guids
[TokenSpaceGuid
]
2342 if Type
== MODEL_PCD_PATCHABLE_IN_MODULE
and ValueList
[1]:
2343 # Patch PCD: TokenSpace.PcdCName|Value|Offset
2344 Pcd
.Offset
= ValueList
[1]
2346 # get necessary info from package declaring this PCD
2347 for Package
in self
.Packages
:
2349 # 'dynamic' in INF means its type is determined by platform;
2350 # if platform doesn't give its type, use 'lowest' one in the
2351 # following order, if any
2353 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2355 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2356 if Type
== MODEL_PCD_DYNAMIC
:
2358 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2359 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2365 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2366 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2368 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2371 # Check whether the token value exist or not.
2373 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2377 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2378 File
=self
.MetaFile
, Line
=LineNo
,
2382 # Check hexadecimal token value length and format.
2384 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2385 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2386 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2390 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2391 File
=self
.MetaFile
, Line
=LineNo
,
2396 # Check decimal token value length and format.
2400 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2401 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2405 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!"% (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2406 File
=self
.MetaFile
, Line
=LineNo
,
2413 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!"% (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2414 File
=self
.MetaFile
, Line
=LineNo
,
2418 Pcd
.DatumType
= PcdInPackage
.DatumType
2419 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2420 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2421 if Pcd
.DefaultValue
in [None, '']:
2422 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2428 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2429 File
=self
.MetaFile
, Line
=LineNo
,
2430 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2432 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2436 ## check whether current module is binary module
2437 def _IsBinaryModule(self
):
2438 if self
.Binaries
and not self
.Sources
:
2440 elif GlobalData
.gIgnoreSource
:
2445 _Macros
= property(_GetMacros
)
2446 Arch
= property(_GetArch
, _SetArch
)
2447 Platform
= property(_GetPlatform
, _SetPlatform
)
2449 HeaderComments
= property(_GetHeaderComments
)
2450 AutoGenVersion
= property(_GetInfVersion
)
2451 BaseName
= property(_GetBaseName
)
2452 ModuleType
= property(_GetModuleType
)
2453 ComponentType
= property(_GetComponentType
)
2454 BuildType
= property(_GetBuildType
)
2455 Guid
= property(_GetFileGuid
)
2456 Version
= property(_GetVersion
)
2457 PcdIsDriver
= property(_GetPcdIsDriver
)
2458 Shadow
= property(_GetShadow
)
2459 CustomMakefile
= property(_GetMakefile
)
2460 Specification
= property(_GetSpec
)
2461 LibraryClass
= property(_GetLibraryClass
)
2462 ModuleEntryPointList
= property(_GetEntryPoint
)
2463 ModuleUnloadImageList
= property(_GetUnloadImage
)
2464 ConstructorList
= property(_GetConstructor
)
2465 DestructorList
= property(_GetDestructor
)
2466 Defines
= property(_GetDefines
)
2467 DxsFile
= property(_GetDxsFile
)
2469 Binaries
= property(_GetBinaryFiles
)
2470 Sources
= property(_GetSourceFiles
)
2471 LibraryClasses
= property(_GetLibraryClassUses
)
2472 Libraries
= property(_GetLibraryNames
)
2473 Protocols
= property(_GetProtocols
)
2474 ProtocolComments
= property(_GetProtocolComments
)
2475 Ppis
= property(_GetPpis
)
2476 PpiComments
= property(_GetPpiComments
)
2477 Guids
= property(_GetGuids
)
2478 GuidComments
= property(_GetGuidComments
)
2479 Includes
= property(_GetIncludes
)
2480 Packages
= property(_GetPackages
)
2481 Pcds
= property(_GetPcds
)
2482 PcdComments
= property(_GetPcdComments
)
2483 BuildOptions
= property(_GetBuildOptions
)
2484 Depex
= property(_GetDepex
)
2485 DepexExpression
= property(_GetDepexExpression
)
2486 IsBinaryModule
= property(_IsBinaryModule
)
2490 # This class defined the build database for all modules, packages and platform.
2491 # It will call corresponding parser for the given file if it cannot find it in
2494 # @param DbPath Path of database file
2495 # @param GlobalMacros Global macros used for replacement during file parsing
2496 # @prarm RenewDb=False Create new database file if it's already there
2498 class WorkspaceDatabase(object):
2500 # default database file path
2501 _DB_PATH_
= "Conf/.cache/build.db"
2504 # internal class used for call corresponding file parser and caching the result
2505 # to avoid unnecessary re-parsing
2507 class BuildObjectFactory(object):
2510 ".inf" : MODEL_FILE_INF
,
2511 ".dec" : MODEL_FILE_DEC
,
2512 ".dsc" : MODEL_FILE_DSC
,
2517 MODEL_FILE_INF
: InfParser
,
2518 MODEL_FILE_DEC
: DecParser
,
2519 MODEL_FILE_DSC
: DscParser
,
2522 # convert to xxxBuildData object
2524 MODEL_FILE_INF
: InfBuildData
,
2525 MODEL_FILE_DEC
: DecBuildData
,
2526 MODEL_FILE_DSC
: DscBuildData
,
2529 _CACHE_
= {} # (FilePath, Arch) : <object>
2532 def __init__(self
, WorkspaceDb
):
2533 self
.WorkspaceDb
= WorkspaceDb
2535 # key = (FilePath, Arch=None)
2536 def __contains__(self
, Key
):
2542 return (FilePath
, Arch
) in self
._CACHE
_
2544 # key = (FilePath, Arch=None, Target=None, Toochain=None)
2545 def __getitem__(self
, Key
):
2547 KeyLength
= len(Key
)
2561 # if it's generated before, just return the cached one
2562 Key
= (FilePath
, Arch
, Target
, Toolchain
)
2563 if Key
in self
._CACHE
_:
2564 return self
._CACHE
_[Key
]
2568 if Ext
not in self
._FILE
_TYPE
_:
2570 FileType
= self
._FILE
_TYPE
_[Ext
]
2571 if FileType
not in self
._GENERATOR
_:
2574 # get the parser ready for this file
2575 MetaFile
= self
._FILE
_PARSER
_[FileType
](
2578 MetaFileStorage(self
.WorkspaceDb
.Cur
, FilePath
, FileType
)
2580 # alwasy do post-process, in case of macros change
2581 MetaFile
.DoPostProcess()
2582 # object the build is based on
2583 BuildObject
= self
._GENERATOR
_[FileType
](
2591 self
._CACHE
_[Key
] = BuildObject
2594 # placeholder for file format conversion
2595 class TransformObjectFactory
:
2596 def __init__(self
, WorkspaceDb
):
2597 self
.WorkspaceDb
= WorkspaceDb
2599 # key = FilePath, Arch
2600 def __getitem__(self
, Key
):
2603 ## Constructor of WorkspaceDatabase
2605 # @param DbPath Path of database file
2606 # @param GlobalMacros Global macros used for replacement during file parsing
2607 # @prarm RenewDb=False Create new database file if it's already there
2609 def __init__(self
, DbPath
, RenewDb
=False):
2610 self
._DbClosedFlag
= False
2612 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2614 # don't create necessary path for db in memory
2615 if DbPath
!= ':memory:':
2616 DbDir
= os
.path
.split(DbPath
)[0]
2617 if not os
.path
.exists(DbDir
):
2620 # remove db file in case inconsistency between db and file in file system
2621 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2624 # create db with optimized parameters
2625 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2626 self
.Conn
.execute("PRAGMA synchronous=OFF")
2627 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2628 self
.Conn
.execute("PRAGMA count_changes=OFF")
2629 self
.Conn
.execute("PRAGMA cache_size=8192")
2630 #self.Conn.execute("PRAGMA page_size=8192")
2632 # to avoid non-ascii character conversion issue
2633 self
.Conn
.text_factory
= str
2634 self
.Cur
= self
.Conn
.cursor()
2636 # create table for internal uses
2637 self
.TblDataModel
= TableDataModel(self
.Cur
)
2638 self
.TblFile
= TableFile(self
.Cur
)
2639 self
.Platform
= None
2641 # conversion object for build or file format conversion purpose
2642 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2643 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2645 ## Check whether workspace database need to be renew.
2646 # The renew reason maybe:
2647 # 1) If user force to renew;
2648 # 2) If user do not force renew, and
2649 # a) If the time of last modified python source is newer than database file;
2650 # b) If the time of last modified frozen executable file is newer than database file;
2652 # @param force User force renew database
2653 # @param DbPath The absolute path of workspace database file
2655 # @return Bool value for whether need renew workspace databse
2657 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2658 # if database does not exist, we need do nothing
2659 if not os
.path
.exists(DbPath
): return False
2661 # if user force to renew database, then not check whether database is out of date
2662 if force
: return True
2665 # Check the time of last modified source file or build.exe
2666 # if is newer than time of database, then database need to be re-created.
2668 timeOfToolModified
= 0
2669 if hasattr(sys
, "frozen"):
2670 exePath
= os
.path
.abspath(sys
.executable
)
2671 timeOfToolModified
= os
.stat(exePath
).st_mtime
2673 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2674 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2675 if rootPath
== "" or rootPath
== None:
2676 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2677 determine whether database file is out of date!\n")
2679 # walk the root path of source or build's binary to get the time last modified.
2681 for root
, dirs
, files
in os
.walk (rootPath
):
2683 # bypass source control folder
2684 if dir.lower() in [".svn", "_svn", "cvs"]:
2688 ext
= os
.path
.splitext(file)[1]
2689 if ext
.lower() == ".py": # only check .py files
2690 fd
= os
.stat(os
.path
.join(root
, file))
2691 if timeOfToolModified
< fd
.st_mtime
:
2692 timeOfToolModified
= fd
.st_mtime
2693 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2694 EdkLogger
.verbose("\nWorkspace database is out of data!")
2699 ## Initialize build database
2700 def InitDatabase(self
):
2701 EdkLogger
.verbose("\nInitialize build database started ...")
2706 self
.TblDataModel
.Create(False)
2707 self
.TblFile
.Create(False)
2710 # Initialize table DataModel
2712 self
.TblDataModel
.InitTable()
2713 EdkLogger
.verbose("Initialize build database ... DONE!")
2717 # @param Table: The instance of the table to be queried
2719 def QueryTable(self
, Table
):
2725 ## Close entire database
2728 # Close the connection and cursor
2731 if not self
._DbClosedFlag
:
2735 self
._DbClosedFlag
= True
2737 ## Summarize all packages in the database
2738 def GetPackageList(self
, Platform
, Arch
, TargetName
, ToolChainTag
):
2739 self
.Platform
= Platform
2741 Pa
= self
.BuildObject
[self
.Platform
, 'COMMON']
2743 # Get Package related to Modules
2745 for Module
in Pa
.Modules
:
2746 ModuleObj
= self
.BuildObject
[Module
, Arch
, TargetName
, ToolChainTag
]
2747 for Package
in ModuleObj
.Packages
:
2748 if Package
not in PackageList
:
2749 PackageList
.append(Package
)
2751 # Get Packages related to Libraries
2753 for Lib
in Pa
.LibraryInstances
:
2754 LibObj
= self
.BuildObject
[Lib
, Arch
, TargetName
, ToolChainTag
]
2755 for Package
in LibObj
.Packages
:
2756 if Package
not in PackageList
:
2757 PackageList
.append(Package
)
2761 ## Summarize all platforms in the database
2762 def _GetPlatformList(self
):
2764 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2766 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2769 if Platform
!= None:
2770 PlatformList
.append(Platform
)
2773 PlatformList
= property(_GetPlatformList
)
2777 # This acts like the main() function for the script, unless it is 'import'ed into another
2780 if __name__
== '__main__':