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 *
38 ## Platform build information from DSC file
40 # This class is used to retrieve information stored in database and convert them
41 # into PlatformBuildClassObject form for easier use for AutoGen.
43 class DscBuildData(PlatformBuildClassObject
):
44 # dict used to convert PCD type in database to string used by build tool
46 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
47 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
48 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
49 MODEL_PCD_DYNAMIC
: "Dynamic",
50 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
51 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
52 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
53 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
54 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
55 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
56 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
59 # dict used to convert part of [Defines] to members of DscBuildData directly
64 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
65 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
66 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
67 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
68 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
69 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
70 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
71 #TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
72 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
73 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
74 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
75 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
76 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
77 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
78 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
81 # used to compose dummy library class name for those forced library instances
82 _NullLibraryNumber
= 0
84 ## Constructor of DscBuildData
86 # Initialize object of DscBuildData
88 # @param FilePath The path of platform description file
89 # @param RawData The raw data of DSC file
90 # @param BuildDataBase Database used to retrieve module/package information
91 # @param Arch The target architecture
92 # @param Platform (not used for DscBuildData)
93 # @param Macros Macros used for replacement in DSC file
95 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Platform
='DUMMY', Macros
={}):
96 self
.MetaFile
= FilePath
97 self
._RawData
= RawData
98 self
._Bdb
= BuildDataBase
100 self
._Macros
= Macros
102 RecordList
= self
._RawData
[MODEL_META_DATA_DEFINE
, self
._Arch
]
103 for Record
in RecordList
:
104 GlobalData
.gEdkGlobal
[Record
[0]] = Record
[1]
106 RecordList
= self
._RawData
[MODEL_META_DATA_GLOBAL_DEFINE
, self
._Arch
]
107 for Record
in RecordList
:
108 GlobalData
.gGlobalDefines
[Record
[0]] = Record
[1]
111 def __setitem__(self
, key
, value
):
112 self
.__dict
__[self
._PROPERTY
_[key
]] = value
115 def __getitem__(self
, key
):
116 return self
.__dict
__[self
._PROPERTY
_[key
]]
119 def __contains__(self
, key
):
120 return key
in self
._PROPERTY
_
122 ## Set all internal used members of DscBuildData to None
125 self
._PlatformName
= None
128 self
._DscSpecification
= None
129 self
._OutputDirectory
= None
130 self
._SupArchList
= None
131 self
._BuildTargets
= None
133 self
._FlashDefinition
= None
134 self
._BuildNumber
= None
135 self
._MakefileName
= None
136 self
._BsBaseAddress
= None
137 self
._RtBaseAddress
= None
140 self
._LibraryInstances
= None
141 self
._LibraryClasses
= None
143 self
._BuildOptions
= None
144 self
._LoadFixAddress
= None
145 self
._RFCLanguages
= None
146 self
._ISOLanguages
= None
147 self
._VpdToolGuid
= None
155 # Changing the default ARCH to another may affect all other information
156 # because all information in a platform may be ARCH-related. That's
157 # why we need to clear all internal used members, in order to cause all
158 # information to be re-retrieved.
160 # @param Value The value of ARCH
162 def _SetArch(self
, Value
):
163 if self
._Arch
== Value
:
168 ## Retrieve all information in [Defines] section
170 # (Retriving all [Defines] information in one-shot is just to save time.)
172 def _GetHeaderInfo(self
):
173 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
174 for Record
in RecordList
:
176 # items defined _PROPERTY_ don't need additional processing
178 self
[Name
] = Record
[1]
179 # some special items in [Defines] section need special treatment
180 elif Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
181 self
._OutputDirectory
= NormPath(Record
[1], self
._Macros
)
182 if ' ' in self
._OutputDirectory
:
183 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
184 File
=self
.MetaFile
, Line
=Record
[-1],
185 ExtraData
=self
._OutputDirectory
)
186 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
187 self
._FlashDefinition
= PathClass(NormPath(Record
[1], self
._Macros
), GlobalData
.gWorkspace
)
188 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
190 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
192 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
193 self
._SupArchList
= GetSplitValueList(Record
[1], TAB_VALUE_SPLIT
)
194 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
195 self
._BuildTargets
= GetSplitValueList(Record
[1])
196 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
197 if self
._SkuName
== None:
198 self
._SkuName
= Record
[1]
199 elif Name
== TAB_FIX_LOAD_TOP_MEMORY_ADDRESS
:
200 self
._LoadFixAddress
= Record
[1]
201 elif Name
== TAB_DSC_DEFINES_RFC_LANGUAGES
:
202 if not Record
[1] or Record
[1][0] != '"' or Record
[1][-1] != '"' or len(Record
[1]) == 1:
203 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"',
204 File
=self
.MetaFile
, Line
=Record
[-1])
205 LanguageCodes
= Record
[1][1:-1]
206 if not LanguageCodes
:
207 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
208 File
=self
.MetaFile
, Line
=Record
[-1])
209 LanguageList
= GetSplitValueList(LanguageCodes
, TAB_SEMI_COLON_SPLIT
)
210 # check whether there is empty entries in the list
211 if None in LanguageList
:
212 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more empty language code is in RFC_LANGUAGES statement',
213 File
=self
.MetaFile
, Line
=Record
[-1])
214 self
._RFCLanguages
= LanguageList
215 elif Name
== TAB_DSC_DEFINES_ISO_LANGUAGES
:
216 if not Record
[1] or Record
[1][0] != '"' or Record
[1][-1] != '"' or len(Record
[1]) == 1:
217 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
218 File
=self
.MetaFile
, Line
=Record
[-1])
219 LanguageCodes
= Record
[1][1:-1]
220 if not LanguageCodes
:
221 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
222 File
=self
.MetaFile
, Line
=Record
[-1])
223 if len(LanguageCodes
)%3:
224 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, 'bad ISO639-2 format for ISO_LANGUAGES',
225 File
=self
.MetaFile
, Line
=Record
[-1])
227 for i
in range(0, len(LanguageCodes
), 3):
228 LanguageList
.append(LanguageCodes
[i
:i
+3])
229 self
._ISOLanguages
= LanguageList
230 elif Name
== TAB_DSC_DEFINES_VPD_TOOL_GUID
:
232 # try to convert GUID to a real UUID value to see whether the GUID is format
233 # for VPD_TOOL_GUID is correct.
238 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid GUID format for VPD_TOOL_GUID", File
=self
.MetaFile
)
239 self
._VpdToolGuid
= Record
[1]
240 # set _Header to non-None in order to avoid database re-querying
241 self
._Header
= 'DUMMY'
243 ## Retrieve platform name
244 def _GetPlatformName(self
):
245 if self
._PlatformName
== None:
246 if self
._Header
== None:
247 self
._GetHeaderInfo
()
248 if self
._PlatformName
== None:
249 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
250 return self
._PlatformName
252 ## Retrieve file guid
253 def _GetFileGuid(self
):
254 if self
._Guid
== None:
255 if self
._Header
== None:
256 self
._GetHeaderInfo
()
257 if self
._Guid
== None:
258 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No FILE_GUID", File
=self
.MetaFile
)
261 ## Retrieve platform version
262 def _GetVersion(self
):
263 if self
._Version
== None:
264 if self
._Header
== None:
265 self
._GetHeaderInfo
()
266 if self
._Version
== None:
270 ## Retrieve platform description file version
271 def _GetDscSpec(self
):
272 if self
._DscSpecification
== None:
273 if self
._Header
== None:
274 self
._GetHeaderInfo
()
275 if self
._DscSpecification
== None:
276 self
._DscSpecification
= ''
277 return self
._DscSpecification
279 ## Retrieve OUTPUT_DIRECTORY
280 def _GetOutpuDir(self
):
281 if self
._OutputDirectory
== None:
282 if self
._Header
== None:
283 self
._GetHeaderInfo
()
284 if self
._OutputDirectory
== None:
285 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
286 return self
._OutputDirectory
288 ## Retrieve SUPPORTED_ARCHITECTURES
289 def _GetSupArch(self
):
290 if self
._SupArchList
== None:
291 if self
._Header
== None:
292 self
._GetHeaderInfo
()
293 if self
._SupArchList
== None:
294 self
._SupArchList
= ARCH_LIST
295 return self
._SupArchList
297 ## Retrieve BUILD_TARGETS
298 def _GetBuildTarget(self
):
299 if self
._BuildTargets
== None:
300 if self
._Header
== None:
301 self
._GetHeaderInfo
()
302 if self
._BuildTargets
== None:
303 self
._BuildTargets
= ['DEBUG', 'RELEASE', 'NOOPT']
304 return self
._BuildTargets
306 ## Retrieve SKUID_IDENTIFIER
307 def _GetSkuName(self
):
308 if self
._SkuName
== None:
309 if self
._Header
== None:
310 self
._GetHeaderInfo
()
311 if self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
:
312 self
._SkuName
= 'DEFAULT'
315 ## Override SKUID_IDENTIFIER
316 def _SetSkuName(self
, Value
):
317 if Value
in self
.SkuIds
:
318 self
._SkuName
= Value
319 # Needs to re-retrieve the PCD information
322 def _GetFdfFile(self
):
323 if self
._FlashDefinition
== None:
324 if self
._Header
== None:
325 self
._GetHeaderInfo
()
326 if self
._FlashDefinition
== None:
327 self
._FlashDefinition
= ''
328 return self
._FlashDefinition
330 ## Retrieve FLASH_DEFINITION
331 def _GetBuildNumber(self
):
332 if self
._BuildNumber
== None:
333 if self
._Header
== None:
334 self
._GetHeaderInfo
()
335 if self
._BuildNumber
== None:
336 self
._BuildNumber
= ''
337 return self
._BuildNumber
339 ## Retrieve MAKEFILE_NAME
340 def _GetMakefileName(self
):
341 if self
._MakefileName
== None:
342 if self
._Header
== None:
343 self
._GetHeaderInfo
()
344 if self
._MakefileName
== None:
345 self
._MakefileName
= ''
346 return self
._MakefileName
348 ## Retrieve BsBaseAddress
349 def _GetBsBaseAddress(self
):
350 if self
._BsBaseAddress
== None:
351 if self
._Header
== None:
352 self
._GetHeaderInfo
()
353 if self
._BsBaseAddress
== None:
354 self
._BsBaseAddress
= ''
355 return self
._BsBaseAddress
357 ## Retrieve RtBaseAddress
358 def _GetRtBaseAddress(self
):
359 if self
._RtBaseAddress
== None:
360 if self
._Header
== None:
361 self
._GetHeaderInfo
()
362 if self
._RtBaseAddress
== None:
363 self
._RtBaseAddress
= ''
364 return self
._RtBaseAddress
366 ## Retrieve the top address for the load fix address
367 def _GetLoadFixAddress(self
):
368 if self
._LoadFixAddress
== None:
369 if self
._Header
== None:
370 self
._GetHeaderInfo
()
371 if self
._LoadFixAddress
== None:
372 self
._LoadFixAddress
= ''
373 return self
._LoadFixAddress
375 ## Retrieve RFCLanguage filter
376 def _GetRFCLanguages(self
):
377 if self
._RFCLanguages
== None:
378 if self
._Header
== None:
379 self
._GetHeaderInfo
()
380 if self
._RFCLanguages
== None:
381 self
._RFCLanguages
= []
382 return self
._RFCLanguages
384 ## Retrieve ISOLanguage filter
385 def _GetISOLanguages(self
):
386 if self
._ISOLanguages
== None:
387 if self
._Header
== None:
388 self
._GetHeaderInfo
()
389 if self
._ISOLanguages
== None:
390 self
._ISOLanguages
= []
391 return self
._ISOLanguages
393 ## Retrieve the GUID string for VPD tool
394 def _GetVpdToolGuid(self
):
395 if self
._VpdToolGuid
== None:
396 if self
._Header
== None:
397 self
._GetHeaderInfo
()
398 if self
._VpdToolGuid
== None:
399 self
._VpdToolGuid
= ''
400 return self
._VpdToolGuid
402 ## Retrieve [SkuIds] section information
403 def _GetSkuIds(self
):
404 if self
._SkuIds
== None:
406 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
]
407 for Record
in RecordList
:
408 if Record
[0] in [None, '']:
409 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
410 File
=self
.MetaFile
, Line
=Record
[-1])
411 if Record
[1] in [None, '']:
412 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
413 File
=self
.MetaFile
, Line
=Record
[-1])
414 self
._SkuIds
[Record
[1]] = Record
[0]
415 if 'DEFAULT' not in self
._SkuIds
:
416 self
._SkuIds
['DEFAULT'] = 0
419 ## Retrieve [Components] section information
420 def _GetModules(self
):
421 if self
._Modules
!= None:
424 self
._Modules
= sdict()
425 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
426 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
427 Macros
.update(self
._Macros
)
428 for Record
in RecordList
:
429 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
433 # check the file validation
434 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
436 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
439 if ModuleFile
in self
._Modules
:
440 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
442 Module
= ModuleBuildClassObject()
443 Module
.MetaFile
= ModuleFile
445 # get module override path
446 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
448 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
450 # Check if the source override path exists
451 if not os
.path
.isdir(Module
.SourceOverridePath
):
452 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
454 #Add to GlobalData Variables
455 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
457 # get module private library instance
458 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
459 for Record
in RecordList
:
460 LibraryClass
= Record
[0]
461 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
464 # check the file validation
465 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
467 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
470 if LibraryClass
== '' or LibraryClass
== 'NULL':
471 self
._NullLibraryNumber
+= 1
472 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
473 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
474 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
475 if LibraryPath
not in self
.LibraryInstances
:
476 self
.LibraryInstances
.append(LibraryPath
)
478 # get module private PCD setting
479 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
480 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
481 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
482 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
483 TokenList
= GetSplitValueList(Setting
)
484 DefaultValue
= TokenList
[0]
485 if len(TokenList
) > 1:
486 MaxDatumSize
= TokenList
[1]
489 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
490 Pcd
= PcdClassObject(
502 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
504 # get module private build options
505 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
506 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
507 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
508 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
510 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
511 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
513 self
._Modules
[ModuleFile
] = Module
516 ## Retrieve all possible library instances used in this platform
517 def _GetLibraryInstances(self
):
518 if self
._LibraryInstances
== None:
519 self
._GetLibraryClasses
()
520 return self
._LibraryInstances
522 ## Retrieve [LibraryClasses] information
523 def _GetLibraryClasses(self
):
524 if self
._LibraryClasses
== None:
525 self
._LibraryInstances
= []
527 # tdict is a special dict kind of type, used for selecting correct
528 # library instance for given library class and module type
530 LibraryClassDict
= tdict(True, 3)
531 # track all library class names
532 LibraryClassSet
= set()
533 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
534 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
535 Macros
.update(self
._Macros
)
536 for Record
in RecordList
:
537 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
538 if LibraryClass
== '' or LibraryClass
== 'NULL':
539 self
._NullLibraryNumber
+= 1
540 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
541 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
542 LibraryClassSet
.add(LibraryClass
)
543 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
544 # check the file validation
545 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
547 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
550 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
551 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
552 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
553 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
554 if LibraryInstance
not in self
._LibraryInstances
:
555 self
._LibraryInstances
.append(LibraryInstance
)
557 # resolve the specific library instance for each class and each module type
558 self
._LibraryClasses
= tdict(True)
559 for LibraryClass
in LibraryClassSet
:
560 # try all possible module types
561 for ModuleType
in SUP_MODULE_LIST
:
562 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
563 if LibraryInstance
== None:
565 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
567 # for EDK style library instances, which are listed in different section
568 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
569 for Record
in RecordList
:
570 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
572 # check the file validation
573 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
575 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
577 if File
not in self
._LibraryInstances
:
578 self
._LibraryInstances
.append(File
)
580 # we need the module name as the library class name, so we have
581 # to parse it here. (self._Bdb[] will trigger a file parse if it
582 # hasn't been parsed)
584 Library
= self
._Bdb
[File
, self
._Arch
]
585 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
586 return self
._LibraryClasses
588 ## Retrieve all PCD settings in platform
590 if self
._Pcds
== None:
592 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
593 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
594 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
595 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
596 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
597 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
598 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
599 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
600 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
603 ## Retrieve [BuildOptions]
604 def _GetBuildOptions(self
):
605 if self
._BuildOptions
== None:
606 self
._BuildOptions
= {}
608 # Retrieve build option for EDKII style module
610 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, 'COMMON', EDKII_NAME
]
611 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
612 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDKII_NAME
] = Option
614 # Retrieve build option for EDK style module
616 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, 'COMMON', EDK_NAME
]
617 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
618 self
._BuildOptions
[ToolChainFamily
, ToolChain
, EDK_NAME
] = Option
619 return self
._BuildOptions
621 ## Retrieve non-dynamic PCD settings
623 # @param Type PCD type
625 # @retval a dict object contains settings of given PCD type
627 def _GetPcd(self
, Type
):
630 # tdict is a special dict kind of type, used for selecting correct
631 # PCD settings for certain ARCH
633 PcdDict
= tdict(True, 3)
635 # Find out all possible PCD candidates for self._Arch
636 RecordList
= self
._RawData
[Type
, self
._Arch
]
637 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
638 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
639 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
640 # Remove redundant PCD candidates
641 for PcdCName
, TokenSpaceGuid
in PcdSet
:
642 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
645 PcdValue
, DatumType
, MaxDatumSize
= AnalyzePcdData(Setting
)
646 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
649 self
._PCD
_TYPE
_STRING
_[Type
],
660 ## Retrieve dynamic PCD settings
662 # @param Type PCD type
664 # @retval a dict object contains settings of given PCD type
666 def _GetDynamicPcd(self
, Type
):
669 # tdict is a special dict kind of type, used for selecting correct
670 # PCD settings for certain ARCH and SKU
672 PcdDict
= tdict(True, 4)
674 # Find out all possible PCD candidates for self._Arch
675 RecordList
= self
._RawData
[Type
, self
._Arch
]
676 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
677 PcdList
.append((PcdCName
, TokenSpaceGuid
))
678 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
679 # Remove redundant PCD candidates, per the ARCH and SKU
680 for PcdCName
, TokenSpaceGuid
in PcdList
:
681 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
685 PcdValue
, DatumType
, MaxDatumSize
= AnalyzePcdData(Setting
)
687 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', '', PcdValue
)
688 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
691 self
._PCD
_TYPE
_STRING
_[Type
],
696 {self
.SkuName
: SkuInfo
},
702 ## Retrieve dynamic HII PCD settings
704 # @param Type PCD type
706 # @retval a dict object contains settings of given PCD type
708 def _GetDynamicHiiPcd(self
, Type
):
711 # tdict is a special dict kind of type, used for selecting correct
712 # PCD settings for certain ARCH and SKU
714 PcdDict
= tdict(True, 4)
716 RecordList
= self
._RawData
[Type
, self
._Arch
]
717 # Find out all possible PCD candidates for self._Arch
718 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
719 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
720 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
721 # Remove redundant PCD candidates, per the ARCH and SKU
722 for PcdCName
, TokenSpaceGuid
in PcdSet
:
723 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
726 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= AnalyzeHiiPcdData(Setting
)
727 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
728 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
731 self
._PCD
_TYPE
_STRING
_[Type
],
736 {self
.SkuName
: SkuInfo
},
742 ## Retrieve dynamic VPD PCD settings
744 # @param Type PCD type
746 # @retval a dict object contains settings of given PCD type
748 def _GetDynamicVpdPcd(self
, Type
):
751 # tdict is a special dict kind of type, used for selecting correct
752 # PCD settings for certain ARCH and SKU
754 PcdDict
= tdict(True, 4)
756 # Find out all possible PCD candidates for self._Arch
757 RecordList
= self
._RawData
[Type
, self
._Arch
]
758 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
759 PcdList
.append((PcdCName
, TokenSpaceGuid
))
760 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
761 # Remove redundant PCD candidates, per the ARCH and SKU
762 for PcdCName
, TokenSpaceGuid
in PcdList
:
763 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
767 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
768 # For the Integer & Boolean type, the optional data can only be InitialValue.
769 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
770 # until the DEC parser has been called.
772 VpdOffset
, MaxDatumSize
, InitialValue
= AnalyzeVpdPcdData(Setting
)
774 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', VpdOffset
, InitialValue
)
775 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
778 self
._PCD
_TYPE
_STRING
_[Type
],
783 {self
.SkuName
: SkuInfo
},
789 ## Add external modules
791 # The external modules are mostly those listed in FDF file, which don't
794 # @param FilePath The path of module description file
796 def AddModule(self
, FilePath
):
797 FilePath
= NormPath(FilePath
)
798 if FilePath
not in self
.Modules
:
799 Module
= ModuleBuildClassObject()
800 Module
.MetaFile
= FilePath
801 self
.Modules
.append(Module
)
805 # The external PCDs are mostly those listed in FDF file to specify address
806 # or offset information.
808 # @param Name Name of the PCD
809 # @param Guid Token space guid of the PCD
810 # @param Value Value of the PCD
812 def AddPcd(self
, Name
, Guid
, Value
):
813 if (Name
, Guid
) not in self
.Pcds
:
814 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, False, None)
815 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
817 Arch
= property(_GetArch
, _SetArch
)
818 Platform
= property(_GetPlatformName
)
819 PlatformName
= property(_GetPlatformName
)
820 Guid
= property(_GetFileGuid
)
821 Version
= property(_GetVersion
)
822 DscSpecification
= property(_GetDscSpec
)
823 OutputDirectory
= property(_GetOutpuDir
)
824 SupArchList
= property(_GetSupArch
)
825 BuildTargets
= property(_GetBuildTarget
)
826 SkuName
= property(_GetSkuName
, _SetSkuName
)
827 FlashDefinition
= property(_GetFdfFile
)
828 BuildNumber
= property(_GetBuildNumber
)
829 MakefileName
= property(_GetMakefileName
)
830 BsBaseAddress
= property(_GetBsBaseAddress
)
831 RtBaseAddress
= property(_GetRtBaseAddress
)
832 LoadFixAddress
= property(_GetLoadFixAddress
)
833 RFCLanguages
= property(_GetRFCLanguages
)
834 ISOLanguages
= property(_GetISOLanguages
)
835 VpdToolGuid
= property(_GetVpdToolGuid
)
836 SkuIds
= property(_GetSkuIds
)
837 Modules
= property(_GetModules
)
838 LibraryInstances
= property(_GetLibraryInstances
)
839 LibraryClasses
= property(_GetLibraryClasses
)
840 Pcds
= property(_GetPcds
)
841 BuildOptions
= property(_GetBuildOptions
)
843 ## Platform build information from DEC file
845 # This class is used to retrieve information stored in database and convert them
846 # into PackageBuildClassObject form for easier use for AutoGen.
848 class DecBuildData(PackageBuildClassObject
):
849 # dict used to convert PCD type in database to string used by build tool
850 _PCD_TYPE_STRING_
= {
851 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
852 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
853 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
854 MODEL_PCD_DYNAMIC
: "Dynamic",
855 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
856 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
857 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
858 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
859 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
860 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
861 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
864 # dict used to convert part of [Defines] to members of DecBuildData directly
869 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
870 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
871 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
872 TAB_DEC_DEFINES_PKG_UNI_FILE
: "_PkgUniFile",
876 ## Constructor of DecBuildData
878 # Initialize object of DecBuildData
880 # @param FilePath The path of package description file
881 # @param RawData The raw data of DEC file
882 # @param BuildDataBase Database used to retrieve module information
883 # @param Arch The target architecture
884 # @param Platform (not used for DecBuildData)
885 # @param Macros Macros used for replacement in DSC file
887 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Platform
='DUMMY', Macros
={}):
889 self
._PackageDir
= File
.Dir
890 self
._RawData
= RawData
891 self
._Bdb
= BuildDataBase
893 self
._Macros
= Macros
897 def __setitem__(self
, key
, value
):
898 self
.__dict
__[self
._PROPERTY
_[key
]] = value
901 def __getitem__(self
, key
):
902 return self
.__dict
__[self
._PROPERTY
_[key
]]
905 def __contains__(self
, key
):
906 return key
in self
._PROPERTY
_
908 ## Set all internal used members of DecBuildData to None
911 self
._PackageName
= None
914 self
._PkgUniFile
= None
915 self
._Protocols
= None
918 self
._Includes
= None
919 self
._LibraryClasses
= None
928 # Changing the default ARCH to another may affect all other information
929 # because all information in a platform may be ARCH-related. That's
930 # why we need to clear all internal used members, in order to cause all
931 # information to be re-retrieved.
933 # @param Value The value of ARCH
935 def _SetArch(self
, Value
):
936 if self
._Arch
== Value
:
941 ## Retrieve all information in [Defines] section
943 # (Retriving all [Defines] information in one-shot is just to save time.)
945 def _GetHeaderInfo(self
):
946 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
]
947 for Record
in RecordList
:
950 self
[Name
] = Record
[1]
951 self
._Header
= 'DUMMY'
953 ## Retrieve package name
954 def _GetPackageName(self
):
955 if self
._PackageName
== None:
956 if self
._Header
== None:
957 self
._GetHeaderInfo
()
958 if self
._PackageName
== None:
959 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
960 return self
._PackageName
962 ## Retrieve file guid
963 def _GetFileGuid(self
):
964 if self
._Guid
== None:
965 if self
._Header
== None:
966 self
._GetHeaderInfo
()
967 if self
._Guid
== None:
968 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
971 ## Retrieve package version
972 def _GetVersion(self
):
973 if self
._Version
== None:
974 if self
._Header
== None:
975 self
._GetHeaderInfo
()
976 if self
._Version
== None:
980 ## Retrieve protocol definitions (name/value pairs)
981 def _GetProtocol(self
):
982 if self
._Protocols
== None:
984 # tdict is a special kind of dict, used for selecting correct
985 # protocol defition for given ARCH
987 ProtocolDict
= tdict(True)
989 # find out all protocol definitions for specific and 'common' arch
990 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
991 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
992 if Name
not in NameList
:
993 NameList
.append(Name
)
994 ProtocolDict
[Arch
, Name
] = Guid
995 # use sdict to keep the order
996 self
._Protocols
= sdict()
997 for Name
in NameList
:
999 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1000 # will automatically turn to 'common' ARCH for trying
1002 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
1003 return self
._Protocols
1005 ## Retrieve PPI definitions (name/value pairs)
1007 if self
._Ppis
== None:
1009 # tdict is a special kind of dict, used for selecting correct
1010 # PPI defition for given ARCH
1012 PpiDict
= tdict(True)
1014 # find out all PPI definitions for specific arch and 'common' arch
1015 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
1016 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1017 if Name
not in NameList
:
1018 NameList
.append(Name
)
1019 PpiDict
[Arch
, Name
] = Guid
1020 # use sdict to keep the order
1021 self
._Ppis
= sdict()
1022 for Name
in NameList
:
1024 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1025 # will automatically turn to 'common' ARCH for trying
1027 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
1030 ## Retrieve GUID definitions (name/value pairs)
1032 if self
._Guids
== None:
1034 # tdict is a special kind of dict, used for selecting correct
1035 # GUID defition for given ARCH
1037 GuidDict
= tdict(True)
1039 # find out all protocol definitions for specific and 'common' arch
1040 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
1041 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1042 if Name
not in NameList
:
1043 NameList
.append(Name
)
1044 GuidDict
[Arch
, Name
] = Guid
1045 # use sdict to keep the order
1046 self
._Guids
= sdict()
1047 for Name
in NameList
:
1049 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1050 # will automatically turn to 'common' ARCH for trying
1052 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
1055 ## Retrieve public include paths declared in this package
1056 def _GetInclude(self
):
1057 if self
._Includes
== None:
1059 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
1060 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1061 Macros
.update(self
._Macros
)
1062 for Record
in RecordList
:
1063 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1066 ErrorCode
, ErrorInfo
= File
.Validate()
1068 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1070 # avoid duplicate include path
1071 if File
not in self
._Includes
:
1072 self
._Includes
.append(File
)
1073 return self
._Includes
1075 ## Retrieve library class declarations (not used in build at present)
1076 def _GetLibraryClass(self
):
1077 if self
._LibraryClasses
== None:
1079 # tdict is a special kind of dict, used for selecting correct
1080 # library class declaration for given ARCH
1082 LibraryClassDict
= tdict(True)
1083 LibraryClassSet
= set()
1084 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
1085 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1086 Macros
.update(self
._Macros
)
1087 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
1088 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
1089 # check the file validation
1090 ErrorCode
, ErrorInfo
= File
.Validate()
1092 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1093 LibraryClassSet
.add(LibraryClass
)
1094 LibraryClassDict
[Arch
, LibraryClass
] = File
1095 self
._LibraryClasses
= sdict()
1096 for LibraryClass
in LibraryClassSet
:
1097 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
1098 return self
._LibraryClasses
1100 ## Retrieve PCD declarations
1102 if self
._Pcds
== None:
1104 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1105 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1106 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1107 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1108 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1111 ## Retrieve PCD declarations for given type
1112 def _GetPcd(self
, Type
):
1115 # tdict is a special kind of dict, used for selecting correct
1116 # PCD declaration for given ARCH
1118 PcdDict
= tdict(True, 3)
1119 # for summarizing PCD
1121 # find out all PCDs of the 'type'
1122 RecordList
= self
._RawData
[Type
, self
._Arch
]
1123 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1124 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1125 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1127 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1129 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1130 # will automatically turn to 'common' ARCH and try again
1132 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1136 DefaultValue
, DatumType
, TokenNumber
= AnalyzePcdData(Setting
)
1138 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1141 self
._PCD
_TYPE
_STRING
_[Type
],
1153 Arch
= property(_GetArch
, _SetArch
)
1154 PackageName
= property(_GetPackageName
)
1155 Guid
= property(_GetFileGuid
)
1156 Version
= property(_GetVersion
)
1158 Protocols
= property(_GetProtocol
)
1159 Ppis
= property(_GetPpi
)
1160 Guids
= property(_GetGuid
)
1161 Includes
= property(_GetInclude
)
1162 LibraryClasses
= property(_GetLibraryClass
)
1163 Pcds
= property(_GetPcds
)
1165 ## Module build information from INF file
1167 # This class is used to retrieve information stored in database and convert them
1168 # into ModuleBuildClassObject form for easier use for AutoGen.
1170 class InfBuildData(ModuleBuildClassObject
):
1171 # dict used to convert PCD type in database to string used by build tool
1172 _PCD_TYPE_STRING_
= {
1173 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1174 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1175 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1176 MODEL_PCD_DYNAMIC
: "Dynamic",
1177 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1178 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1179 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1180 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1181 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1182 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1183 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1186 # dict used to convert part of [Defines] to members of InfBuildData directly
1191 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1192 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1193 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1197 TAB_INF_DEFINES_INF_VERSION
: "_AutoGenVersion",
1198 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1199 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1200 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1201 TAB_INF_DEFINES_DPX_SOURCE
:"_DxsFile",
1202 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1203 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1204 TAB_INF_DEFINES_VERSION
: "_Version",
1205 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1206 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1208 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1211 # dict used to convert Component type to Module type
1214 "SECURITY_CORE" : "SEC",
1215 "PEI_CORE" : "PEI_CORE",
1216 "COMBINED_PEIM_DRIVER" : "PEIM",
1217 "PIC_PEIM" : "PEIM",
1218 "RELOCATABLE_PEIM" : "PEIM",
1219 "PE32_PEIM" : "PEIM",
1220 "BS_DRIVER" : "DXE_DRIVER",
1221 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1222 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1223 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1224 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1225 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1226 # "BS_DRIVER" : "UEFI_DRIVER",
1227 "APPLICATION" : "UEFI_APPLICATION",
1231 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1232 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1233 # dict used to convert old tool name used in [nmake] section to new ones
1241 ## Constructor of DscBuildData
1243 # Initialize object of DscBuildData
1245 # @param FilePath The path of platform description file
1246 # @param RawData The raw data of DSC file
1247 # @param BuildDataBase Database used to retrieve module/package information
1248 # @param Arch The target architecture
1249 # @param Platform The name of platform employing this module
1250 # @param Macros Macros used for replacement in DSC file
1252 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Platform
='COMMON', Macros
={}):
1253 self
.MetaFile
= FilePath
1254 self
._ModuleDir
= FilePath
.Dir
1255 self
._RawData
= RawData
1256 self
._Bdb
= BuildDatabase
1258 self
._Platform
= 'COMMON'
1259 self
._Macros
= Macros
1260 self
._SourceOverridePath
= None
1261 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1262 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1266 def __setitem__(self
, key
, value
):
1267 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1270 def __getitem__(self
, key
):
1271 return self
.__dict
__[self
._PROPERTY
_[key
]]
1273 ## "in" test support
1274 def __contains__(self
, key
):
1275 return key
in self
._PROPERTY
_
1277 ## Set all internal used members of InfBuildData to None
1279 self
._Header
_ = None
1280 self
._AutoGenVersion
= None
1281 self
._BaseName
= None
1282 self
._DxsFile
= None
1283 self
._ModuleType
= None
1284 self
._ComponentType
= None
1285 self
._BuildType
= None
1287 self
._Version
= None
1288 self
._PcdIsDriver
= None
1289 self
._BinaryModule
= None
1291 self
._MakefileName
= None
1292 self
._CustomMakefile
= None
1293 self
._Specification
= None
1294 self
._LibraryClass
= None
1295 self
._ModuleEntryPointList
= None
1296 self
._ModuleUnloadImageList
= None
1297 self
._ConstructorList
= None
1298 self
._DestructorList
= None
1300 self
._Binaries
= None
1301 self
._Sources
= None
1302 self
._LibraryClasses
= None
1303 self
._Libraries
= None
1304 self
._Protocols
= None
1307 self
._Includes
= None
1308 self
._Packages
= None
1310 self
._BuildOptions
= None
1312 self
._DepexExpression
= None
1313 #self._SourceOverridePath = None
1321 # Changing the default ARCH to another may affect all other information
1322 # because all information in a platform may be ARCH-related. That's
1323 # why we need to clear all internal used members, in order to cause all
1324 # information to be re-retrieved.
1326 # @param Value The value of ARCH
1328 def _SetArch(self
, Value
):
1329 if self
._Arch
== Value
:
1334 ## Return the name of platform employing this module
1335 def _GetPlatform(self
):
1336 return self
._Platform
1338 ## Change the name of platform employing this module
1340 # Changing the default name of platform to another may affect some information
1341 # because they may be PLATFORM-related. That's why we need to clear all internal
1342 # used members, in order to cause all information to be re-retrieved.
1344 def _SetPlatform(self
, Value
):
1345 if self
._Platform
== Value
:
1347 self
._Platform
= Value
1350 ## Retrieve all information in [Defines] section
1352 # (Retriving all [Defines] information in one-shot is just to save time.)
1354 def _GetHeaderInfo(self
):
1355 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1356 for Record
in RecordList
:
1357 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1359 # items defined _PROPERTY_ don't need additional processing
1361 self
[Name
] = Record
[1]
1362 # some special items in [Defines] section need special treatment
1363 elif Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
1364 if Name
in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
1365 Name
= 'UEFI_SPECIFICATION_VERSION'
1366 if self
._Specification
== None:
1367 self
._Specification
= sdict()
1368 self
._Specification
[Name
] = GetHexVerValue(Record
[1])
1369 if self
._Specification
[Name
] == None:
1370 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1371 "'%s' format is not supported for %s" % (Record
[1], Name
),
1372 File
=self
.MetaFile
, Line
=Record
[-1])
1373 elif Name
== 'LIBRARY_CLASS':
1374 if self
._LibraryClass
== None:
1375 self
._LibraryClass
= []
1376 ValueList
= GetSplitValueList(Record
[1])
1377 LibraryClass
= ValueList
[0]
1378 if len(ValueList
) > 1:
1379 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1381 SupModuleList
= SUP_MODULE_LIST
1382 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1383 elif Name
== 'ENTRY_POINT':
1384 if self
._ModuleEntryPointList
== None:
1385 self
._ModuleEntryPointList
= []
1386 self
._ModuleEntryPointList
.append(Record
[1])
1387 elif Name
== 'UNLOAD_IMAGE':
1388 if self
._ModuleUnloadImageList
== None:
1389 self
._ModuleUnloadImageList
= []
1392 self
._ModuleUnloadImageList
.append(Record
[1])
1393 elif Name
== 'CONSTRUCTOR':
1394 if self
._ConstructorList
== None:
1395 self
._ConstructorList
= []
1398 self
._ConstructorList
.append(Record
[1])
1399 elif Name
== 'DESTRUCTOR':
1400 if self
._DestructorList
== None:
1401 self
._DestructorList
= []
1404 self
._DestructorList
.append(Record
[1])
1405 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1406 TokenList
= GetSplitValueList(Record
[1])
1407 if self
._CustomMakefile
== None:
1408 self
._CustomMakefile
= {}
1409 if len(TokenList
) < 2:
1410 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1411 self
._CustomMakefile
['GCC'] = TokenList
[0]
1413 if TokenList
[0] not in ['MSFT', 'GCC']:
1414 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1415 "No supported family [%s]" % TokenList
[0],
1416 File
=self
.MetaFile
, Line
=Record
[-1])
1417 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1419 if self
._Defs
== None:
1420 self
._Defs
= sdict()
1421 self
._Defs
[Name
] = Record
[1]
1424 # Retrieve information in sections specific to EDK.x modules
1426 if self
._AutoGenVersion
>= 0x00010005: # _AutoGenVersion may be None, which is less than anything
1427 if not self
._ModuleType
:
1428 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1429 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1430 if self
._ModuleType
not in SUP_MODULE_LIST
:
1431 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1432 for Record
in RecordList
:
1434 if Name
== "MODULE_TYPE":
1437 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1438 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self
._ModuleType
,' '.join(l
for l
in SUP_MODULE_LIST
)),
1439 File
=self
.MetaFile
, Line
=LineNo
)
1440 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (int(self
._Specification
['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
1441 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1442 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
)
1443 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1444 and 'PCI_CLASS_CODE' in self
._Defs
:
1445 self
._BuildType
= 'UEFI_OPTIONROM'
1446 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1447 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1448 self
._BuildType
= 'UEFI_HII'
1450 self
._BuildType
= self
._ModuleType
.upper()
1453 File
= PathClass(NormPath(self
._DxsFile
), self
._ModuleDir
, Arch
=self
._Arch
)
1454 # check the file validation
1455 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1457 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1458 File
=self
.MetaFile
, Line
=LineNo
)
1459 if self
.Sources
== None:
1461 self
._Sources
.append(File
)
1463 self
._BuildType
= self
._ComponentType
.upper()
1464 if not self
._ComponentType
:
1465 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1466 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1467 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1468 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1469 if self
._ComponentType
== 'LIBRARY':
1470 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1471 # make use some [nmake] section macros
1472 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1473 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1474 Value
= Value
.replace('$(PROCESSOR)', self
._Arch
)
1475 Name
= Name
.replace('$(PROCESSOR)', self
._Arch
)
1476 Name
, Value
= ReplaceMacros((Name
, Value
), GlobalData
.gEdkGlobal
, True)
1477 if Name
== "IMAGE_ENTRY_POINT":
1478 if self
._ModuleEntryPointList
== None:
1479 self
._ModuleEntryPointList
= []
1480 self
._ModuleEntryPointList
.append(Value
)
1481 elif Name
== "DPX_SOURCE":
1482 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1483 Macros
.update(self
._Macros
)
1484 File
= PathClass(NormPath(Value
, Macros
), self
._ModuleDir
, Arch
=self
._Arch
)
1485 # check the file validation
1486 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1488 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1489 File
=self
.MetaFile
, Line
=LineNo
)
1490 if self
.Sources
== None:
1492 self
._Sources
.append(File
)
1494 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1495 if len(ToolList
) == 0 or len(ToolList
) != 1:
1497 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1498 # File=self.MetaFile, Line=LineNo)
1500 if self
._BuildOptions
== None:
1501 self
._BuildOptions
= sdict()
1503 if ToolList
[0] in self
._TOOL
_CODE
_:
1504 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1507 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1508 ToolChainFamily
= 'MSFT' # EDK.x only support MSFT tool chain
1509 #ignore not replaced macros in value
1510 ValueList
= GetSplitValueList(' ' + Value
, '/D')
1511 Dummy
= ValueList
[0]
1512 for Index
in range(1, len(ValueList
)):
1513 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1515 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1516 Value
= Dummy
.strip()
1517 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1518 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1520 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1521 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1522 # set _Header to non-None in order to avoid database re-querying
1523 self
._Header
_ = 'DUMMY'
1525 ## Retrieve file version
1526 def _GetInfVersion(self
):
1527 if self
._AutoGenVersion
== None:
1528 if self
._Header
_ == None:
1529 self
._GetHeaderInfo
()
1530 if self
._AutoGenVersion
== None:
1531 self
._AutoGenVersion
= 0x00010000
1532 return self
._AutoGenVersion
1534 ## Retrieve BASE_NAME
1535 def _GetBaseName(self
):
1536 if self
._BaseName
== None:
1537 if self
._Header
_ == None:
1538 self
._GetHeaderInfo
()
1539 if self
._BaseName
== None:
1540 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1541 return self
._BaseName
1544 def _GetDxsFile(self
):
1545 if self
._DxsFile
== None:
1546 if self
._Header
_ == None:
1547 self
._GetHeaderInfo
()
1548 if self
._DxsFile
== None:
1550 return self
._DxsFile
1552 ## Retrieve MODULE_TYPE
1553 def _GetModuleType(self
):
1554 if self
._ModuleType
== None:
1555 if self
._Header
_ == None:
1556 self
._GetHeaderInfo
()
1557 if self
._ModuleType
== None:
1558 self
._ModuleType
= 'BASE'
1559 if self
._ModuleType
not in SUP_MODULE_LIST
:
1560 self
._ModuleType
= "USER_DEFINED"
1561 return self
._ModuleType
1563 ## Retrieve COMPONENT_TYPE
1564 def _GetComponentType(self
):
1565 if self
._ComponentType
== None:
1566 if self
._Header
_ == None:
1567 self
._GetHeaderInfo
()
1568 if self
._ComponentType
== None:
1569 self
._ComponentType
= 'USER_DEFINED'
1570 return self
._ComponentType
1572 ## Retrieve "BUILD_TYPE"
1573 def _GetBuildType(self
):
1574 if self
._BuildType
== None:
1575 if self
._Header
_ == None:
1576 self
._GetHeaderInfo
()
1577 if not self
._BuildType
:
1578 self
._BuildType
= "BASE"
1579 return self
._BuildType
1581 ## Retrieve file guid
1582 def _GetFileGuid(self
):
1583 if self
._Guid
== None:
1584 if self
._Header
_ == None:
1585 self
._GetHeaderInfo
()
1586 if self
._Guid
== None:
1587 self
._Guid
= '00000000-0000-0000-000000000000'
1590 ## Retrieve module version
1591 def _GetVersion(self
):
1592 if self
._Version
== None:
1593 if self
._Header
_ == None:
1594 self
._GetHeaderInfo
()
1595 if self
._Version
== None:
1596 self
._Version
= '0.0'
1597 return self
._Version
1599 ## Retrieve PCD_IS_DRIVER
1600 def _GetPcdIsDriver(self
):
1601 if self
._PcdIsDriver
== None:
1602 if self
._Header
_ == None:
1603 self
._GetHeaderInfo
()
1604 if self
._PcdIsDriver
== None:
1605 self
._PcdIsDriver
= ''
1606 return self
._PcdIsDriver
1609 def _GetShadow(self
):
1610 if self
._Shadow
== None:
1611 if self
._Header
_ == None:
1612 self
._GetHeaderInfo
()
1613 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1616 self
._Shadow
= False
1619 ## Retrieve CUSTOM_MAKEFILE
1620 def _GetMakefile(self
):
1621 if self
._CustomMakefile
== None:
1622 if self
._Header
_ == None:
1623 self
._GetHeaderInfo
()
1624 if self
._CustomMakefile
== None:
1625 self
._CustomMakefile
= {}
1626 return self
._CustomMakefile
1628 ## Retrieve EFI_SPECIFICATION_VERSION
1630 if self
._Specification
== None:
1631 if self
._Header
_ == None:
1632 self
._GetHeaderInfo
()
1633 if self
._Specification
== None:
1634 self
._Specification
= {}
1635 return self
._Specification
1637 ## Retrieve LIBRARY_CLASS
1638 def _GetLibraryClass(self
):
1639 if self
._LibraryClass
== None:
1640 if self
._Header
_ == None:
1641 self
._GetHeaderInfo
()
1642 if self
._LibraryClass
== None:
1643 self
._LibraryClass
= []
1644 return self
._LibraryClass
1646 ## Retrieve ENTRY_POINT
1647 def _GetEntryPoint(self
):
1648 if self
._ModuleEntryPointList
== None:
1649 if self
._Header
_ == None:
1650 self
._GetHeaderInfo
()
1651 if self
._ModuleEntryPointList
== None:
1652 self
._ModuleEntryPointList
= []
1653 return self
._ModuleEntryPointList
1655 ## Retrieve UNLOAD_IMAGE
1656 def _GetUnloadImage(self
):
1657 if self
._ModuleUnloadImageList
== None:
1658 if self
._Header
_ == None:
1659 self
._GetHeaderInfo
()
1660 if self
._ModuleUnloadImageList
== None:
1661 self
._ModuleUnloadImageList
= []
1662 return self
._ModuleUnloadImageList
1664 ## Retrieve CONSTRUCTOR
1665 def _GetConstructor(self
):
1666 if self
._ConstructorList
== None:
1667 if self
._Header
_ == None:
1668 self
._GetHeaderInfo
()
1669 if self
._ConstructorList
== None:
1670 self
._ConstructorList
= []
1671 return self
._ConstructorList
1673 ## Retrieve DESTRUCTOR
1674 def _GetDestructor(self
):
1675 if self
._DestructorList
== None:
1676 if self
._Header
_ == None:
1677 self
._GetHeaderInfo
()
1678 if self
._DestructorList
== None:
1679 self
._DestructorList
= []
1680 return self
._DestructorList
1682 ## Retrieve definies other than above ones
1683 def _GetDefines(self
):
1684 if self
._Defs
== None:
1685 if self
._Header
_ == None:
1686 self
._GetHeaderInfo
()
1687 if self
._Defs
== None:
1688 self
._Defs
= sdict()
1691 ## Retrieve binary files
1692 def _GetBinaryFiles(self
):
1693 if self
._Binaries
== None:
1695 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
1696 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
, 'PROCESSOR':self
._Arch
}
1697 Macros
.update(self
._Macros
)
1698 for Record
in RecordList
:
1699 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1700 FileType
= Record
[0]
1705 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
1707 Target
= TokenList
[0]
1708 if len(TokenList
) > 1:
1709 FeatureFlag
= Record
[1:]
1711 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
1712 # check the file validation
1713 ErrorCode
, ErrorInfo
= File
.Validate()
1715 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1716 self
._Binaries
.append(File
)
1717 return self
._Binaries
1719 ## Retrieve source files
1720 def _GetSourceFiles(self
):
1721 if self
._Sources
== None:
1723 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
1724 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
, 'PROCESSOR':self
._Arch
}
1725 Macros
.update(self
._Macros
)
1726 for Record
in RecordList
:
1727 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1729 ToolChainFamily
= Record
[1]
1731 ToolCode
= Record
[3]
1732 FeatureFlag
= Record
[4]
1733 if self
._AutoGenVersion
< 0x00010005:
1734 # old module source files (EDK)
1735 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
1736 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1737 # check the file validation
1738 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
1740 if File
.Ext
.lower() == '.h':
1741 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
1742 File
=self
.MetaFile
, Line
=LineNo
)
1745 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
1747 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
1748 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1749 # check the file validation
1750 ErrorCode
, ErrorInfo
= File
.Validate()
1752 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1754 self
._Sources
.append(File
)
1755 return self
._Sources
1757 ## Retrieve library classes employed by this module
1758 def _GetLibraryClassUses(self
):
1759 if self
._LibraryClasses
== None:
1760 self
._LibraryClasses
= sdict()
1761 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
1762 for Record
in RecordList
:
1763 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1765 Instance
= Record
[1]
1766 if Instance
!= None and Instance
!= '':
1767 Instance
= NormPath(Instance
, self
._Macros
)
1768 self
._LibraryClasses
[Lib
] = Instance
1769 return self
._LibraryClasses
1771 ## Retrieve library names (for EDK.x style of modules)
1772 def _GetLibraryNames(self
):
1773 if self
._Libraries
== None:
1774 self
._Libraries
= []
1775 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
1776 for Record
in RecordList
:
1777 # in case of name with '.lib' extension, which is unusual in EDK.x inf
1778 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1779 LibraryName
= os
.path
.splitext(Record
[0])[0]
1780 if LibraryName
not in self
._Libraries
:
1781 self
._Libraries
.append(LibraryName
)
1782 return self
._Libraries
1784 ## Retrieve protocols consumed/produced by this module
1785 def _GetProtocols(self
):
1786 if self
._Protocols
== None:
1787 self
._Protocols
= sdict()
1788 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
1789 for Record
in RecordList
:
1791 Value
= ProtocolValue(CName
, self
.Packages
)
1793 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1794 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1795 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
1796 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1797 self
._Protocols
[CName
] = Value
1798 return self
._Protocols
1800 ## Retrieve PPIs consumed/produced by this module
1802 if self
._Ppis
== None:
1803 self
._Ppis
= sdict()
1804 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
1805 for Record
in RecordList
:
1807 Value
= PpiValue(CName
, self
.Packages
)
1809 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1810 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1811 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
1812 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1813 self
._Ppis
[CName
] = Value
1816 ## Retrieve GUIDs consumed/produced by this module
1817 def _GetGuids(self
):
1818 if self
._Guids
== None:
1819 self
._Guids
= sdict()
1820 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
1821 for Record
in RecordList
:
1823 Value
= GuidValue(CName
, self
.Packages
)
1825 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1826 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1827 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
1828 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1829 self
._Guids
[CName
] = Value
1832 ## Retrieve include paths necessary for this module (for EDK.x style of modules)
1833 def _GetIncludes(self
):
1834 if self
._Includes
== None:
1836 if self
._SourceOverridePath
:
1837 self
._Includes
.append(self
._SourceOverridePath
)
1838 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
1839 # [includes] section must be used only in old (EDK.x) inf file
1840 if self
.AutoGenVersion
>= 0x00010005 and len(RecordList
) > 0:
1841 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, "No [include] section allowed",
1842 File
=self
.MetaFile
, Line
=RecordList
[0][-1]-1)
1843 for Record
in RecordList
:
1844 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1845 Record
[0] = Record
[0].replace('$(PROCESSOR)', self
._Arch
)
1846 Record
[0] = ReplaceMacro(Record
[0], {'EFI_SOURCE' : GlobalData
.gEfiSource
}, False)
1847 if Record
[0].find('EDK_SOURCE') > -1:
1848 File
= NormPath(ReplaceMacro(Record
[0], {'EDK_SOURCE' : GlobalData
.gEcpSource
}, False), self
._Macros
)
1850 File
= os
.path
.join(self
._ModuleDir
, File
)
1852 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1853 File
= RealPath(os
.path
.normpath(File
))
1855 self
._Includes
.append(File
)
1857 #TRICK: let compiler to choose correct header file
1858 File
= NormPath(ReplaceMacro(Record
[0], {'EDK_SOURCE' : GlobalData
.gEdkSource
}, False), self
._Macros
)
1860 File
= os
.path
.join(self
._ModuleDir
, File
)
1862 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1863 File
= RealPath(os
.path
.normpath(File
))
1865 self
._Includes
.append(File
)
1867 File
= NormPath(Record
[0], self
._Macros
)
1869 File
= os
.path
.join(self
._ModuleDir
, File
)
1871 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1872 File
= RealPath(os
.path
.normpath(File
))
1874 self
._Includes
.append(File
)
1875 return self
._Includes
1877 ## Retrieve packages this module depends on
1878 def _GetPackages(self
):
1879 if self
._Packages
== None:
1881 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
1882 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1883 Macros
.update(self
._Macros
)
1884 for Record
in RecordList
:
1885 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
1887 # check the file validation
1888 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
1890 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1891 # parse this package now. we need it to get protocol/ppi/guid value
1892 Package
= self
._Bdb
[File
, self
._Arch
]
1893 self
._Packages
.append(Package
)
1894 return self
._Packages
1896 ## Retrieve PCDs used in this module
1898 if self
._Pcds
== None:
1899 self
._Pcds
= sdict()
1900 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1901 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1902 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1903 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1904 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1907 ## Retrieve build options specific to this module
1908 def _GetBuildOptions(self
):
1909 if self
._BuildOptions
== None:
1910 self
._BuildOptions
= sdict()
1911 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
1912 for Record
in RecordList
:
1913 ToolChainFamily
= Record
[0]
1914 ToolChain
= Record
[1]
1916 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1917 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
1919 # concatenate the option string if they're for the same tool
1920 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1921 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
1922 return self
._BuildOptions
1924 ## Retrieve depedency expression
1925 def _GetDepex(self
):
1926 if self
._Depex
== None:
1927 self
._Depex
= tdict(False, 2)
1928 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1930 # If the module has only Binaries and no Sources, then ignore [Depex]
1931 if self
.Sources
== None or self
.Sources
== []:
1932 if self
.Binaries
<> None and self
.Binaries
<> []:
1935 # PEIM and DXE drivers must have a valid [Depex] section
1936 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
1937 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
1938 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
1939 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
1940 % self
.ModuleType
, File
=self
.MetaFile
)
1943 for Record
in RecordList
:
1944 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1946 ModuleType
= Record
[4]
1947 TokenList
= Record
[0].split()
1948 if (Arch
, ModuleType
) not in Depex
:
1949 Depex
[Arch
, ModuleType
] = []
1950 DepexList
= Depex
[Arch
, ModuleType
]
1951 for Token
in TokenList
:
1952 if Token
in DEPEX_SUPPORTED_OPCODE
:
1953 DepexList
.append(Token
)
1954 elif Token
.endswith(".inf"): # module file name
1955 ModuleFile
= os
.path
.normpath(Token
)
1956 Module
= self
.BuildDatabase
[ModuleFile
]
1958 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
1959 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
1960 DepexList
.append(Module
.Guid
)
1962 # get the GUID value now
1963 Value
= ProtocolValue(Token
, self
.Packages
)
1965 Value
= PpiValue(Token
, self
.Packages
)
1967 Value
= GuidValue(Token
, self
.Packages
)
1969 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1970 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1971 "Value of [%s] is not found in" % Token
,
1972 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1973 DepexList
.append(Value
)
1974 for Arch
, ModuleType
in Depex
:
1975 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
1978 ## Retrieve depedency expression
1979 def _GetDepexExpression(self
):
1980 if self
._DepexExpression
== None:
1981 self
._DepexExpression
= tdict(False, 2)
1982 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1983 DepexExpression
= {}
1984 for Record
in RecordList
:
1985 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1987 ModuleType
= Record
[4]
1988 TokenList
= Record
[0].split()
1989 if (Arch
, ModuleType
) not in DepexExpression
:
1990 DepexExpression
[Arch
, ModuleType
] = ''
1991 for Token
in TokenList
:
1992 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
1993 for Arch
, ModuleType
in DepexExpression
:
1994 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
1995 return self
._DepexExpression
1997 ## Retrieve PCD for given type
1998 def _GetPcd(self
, Type
):
2000 PcdDict
= tdict(True, 4)
2002 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
2003 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Dummy1
, LineNo
in RecordList
:
2004 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
2005 PcdList
.append((PcdCName
, TokenSpaceGuid
))
2006 # get the guid value
2007 if TokenSpaceGuid
not in self
.Guids
:
2008 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
2010 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
2011 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
2012 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
2013 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
2014 self
.Guids
[TokenSpaceGuid
] = Value
2016 # resolve PCD type, value, datum info, etc. by getting its definition from package
2017 for PcdCName
, TokenSpaceGuid
in PcdList
:
2018 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
2021 ValueList
= AnalyzePcdData(Setting
)
2022 DefaultValue
= ValueList
[0]
2023 Pcd
= PcdClassObject(
2033 self
.Guids
[TokenSpaceGuid
]
2036 # get necessary info from package declaring this PCD
2037 for Package
in self
.Packages
:
2039 # 'dynamic' in INF means its type is determined by platform;
2040 # if platform doesn't give its type, use 'lowest' one in the
2041 # following order, if any
2043 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
2045 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
2046 if Type
== MODEL_PCD_DYNAMIC
:
2048 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
2049 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
2055 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
2056 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
2058 Pcd
.TokenValue
= PcdInPackage
.TokenValue
2061 # Check whether the token value exist or not.
2063 if Pcd
.TokenValue
== None or Pcd
.TokenValue
== "":
2067 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid
, PcdCName
, str(Package
)),
2068 File
=self
.MetaFile
, Line
=LineNo
,
2072 # Check hexadecimal token value length and format.
2074 ReIsValidPcdTokenValue
= re
.compile(r
"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re
.DOTALL
)
2075 if Pcd
.TokenValue
.startswith("0x") or Pcd
.TokenValue
.startswith("0X"):
2076 if ReIsValidPcdTokenValue
.match(Pcd
.TokenValue
) == None:
2080 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd
.TokenValue
, TokenSpaceGuid
, PcdCName
, str(Package
)),
2081 File
=self
.MetaFile
, Line
=LineNo
,
2086 # Check decimal token value length and format.
2090 TokenValueInt
= int (Pcd
.TokenValue
, 10)
2091 if (TokenValueInt
< 0 or TokenValueInt
> 4294967295):
2095 "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
)),
2096 File
=self
.MetaFile
, Line
=LineNo
,
2103 "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
)),
2104 File
=self
.MetaFile
, Line
=LineNo
,
2108 Pcd
.DatumType
= PcdInPackage
.DatumType
2109 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
2110 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
2111 if Pcd
.DefaultValue
in [None, '']:
2112 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
2118 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
2119 File
=self
.MetaFile
, Line
=LineNo
,
2120 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
2122 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
2126 Arch
= property(_GetArch
, _SetArch
)
2127 Platform
= property(_GetPlatform
, _SetPlatform
)
2129 AutoGenVersion
= property(_GetInfVersion
)
2130 BaseName
= property(_GetBaseName
)
2131 ModuleType
= property(_GetModuleType
)
2132 ComponentType
= property(_GetComponentType
)
2133 BuildType
= property(_GetBuildType
)
2134 Guid
= property(_GetFileGuid
)
2135 Version
= property(_GetVersion
)
2136 PcdIsDriver
= property(_GetPcdIsDriver
)
2137 Shadow
= property(_GetShadow
)
2138 CustomMakefile
= property(_GetMakefile
)
2139 Specification
= property(_GetSpec
)
2140 LibraryClass
= property(_GetLibraryClass
)
2141 ModuleEntryPointList
= property(_GetEntryPoint
)
2142 ModuleUnloadImageList
= property(_GetUnloadImage
)
2143 ConstructorList
= property(_GetConstructor
)
2144 DestructorList
= property(_GetDestructor
)
2145 Defines
= property(_GetDefines
)
2146 DxsFile
= property(_GetDxsFile
)
2148 Binaries
= property(_GetBinaryFiles
)
2149 Sources
= property(_GetSourceFiles
)
2150 LibraryClasses
= property(_GetLibraryClassUses
)
2151 Libraries
= property(_GetLibraryNames
)
2152 Protocols
= property(_GetProtocols
)
2153 Ppis
= property(_GetPpis
)
2154 Guids
= property(_GetGuids
)
2155 Includes
= property(_GetIncludes
)
2156 Packages
= property(_GetPackages
)
2157 Pcds
= property(_GetPcds
)
2158 BuildOptions
= property(_GetBuildOptions
)
2159 Depex
= property(_GetDepex
)
2160 DepexExpression
= property(_GetDepexExpression
)
2164 # This class defined the build database for all modules, packages and platform.
2165 # It will call corresponding parser for the given file if it cannot find it in
2168 # @param DbPath Path of database file
2169 # @param GlobalMacros Global macros used for replacement during file parsing
2170 # @prarm RenewDb=False Create new database file if it's already there
2172 class WorkspaceDatabase(object):
2175 MODEL_FILE_INF
: InfParser
,
2176 MODEL_FILE_DEC
: DecParser
,
2177 MODEL_FILE_DSC
: DscParser
,
2178 MODEL_FILE_FDF
: None, #FdfParser,
2179 MODEL_FILE_CIF
: None
2184 MODEL_FILE_INF
: ModuleTable
,
2185 MODEL_FILE_DEC
: PackageTable
,
2186 MODEL_FILE_DSC
: PlatformTable
,
2189 # default database file path
2190 _DB_PATH_
= "Conf/.cache/build.db"
2193 # internal class used for call corresponding file parser and caching the result
2194 # to avoid unnecessary re-parsing
2196 class BuildObjectFactory(object):
2198 ".inf" : MODEL_FILE_INF
,
2199 ".dec" : MODEL_FILE_DEC
,
2200 ".dsc" : MODEL_FILE_DSC
,
2201 ".fdf" : MODEL_FILE_FDF
,
2204 # convert to xxxBuildData object
2206 MODEL_FILE_INF
: InfBuildData
,
2207 MODEL_FILE_DEC
: DecBuildData
,
2208 MODEL_FILE_DSC
: DscBuildData
,
2209 MODEL_FILE_FDF
: None #FlashDefTable,
2212 _CACHE_
= {} # (FilePath, Arch) : <object>
2215 def __init__(self
, WorkspaceDb
):
2216 self
.WorkspaceDb
= WorkspaceDb
2218 # key = (FilePath, Arch='COMMON')
2219 def __contains__(self
, Key
):
2224 return (FilePath
, Arch
) in self
._CACHE
_
2226 # key = (FilePath, Arch='COMMON')
2227 def __getitem__(self
, Key
):
2236 # if it's generated before, just return the cached one
2237 Key
= (FilePath
, Arch
)
2238 if Key
in self
._CACHE
_:
2239 return self
._CACHE
_[Key
]
2242 Ext
= FilePath
.Ext
.lower()
2243 if Ext
not in self
._FILE
_TYPE
_:
2245 FileType
= self
._FILE
_TYPE
_[Ext
]
2246 if FileType
not in self
._GENERATOR
_:
2249 # get table for current file
2250 MetaFile
= self
.WorkspaceDb
[FilePath
, FileType
, self
.WorkspaceDb
._GlobalMacros
]
2251 BuildObject
= self
._GENERATOR
_[FileType
](
2257 self
.WorkspaceDb
._GlobalMacros
,
2259 self
._CACHE
_[Key
] = BuildObject
2262 # placeholder for file format conversion
2263 class TransformObjectFactory
:
2264 def __init__(self
, WorkspaceDb
):
2265 self
.WorkspaceDb
= WorkspaceDb
2267 # key = FilePath, Arch
2268 def __getitem__(self
, Key
):
2271 ## Constructor of WorkspaceDatabase
2273 # @param DbPath Path of database file
2274 # @param GlobalMacros Global macros used for replacement during file parsing
2275 # @prarm RenewDb=False Create new database file if it's already there
2277 def __init__(self
, DbPath
, GlobalMacros
={}, RenewDb
=False):
2278 self
._DbClosedFlag
= False
2279 self
._GlobalMacros
= GlobalMacros
2281 if DbPath
== None or DbPath
== '':
2282 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2284 # don't create necessary path for db in memory
2285 if DbPath
!= ':memory:':
2286 DbDir
= os
.path
.split(DbPath
)[0]
2287 if not os
.path
.exists(DbDir
):
2290 # remove db file in case inconsistency between db and file in file system
2291 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2294 # create db with optimized parameters
2295 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2296 self
.Conn
.execute("PRAGMA synchronous=OFF")
2297 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2298 self
.Conn
.execute("PRAGMA count_changes=OFF")
2299 self
.Conn
.execute("PRAGMA cache_size=8192")
2300 #self.Conn.execute("PRAGMA page_size=8192")
2302 # to avoid non-ascii character conversion issue
2303 self
.Conn
.text_factory
= str
2304 self
.Cur
= self
.Conn
.cursor()
2306 # create table for internal uses
2307 self
.TblDataModel
= TableDataModel(self
.Cur
)
2308 self
.TblFile
= TableFile(self
.Cur
)
2310 # conversion object for build or file format conversion purpose
2311 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2312 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2314 ## Check whether workspace database need to be renew.
2315 # The renew reason maybe:
2316 # 1) If user force to renew;
2317 # 2) If user do not force renew, and
2318 # a) If the time of last modified python source is newer than database file;
2319 # b) If the time of last modified frozen executable file is newer than database file;
2321 # @param force User force renew database
2322 # @param DbPath The absolute path of workspace database file
2324 # @return Bool value for whether need renew workspace databse
2326 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2327 DbDir
= os
.path
.split(DbPath
)[0]
2328 MacroFilePath
= os
.path
.normpath(os
.path
.join(DbDir
, "build.mac"))
2330 if os
.path
.exists(MacroFilePath
) and os
.path
.isfile(MacroFilePath
):
2333 f
= open(MacroFilePath
,'r')
2334 LastMacros
= pickle
.load(f
)
2341 if LastMacros
!= None and type(LastMacros
) is DictType
:
2342 if LastMacros
== self
._GlobalMacros
:
2344 for Macro
in LastMacros
.keys():
2345 if not (Macro
in self
._GlobalMacros
and LastMacros
[Macro
] == self
._GlobalMacros
[Macro
]):
2350 # save command line macros to file
2352 f
= open(MacroFilePath
,'w')
2353 pickle
.dump(self
._GlobalMacros
, f
, 2)
2362 # if database does not exist, we need do nothing
2363 if not os
.path
.exists(DbPath
): return False
2365 # if user force to renew database, then not check whether database is out of date
2366 if force
: return True
2369 # Check the time of last modified source file or build.exe
2370 # if is newer than time of database, then database need to be re-created.
2372 timeOfToolModified
= 0
2373 if hasattr(sys
, "frozen"):
2374 exePath
= os
.path
.abspath(sys
.executable
)
2375 timeOfToolModified
= os
.stat(exePath
).st_mtime
2377 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2378 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2379 if rootPath
== "" or rootPath
== None:
2380 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2381 determine whether database file is out of date!\n")
2383 # walk the root path of source or build's binary to get the time last modified.
2385 for root
, dirs
, files
in os
.walk (rootPath
):
2387 # bypass source control folder
2388 if dir.lower() in [".svn", "_svn", "cvs"]:
2392 ext
= os
.path
.splitext(file)[1]
2393 if ext
.lower() == ".py": # only check .py files
2394 fd
= os
.stat(os
.path
.join(root
, file))
2395 if timeOfToolModified
< fd
.st_mtime
:
2396 timeOfToolModified
= fd
.st_mtime
2397 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2398 EdkLogger
.verbose("\nWorkspace database is out of data!")
2403 ## Initialize build database
2404 def InitDatabase(self
):
2405 EdkLogger
.verbose("\nInitialize build database started ...")
2410 self
.TblDataModel
.Create(False)
2411 self
.TblFile
.Create(False)
2414 # Initialize table DataModel
2416 self
.TblDataModel
.InitTable()
2417 EdkLogger
.verbose("Initialize build database ... DONE!")
2421 # @param Table: The instance of the table to be queried
2423 def QueryTable(self
, Table
):
2426 ## Close entire database
2429 # Close the connection and cursor
2432 if not self
._DbClosedFlag
:
2436 self
._DbClosedFlag
= True
2438 ## Get unique file ID for the gvien file
2439 def GetFileId(self
, FilePath
):
2440 return self
.TblFile
.GetFileId(FilePath
)
2442 ## Get file type value for the gvien file ID
2443 def GetFileType(self
, FileId
):
2444 return self
.TblFile
.GetFileType(FileId
)
2446 ## Get time stamp stored in file table
2447 def GetTimeStamp(self
, FileId
):
2448 return self
.TblFile
.GetFileTimeStamp(FileId
)
2450 ## Update time stamp in file table
2451 def SetTimeStamp(self
, FileId
, TimeStamp
):
2452 return self
.TblFile
.SetFileTimeStamp(FileId
, TimeStamp
)
2454 ## Check if a table integrity flag exists or not
2455 def CheckIntegrity(self
, TableName
):
2457 Result
= self
.Cur
.execute("select min(ID) from %s" % (TableName
)).fetchall()
2458 if Result
[0][0] != -1:
2461 # Check whether the meta data file has external dependency by comparing the time stamp
2463 Sql
= "select Value1, Value2 from %s where Model=%d" % (TableName
, MODEL_EXTERNAL_DEPENDENCY
)
2464 for Dependency
in self
.Cur
.execute(Sql
).fetchall():
2465 if str(os
.stat(Dependency
[0])[8]) != Dependency
[1]:
2471 ## Compose table name for given file type and file ID
2472 def GetTableName(self
, FileType
, FileId
):
2473 return "_%s_%s" % (FileType
, FileId
)
2475 ## Return a temp table containing all content of the given file
2477 # @param FileInfo The tuple containing path and type of a file
2479 def __getitem__(self
, FileInfo
):
2480 FilePath
, FileType
, Macros
= FileInfo
2481 if FileType
not in self
._FILE
_TABLE
_:
2484 # flag used to indicate if it's parsed or not
2485 FilePath
= str(FilePath
)
2487 FileId
= self
.GetFileId(FilePath
)
2489 TimeStamp
= os
.stat(FilePath
)[8]
2490 TableName
= self
.GetTableName(FileType
, FileId
)
2491 if TimeStamp
!= self
.GetTimeStamp(FileId
):
2492 # update the timestamp in database
2493 self
.SetTimeStamp(FileId
, TimeStamp
)
2495 # if the table exists and is integrity, don't parse it
2496 Parsed
= self
.CheckIntegrity(TableName
)
2498 FileId
= self
.TblFile
.InsertFile(FilePath
, FileType
)
2499 TableName
= self
.GetTableName(FileType
, FileId
)
2501 FileTable
= self
._FILE
_TABLE
_[FileType
](self
.Cur
, TableName
, FileId
)
2502 FileTable
.Create(not Parsed
)
2503 Parser
= self
._FILE
_PARSER
_[FileType
](FilePath
, FileType
, FileTable
, Macros
)
2504 # set the "Finished" flag in parser in order to avoid re-parsing (if parsed)
2505 Parser
.Finished
= Parsed
2508 ## Summarize all packages in the database
2509 def _GetPackageList(self
):
2511 for Module
in self
.ModuleList
:
2512 for Package
in Module
.Packages
:
2513 if Package
not in PackageList
:
2514 PackageList
.append(Package
)
2517 ## Summarize all platforms in the database
2518 def _GetPlatformList(self
):
2520 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2522 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2525 if Platform
!= None:
2526 PlatformList
.append(Platform
)
2529 ## Summarize all modules in the database
2530 def _GetModuleList(self
):
2532 for ModuleFile
in self
.TblFile
.GetFileList(MODEL_FILE_INF
):
2534 Module
= self
.BuildObject
[PathClass(ModuleFile
), 'COMMON']
2538 ModuleList
.append(Module
)
2541 PlatformList
= property(_GetPlatformList
)
2542 PackageList
= property(_GetPackageList
)
2543 ModuleList
= property(_GetModuleList
)
2547 # This acts like the main() function for the script, unless it is 'import'ed into another
2550 if __name__
== '__main__':