2 # This file is used to create a database used by build tool
4 # Copyright (c) 2008 - 2009, Intel Corporation
5 # All rights reserved. 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.
22 import Common
.EdkLogger
as EdkLogger
23 import Common
.GlobalData
as GlobalData
25 from Common
.String
import *
26 from Common
.DataType
import *
27 from Common
.Misc
import *
30 from CommonDataClass
.CommonClass
import SkuInfoClass
32 from MetaDataTable
import *
33 from MetaFileTable
import *
34 from MetaFileParser
import *
35 from BuildClassObject
import *
37 ## Platform build information from DSC file
39 # This class is used to retrieve information stored in database and convert them
40 # into PlatformBuildClassObject form for easier use for AutoGen.
42 class DscBuildData(PlatformBuildClassObject
):
43 # dict used to convert PCD type in database to string used by build tool
45 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
46 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
47 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
48 MODEL_PCD_DYNAMIC
: "Dynamic",
49 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
50 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
51 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
52 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
53 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
54 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
55 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
58 # dict used to convert part of [Defines] to members of DscBuildData directly
63 TAB_DSC_DEFINES_PLATFORM_NAME
: "_PlatformName",
64 TAB_DSC_DEFINES_PLATFORM_GUID
: "_Guid",
65 TAB_DSC_DEFINES_PLATFORM_VERSION
: "_Version",
66 TAB_DSC_DEFINES_DSC_SPECIFICATION
: "_DscSpecification",
67 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
68 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
69 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
70 #TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
71 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
72 TAB_DSC_DEFINES_BUILD_NUMBER
: "_BuildNumber",
73 TAB_DSC_DEFINES_MAKEFILE_NAME
: "_MakefileName",
74 TAB_DSC_DEFINES_BS_BASE_ADDRESS
: "_BsBaseAddress",
75 TAB_DSC_DEFINES_RT_BASE_ADDRESS
: "_RtBaseAddress",
78 # used to compose dummy library class name for those forced library instances
79 _NullLibraryNumber
= 0
81 ## Constructor of DscBuildData
83 # Initialize object of DscBuildData
85 # @param FilePath The path of platform description file
86 # @param RawData The raw data of DSC file
87 # @param BuildDataBase Database used to retrieve module/package information
88 # @param Arch The target architecture
89 # @param Platform (not used for DscBuildData)
90 # @param Macros Macros used for replacement in DSC file
92 def __init__(self
, FilePath
, RawData
, BuildDataBase
, Arch
='COMMON', Platform
='DUMMY', Macros
={}):
93 self
.MetaFile
= FilePath
94 self
._RawData
= RawData
95 self
._Bdb
= BuildDataBase
99 RecordList
= self
._RawData
[MODEL_META_DATA_DEFINE
, self
._Arch
]
100 for Record
in RecordList
:
101 GlobalData
.gEdkGlobal
[Record
[0]] = Record
[1]
104 def __setitem__(self
, key
, value
):
105 self
.__dict
__[self
._PROPERTY
_[key
]] = value
108 def __getitem__(self
, key
):
109 return self
.__dict
__[self
._PROPERTY
_[key
]]
112 def __contains__(self
, key
):
113 return key
in self
._PROPERTY
_
115 ## Set all internal used members of DscBuildData to None
118 self
._PlatformName
= None
121 self
._DscSpecification
= None
122 self
._OutputDirectory
= None
123 self
._SupArchList
= None
124 self
._BuildTargets
= None
126 self
._FlashDefinition
= None
127 self
._BuildNumber
= None
128 self
._MakefileName
= None
129 self
._BsBaseAddress
= None
130 self
._RtBaseAddress
= None
133 self
._LibraryInstances
= None
134 self
._LibraryClasses
= None
136 self
._BuildOptions
= None
144 # Changing the default ARCH to another may affect all other information
145 # because all information in a platform may be ARCH-related. That's
146 # why we need to clear all internal used members, in order to cause all
147 # information to be re-retrieved.
149 # @param Value The value of ARCH
151 def _SetArch(self
, Value
):
152 if self
._Arch
== Value
:
157 ## Retrieve all information in [Defines] section
159 # (Retriving all [Defines] information in one-shot is just to save time.)
161 def _GetHeaderInfo(self
):
162 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
]
163 for Record
in RecordList
:
165 # items defined _PROPERTY_ don't need additional processing
167 self
[Name
] = Record
[1]
168 # some special items in [Defines] section need special treatment
169 elif Name
== TAB_DSC_DEFINES_OUTPUT_DIRECTORY
:
170 self
._OutputDirectory
= NormPath(Record
[1], self
._Macros
)
171 if ' ' in self
._OutputDirectory
:
172 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
, "No space is allowed in OUTPUT_DIRECTORY",
173 File
=self
.MetaFile
, Line
=Record
[-1],
174 ExtraData
=self
._OutputDirectory
)
175 elif Name
== TAB_DSC_DEFINES_FLASH_DEFINITION
:
176 self
._FlashDefinition
= PathClass(NormPath(Record
[1], self
._Macros
), GlobalData
.gWorkspace
)
177 ErrorCode
, ErrorInfo
= self
._FlashDefinition
.Validate('.fdf')
179 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=Record
[-1],
181 elif Name
== TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES
:
182 self
._SupArchList
= GetSplitValueList(Record
[1], TAB_VALUE_SPLIT
)
183 elif Name
== TAB_DSC_DEFINES_BUILD_TARGETS
:
184 self
._BuildTargets
= GetSplitValueList(Record
[1])
185 elif Name
== TAB_DSC_DEFINES_SKUID_IDENTIFIER
:
186 if self
._SkuName
== None:
187 self
._SkuName
= Record
[1]
188 # set _Header to non-None in order to avoid database re-querying
189 self
._Header
= 'DUMMY'
191 ## Retrieve platform name
192 def _GetPlatformName(self
):
193 if self
._PlatformName
== None:
194 if self
._Header
== None:
195 self
._GetHeaderInfo
()
196 if self
._PlatformName
== None:
197 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No PLATFORM_NAME", File
=self
.MetaFile
)
198 return self
._PlatformName
200 ## Retrieve file guid
201 def _GetFileGuid(self
):
202 if self
._Guid
== None:
203 if self
._Header
== None:
204 self
._GetHeaderInfo
()
205 if self
._Guid
== None:
206 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No FILE_GUID", File
=self
.MetaFile
)
209 ## Retrieve platform version
210 def _GetVersion(self
):
211 if self
._Version
== None:
212 if self
._Header
== None:
213 self
._GetHeaderInfo
()
214 if self
._Version
== None:
218 ## Retrieve platform description file version
219 def _GetDscSpec(self
):
220 if self
._DscSpecification
== None:
221 if self
._Header
== None:
222 self
._GetHeaderInfo
()
223 if self
._DscSpecification
== None:
224 self
._DscSpecification
= ''
225 return self
._DscSpecification
227 ## Retrieve OUTPUT_DIRECTORY
228 def _GetOutpuDir(self
):
229 if self
._OutputDirectory
== None:
230 if self
._Header
== None:
231 self
._GetHeaderInfo
()
232 if self
._OutputDirectory
== None:
233 self
._OutputDirectory
= os
.path
.join("Build", self
._PlatformName
)
234 return self
._OutputDirectory
236 ## Retrieve SUPPORTED_ARCHITECTURES
237 def _GetSupArch(self
):
238 if self
._SupArchList
== None:
239 if self
._Header
== None:
240 self
._GetHeaderInfo
()
241 if self
._SupArchList
== None:
242 self
._SupArchList
= ARCH_LIST
243 return self
._SupArchList
245 ## Retrieve BUILD_TARGETS
246 def _GetBuildTarget(self
):
247 if self
._BuildTargets
== None:
248 if self
._Header
== None:
249 self
._GetHeaderInfo
()
250 if self
._BuildTargets
== None:
251 self
._BuildTargets
= ['DEBUG', 'RELEASE']
252 return self
._BuildTargets
254 ## Retrieve SKUID_IDENTIFIER
255 def _GetSkuName(self
):
256 if self
._SkuName
== None:
257 if self
._Header
== None:
258 self
._GetHeaderInfo
()
259 if self
._SkuName
== None or self
._SkuName
not in self
.SkuIds
:
260 self
._SkuName
= 'DEFAULT'
263 ## Override SKUID_IDENTIFIER
264 def _SetSkuName(self
, Value
):
265 if Value
in self
.SkuIds
:
266 self
._SkuName
= Value
268 def _GetFdfFile(self
):
269 if self
._FlashDefinition
== None:
270 if self
._Header
== None:
271 self
._GetHeaderInfo
()
272 if self
._FlashDefinition
== None:
273 self
._FlashDefinition
= ''
274 return self
._FlashDefinition
276 ## Retrieve FLASH_DEFINITION
277 def _GetBuildNumber(self
):
278 if self
._BuildNumber
== None:
279 if self
._Header
== None:
280 self
._GetHeaderInfo
()
281 if self
._BuildNumber
== None:
282 self
._BuildNumber
= ''
283 return self
._BuildNumber
285 ## Retrieve MAKEFILE_NAME
286 def _GetMakefileName(self
):
287 if self
._MakefileName
== None:
288 if self
._Header
== None:
289 self
._GetHeaderInfo
()
290 if self
._MakefileName
== None:
291 self
._MakefileName
= ''
292 return self
._MakefileName
294 ## Retrieve BsBaseAddress
295 def _GetBsBaseAddress(self
):
296 if self
._BsBaseAddress
== None:
297 if self
._Header
== None:
298 self
._GetHeaderInfo
()
299 if self
._BsBaseAddress
== None:
300 self
._BsBaseAddress
= ''
301 return self
._BsBaseAddress
303 ## Retrieve RtBaseAddress
304 def _GetRtBaseAddress(self
):
305 if self
._RtBaseAddress
== None:
306 if self
._Header
== None:
307 self
._GetHeaderInfo
()
308 if self
._RtBaseAddress
== None:
309 self
._RtBaseAddress
= ''
310 return self
._RtBaseAddress
312 ## Retrieve [SkuIds] section information
313 def _GetSkuIds(self
):
314 if self
._SkuIds
== None:
316 RecordList
= self
._RawData
[MODEL_EFI_SKU_ID
]
317 for Record
in RecordList
:
318 if Record
[0] in [None, '']:
319 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID number',
320 File
=self
.MetaFile
, Line
=Record
[-1])
321 if Record
[1] in [None, '']:
322 EdkLogger
.error('build', FORMAT_INVALID
, 'No Sku ID name',
323 File
=self
.MetaFile
, Line
=Record
[-1])
324 self
._SkuIds
[Record
[1]] = Record
[0]
325 if 'DEFAULT' not in self
._SkuIds
:
326 self
._SkuIds
['DEFAULT'] = 0
329 ## Retrieve [Components] section information
330 def _GetModules(self
):
331 if self
._Modules
!= None:
334 self
._Modules
= sdict()
335 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT
, self
._Arch
]
336 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
337 Macros
.update(self
._Macros
)
338 for Record
in RecordList
:
339 ModuleFile
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
343 # check the file validation
344 ErrorCode
, ErrorInfo
= ModuleFile
.Validate('.inf')
346 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
349 if ModuleFile
in self
._Modules
:
350 EdkLogger
.error('build', FILE_DUPLICATED
, File
=self
.MetaFile
, ExtraData
=str(ModuleFile
), Line
=LineNo
)
352 Module
= ModuleBuildClassObject()
353 Module
.MetaFile
= ModuleFile
355 # get module override path
356 RecordList
= self
._RawData
[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH
, self
._Arch
, None, ModuleId
]
358 Module
.SourceOverridePath
= os
.path
.join(GlobalData
.gWorkspace
, NormPath(RecordList
[0][0], Macros
))
360 # Check if the source override path exists
361 if not os
.path
.isdir(Module
.SourceOverridePath
):
362 EdkLogger
.error('build', FILE_NOT_FOUND
, Message
= 'Source override path does not exist:', File
=self
.MetaFile
, ExtraData
=Module
.SourceOverridePath
, Line
=LineNo
)
364 #Add to GlobalData Variables
365 GlobalData
.gOverrideDir
[ModuleFile
.Key
] = Module
.SourceOverridePath
367 # get module private library instance
368 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, None, ModuleId
]
369 for Record
in RecordList
:
370 LibraryClass
= Record
[0]
371 LibraryPath
= PathClass(NormPath(Record
[1], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
374 # check the file validation
375 ErrorCode
, ErrorInfo
= LibraryPath
.Validate('.inf')
377 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
380 if LibraryClass
== '' or LibraryClass
== 'NULL':
381 self
._NullLibraryNumber
+= 1
382 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
383 EdkLogger
.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile
, LibraryPath
, LibraryClass
))
384 Module
.LibraryClasses
[LibraryClass
] = LibraryPath
385 if LibraryPath
not in self
.LibraryInstances
:
386 self
.LibraryInstances
.append(LibraryPath
)
388 # get module private PCD setting
389 for Type
in [MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, \
390 MODEL_PCD_FEATURE_FLAG
, MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
391 RecordList
= self
._RawData
[Type
, self
._Arch
, None, ModuleId
]
392 for TokenSpaceGuid
, PcdCName
, Setting
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
393 TokenList
= GetSplitValueList(Setting
)
394 DefaultValue
= TokenList
[0]
395 if len(TokenList
) > 1:
396 MaxDatumSize
= TokenList
[1]
399 TypeString
= self
._PCD
_TYPE
_STRING
_[Type
]
400 Pcd
= PcdClassObject(
411 Module
.Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
413 # get module private build options
414 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, None, ModuleId
]
415 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
416 if (ToolChainFamily
, ToolChain
) not in Module
.BuildOptions
:
417 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = Option
419 OptionString
= Module
.BuildOptions
[ToolChainFamily
, ToolChain
]
420 Module
.BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
422 self
._Modules
[ModuleFile
] = Module
425 ## Retrieve all possible library instances used in this platform
426 def _GetLibraryInstances(self
):
427 if self
._LibraryInstances
== None:
428 self
._GetLibraryClasses
()
429 return self
._LibraryInstances
431 ## Retrieve [LibraryClasses] information
432 def _GetLibraryClasses(self
):
433 if self
._LibraryClasses
== None:
434 self
._LibraryInstances
= []
436 # tdict is a special dict kind of type, used for selecting correct
437 # library instance for given library class and module type
439 LibraryClassDict
= tdict(True, 3)
440 # track all library class names
441 LibraryClassSet
= set()
442 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
443 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
444 Macros
.update(self
._Macros
)
445 for Record
in RecordList
:
446 LibraryClass
, LibraryInstance
, Dummy
, Arch
, ModuleType
, Dummy
, LineNo
= Record
447 if LibraryClass
== '' or LibraryClass
== 'NULL':
448 self
._NullLibraryNumber
+= 1
449 LibraryClass
= 'NULL%d' % self
._NullLibraryNumber
450 EdkLogger
.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch
, LibraryInstance
, LibraryClass
))
451 LibraryClassSet
.add(LibraryClass
)
452 LibraryInstance
= PathClass(NormPath(LibraryInstance
, Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
453 # check the file validation
454 ErrorCode
, ErrorInfo
= LibraryInstance
.Validate('.inf')
456 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
459 if ModuleType
!= 'COMMON' and ModuleType
not in SUP_MODULE_LIST
:
460 EdkLogger
.error('build', OPTION_UNKNOWN
, "Unknown module type [%s]" % ModuleType
,
461 File
=self
.MetaFile
, ExtraData
=LibraryInstance
, Line
=LineNo
)
462 LibraryClassDict
[Arch
, ModuleType
, LibraryClass
] = LibraryInstance
463 if LibraryInstance
not in self
._LibraryInstances
:
464 self
._LibraryInstances
.append(LibraryInstance
)
466 # resolve the specific library instance for each class and each module type
467 self
._LibraryClasses
= tdict(True)
468 for LibraryClass
in LibraryClassSet
:
469 # try all possible module types
470 for ModuleType
in SUP_MODULE_LIST
:
471 LibraryInstance
= LibraryClassDict
[self
._Arch
, ModuleType
, LibraryClass
]
472 if LibraryInstance
== None:
474 self
._LibraryClasses
[LibraryClass
, ModuleType
] = LibraryInstance
476 # for R8 style library instances, which are listed in different section
477 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
]
478 for Record
in RecordList
:
479 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
481 # check the file validation
482 ErrorCode
, ErrorInfo
= File
.Validate('.inf')
484 EdkLogger
.error('build', ErrorCode
, File
=self
.MetaFile
, Line
=LineNo
,
486 if File
not in self
._LibraryInstances
:
487 self
._LibraryInstances
.append(File
)
489 # we need the module name as the library class name, so we have
490 # to parse it here. (self._Bdb[] will trigger a file parse if it
491 # hasn't been parsed)
493 Library
= self
._Bdb
[File
, self
._Arch
]
494 self
._LibraryClasses
[Library
.BaseName
, ':dummy:'] = Library
495 return self
._LibraryClasses
497 ## Retrieve all PCD settings in platform
499 if self
._Pcds
== None:
501 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
502 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
503 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
504 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_DEFAULT
))
505 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_HII
))
506 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_VPD
))
507 self
._Pcds
.update(self
._GetDynamicPcd
(MODEL_PCD_DYNAMIC_EX_DEFAULT
))
508 self
._Pcds
.update(self
._GetDynamicHiiPcd
(MODEL_PCD_DYNAMIC_EX_HII
))
509 self
._Pcds
.update(self
._GetDynamicVpdPcd
(MODEL_PCD_DYNAMIC_EX_VPD
))
512 ## Retrieve [BuildOptions]
513 def _GetBuildOptions(self
):
514 if self
._BuildOptions
== None:
515 self
._BuildOptions
= {}
516 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
]
517 for ToolChainFamily
, ToolChain
, Option
, Dummy1
, Dummy2
, Dummy3
, Dummy4
in RecordList
:
518 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
519 return self
._BuildOptions
521 ## Retrieve non-dynamic PCD settings
523 # @param Type PCD type
525 # @retval a dict object contains settings of given PCD type
527 def _GetPcd(self
, Type
):
530 # tdict is a special dict kind of type, used for selecting correct
531 # PCD settings for certain ARCH
533 PcdDict
= tdict(True, 3)
535 # Find out all possible PCD candidates for self._Arch
536 RecordList
= self
._RawData
[Type
, self
._Arch
]
537 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
538 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
539 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
540 # Remove redundant PCD candidates
541 for PcdCName
, TokenSpaceGuid
in PcdSet
:
542 ValueList
= ['', '', '']
543 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
546 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
547 ValueList
[0:len(TokenList
)] = TokenList
548 PcdValue
, DatumType
, MaxDatumSize
= ValueList
549 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
552 self
._PCD
_TYPE
_STRING
_[Type
],
562 ## Retrieve dynamic PCD settings
564 # @param Type PCD type
566 # @retval a dict object contains settings of given PCD type
568 def _GetDynamicPcd(self
, Type
):
571 # tdict is a special dict kind of type, used for selecting correct
572 # PCD settings for certain ARCH and SKU
574 PcdDict
= tdict(True, 4)
576 # Find out all possible PCD candidates for self._Arch
577 RecordList
= self
._RawData
[Type
, self
._Arch
]
578 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
579 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
580 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
581 # Remove redundant PCD candidates, per the ARCH and SKU
582 for PcdCName
, TokenSpaceGuid
in PcdSet
:
583 ValueList
= ['', '', '']
584 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
587 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
588 ValueList
[0:len(TokenList
)] = TokenList
589 PcdValue
, DatumType
, MaxDatumSize
= ValueList
591 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', '', PcdValue
)
592 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
595 self
._PCD
_TYPE
_STRING
_[Type
],
600 {self
.SkuName
: SkuInfo
},
605 ## Retrieve dynamic HII PCD settings
607 # @param Type PCD type
609 # @retval a dict object contains settings of given PCD type
611 def _GetDynamicHiiPcd(self
, Type
):
614 # tdict is a special dict kind of type, used for selecting correct
615 # PCD settings for certain ARCH and SKU
617 PcdDict
= tdict(True, 4)
619 RecordList
= self
._RawData
[Type
, self
._Arch
]
620 # Find out all possible PCD candidates for self._Arch
621 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
622 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
623 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
624 # Remove redundant PCD candidates, per the ARCH and SKU
625 for PcdCName
, TokenSpaceGuid
in PcdSet
:
626 ValueList
= ['', '', '', '']
627 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
630 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
631 ValueList
[0:len(TokenList
)] = TokenList
632 VariableName
, VariableGuid
, VariableOffset
, DefaultValue
= ValueList
633 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], VariableName
, VariableGuid
, VariableOffset
, DefaultValue
)
634 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
637 self
._PCD
_TYPE
_STRING
_[Type
],
642 {self
.SkuName
: SkuInfo
},
647 ## Retrieve dynamic VPD PCD settings
649 # @param Type PCD type
651 # @retval a dict object contains settings of given PCD type
653 def _GetDynamicVpdPcd(self
, Type
):
656 # tdict is a special dict kind of type, used for selecting correct
657 # PCD settings for certain ARCH and SKU
659 PcdDict
= tdict(True, 4)
661 # Find out all possible PCD candidates for self._Arch
662 RecordList
= self
._RawData
[Type
, self
._Arch
]
663 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, SkuName
, Dummy3
, Dummy4
in RecordList
:
664 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
665 PcdDict
[Arch
, SkuName
, PcdCName
, TokenSpaceGuid
] = Setting
666 # Remove redundant PCD candidates, per the ARCH and SKU
667 for PcdCName
, TokenSpaceGuid
in PcdSet
:
669 Setting
= PcdDict
[self
._Arch
, self
.SkuName
, PcdCName
, TokenSpaceGuid
]
672 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
673 ValueList
[0:len(TokenList
)] = TokenList
674 VpdOffset
, MaxDatumSize
= ValueList
676 SkuInfo
= SkuInfoClass(self
.SkuName
, self
.SkuIds
[self
.SkuName
], '', '', '', '', VpdOffset
)
677 Pcds
[PcdCName
, TokenSpaceGuid
] = PcdClassObject(
680 self
._PCD
_TYPE
_STRING
_[Type
],
685 {self
.SkuName
: SkuInfo
},
690 ## Add external modules
692 # The external modules are mostly those listed in FDF file, which don't
695 # @param FilePath The path of module description file
697 def AddModule(self
, FilePath
):
698 FilePath
= NormPath(FilePath
)
699 if FilePath
not in self
.Modules
:
700 Module
= ModuleBuildClassObject()
701 Module
.MetaFile
= FilePath
702 self
.Modules
.append(Module
)
706 # The external PCDs are mostly those listed in FDF file to specify address
707 # or offset information.
709 # @param Name Name of the PCD
710 # @param Guid Token space guid of the PCD
711 # @param Value Value of the PCD
713 def AddPcd(self
, Name
, Guid
, Value
):
714 if (Name
, Guid
) not in self
.Pcds
:
715 self
.Pcds
[Name
, Guid
] = PcdClassObject(Name
, Guid
, '', '', '', '', '', {}, None)
716 self
.Pcds
[Name
, Guid
].DefaultValue
= Value
718 Arch
= property(_GetArch
, _SetArch
)
719 Platform
= property(_GetPlatformName
)
720 PlatformName
= property(_GetPlatformName
)
721 Guid
= property(_GetFileGuid
)
722 Version
= property(_GetVersion
)
723 DscSpecification
= property(_GetDscSpec
)
724 OutputDirectory
= property(_GetOutpuDir
)
725 SupArchList
= property(_GetSupArch
)
726 BuildTargets
= property(_GetBuildTarget
)
727 SkuName
= property(_GetSkuName
, _SetSkuName
)
728 FlashDefinition
= property(_GetFdfFile
)
729 BuildNumber
= property(_GetBuildNumber
)
730 MakefileName
= property(_GetMakefileName
)
731 BsBaseAddress
= property(_GetBsBaseAddress
)
732 RtBaseAddress
= property(_GetRtBaseAddress
)
734 SkuIds
= property(_GetSkuIds
)
735 Modules
= property(_GetModules
)
736 LibraryInstances
= property(_GetLibraryInstances
)
737 LibraryClasses
= property(_GetLibraryClasses
)
738 Pcds
= property(_GetPcds
)
739 BuildOptions
= property(_GetBuildOptions
)
741 ## Platform build information from DSC file
743 # This class is used to retrieve information stored in database and convert them
744 # into PackageBuildClassObject form for easier use for AutoGen.
746 class DecBuildData(PackageBuildClassObject
):
747 # dict used to convert PCD type in database to string used by build tool
748 _PCD_TYPE_STRING_
= {
749 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
750 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
751 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
752 MODEL_PCD_DYNAMIC
: "Dynamic",
753 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
754 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
755 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
756 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
757 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
758 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
759 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
762 # dict used to convert part of [Defines] to members of DecBuildData directly
767 TAB_DEC_DEFINES_PACKAGE_NAME
: "_PackageName",
768 TAB_DEC_DEFINES_PACKAGE_GUID
: "_Guid",
769 TAB_DEC_DEFINES_PACKAGE_VERSION
: "_Version",
773 ## Constructor of DecBuildData
775 # Initialize object of DecBuildData
777 # @param FilePath The path of package description file
778 # @param RawData The raw data of DEC file
779 # @param BuildDataBase Database used to retrieve module information
780 # @param Arch The target architecture
781 # @param Platform (not used for DecBuildData)
782 # @param Macros Macros used for replacement in DSC file
784 def __init__(self
, File
, RawData
, BuildDataBase
, Arch
='COMMON', Platform
='DUMMY', Macros
={}):
786 self
._PackageDir
= File
.Dir
787 self
._RawData
= RawData
788 self
._Bdb
= BuildDataBase
790 self
._Macros
= Macros
794 def __setitem__(self
, key
, value
):
795 self
.__dict
__[self
._PROPERTY
_[key
]] = value
798 def __getitem__(self
, key
):
799 return self
.__dict
__[self
._PROPERTY
_[key
]]
802 def __contains__(self
, key
):
803 return key
in self
._PROPERTY
_
805 ## Set all internal used members of DecBuildData to None
808 self
._PackageName
= None
811 self
._Protocols
= None
814 self
._Includes
= None
815 self
._LibraryClasses
= None
824 # Changing the default ARCH to another may affect all other information
825 # because all information in a platform may be ARCH-related. That's
826 # why we need to clear all internal used members, in order to cause all
827 # information to be re-retrieved.
829 # @param Value The value of ARCH
831 def _SetArch(self
, Value
):
832 if self
._Arch
== Value
:
837 ## Retrieve all information in [Defines] section
839 # (Retriving all [Defines] information in one-shot is just to save time.)
841 def _GetHeaderInfo(self
):
842 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
]
843 for Record
in RecordList
:
846 self
[Name
] = Record
[1]
847 self
._Header
= 'DUMMY'
849 ## Retrieve package name
850 def _GetPackageName(self
):
851 if self
._PackageName
== None:
852 if self
._Header
== None:
853 self
._GetHeaderInfo
()
854 if self
._PackageName
== None:
855 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_NAME", File
=self
.MetaFile
)
856 return self
._PackageName
858 ## Retrieve file guid
859 def _GetFileGuid(self
):
860 if self
._Guid
== None:
861 if self
._Header
== None:
862 self
._GetHeaderInfo
()
863 if self
._Guid
== None:
864 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "No PACKAGE_GUID", File
=self
.MetaFile
)
867 ## Retrieve package version
868 def _GetVersion(self
):
869 if self
._Version
== None:
870 if self
._Header
== None:
871 self
._GetHeaderInfo
()
872 if self
._Version
== None:
876 ## Retrieve protocol definitions (name/value pairs)
877 def _GetProtocol(self
):
878 if self
._Protocols
== None:
880 # tdict is a special kind of dict, used for selecting correct
881 # protocol defition for given ARCH
883 ProtocolDict
= tdict(True)
885 # find out all protocol definitions for specific and 'common' arch
886 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
]
887 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
888 if Name
not in NameList
:
889 NameList
.append(Name
)
890 ProtocolDict
[Arch
, Name
] = Guid
891 # use sdict to keep the order
892 self
._Protocols
= sdict()
893 for Name
in NameList
:
895 # limit the ARCH to self._Arch, if no self._Arch found, tdict
896 # will automatically turn to 'common' ARCH for trying
898 self
._Protocols
[Name
] = ProtocolDict
[self
._Arch
, Name
]
899 return self
._Protocols
901 ## Retrieve PPI definitions (name/value pairs)
903 if self
._Ppis
== None:
905 # tdict is a special kind of dict, used for selecting correct
906 # PPI defition for given ARCH
908 PpiDict
= tdict(True)
910 # find out all PPI definitions for specific arch and 'common' arch
911 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
]
912 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
913 if Name
not in NameList
:
914 NameList
.append(Name
)
915 PpiDict
[Arch
, Name
] = Guid
916 # use sdict to keep the order
918 for Name
in NameList
:
920 # limit the ARCH to self._Arch, if no self._Arch found, tdict
921 # will automatically turn to 'common' ARCH for trying
923 self
._Ppis
[Name
] = PpiDict
[self
._Arch
, Name
]
926 ## Retrieve GUID definitions (name/value pairs)
928 if self
._Guids
== None:
930 # tdict is a special kind of dict, used for selecting correct
931 # GUID defition for given ARCH
933 GuidDict
= tdict(True)
935 # find out all protocol definitions for specific and 'common' arch
936 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
]
937 for Name
, Guid
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
938 if Name
not in NameList
:
939 NameList
.append(Name
)
940 GuidDict
[Arch
, Name
] = Guid
941 # use sdict to keep the order
942 self
._Guids
= sdict()
943 for Name
in NameList
:
945 # limit the ARCH to self._Arch, if no self._Arch found, tdict
946 # will automatically turn to 'common' ARCH for trying
948 self
._Guids
[Name
] = GuidDict
[self
._Arch
, Name
]
951 ## Retrieve public include paths declared in this package
952 def _GetInclude(self
):
953 if self
._Includes
== None:
955 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
]
956 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
957 Macros
.update(self
._Macros
)
958 for Record
in RecordList
:
959 File
= PathClass(NormPath(Record
[0], Macros
), self
._PackageDir
, Arch
=self
._Arch
)
962 ErrorCode
, ErrorInfo
= File
.Validate()
964 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
966 # avoid duplicate include path
967 if File
not in self
._Includes
:
968 self
._Includes
.append(File
)
969 return self
._Includes
971 ## Retrieve library class declarations (not used in build at present)
972 def _GetLibraryClass(self
):
973 if self
._LibraryClasses
== None:
975 # tdict is a special kind of dict, used for selecting correct
976 # library class declaration for given ARCH
978 LibraryClassDict
= tdict(True)
979 LibraryClassSet
= set()
980 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
]
981 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
982 Macros
.update(self
._Macros
)
983 for LibraryClass
, File
, Dummy
, Arch
, ID
, LineNo
in RecordList
:
984 File
= PathClass(NormPath(File
, Macros
), self
._PackageDir
, Arch
=self
._Arch
)
985 # check the file validation
986 ErrorCode
, ErrorInfo
= File
.Validate()
988 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
989 LibraryClassSet
.add(LibraryClass
)
990 LibraryClassDict
[Arch
, LibraryClass
] = File
991 self
._LibraryClasses
= sdict()
992 for LibraryClass
in LibraryClassSet
:
993 self
._LibraryClasses
[LibraryClass
] = LibraryClassDict
[self
._Arch
, LibraryClass
]
994 return self
._LibraryClasses
996 ## Retrieve PCD declarations
998 if self
._Pcds
== None:
1000 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1001 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1002 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1003 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1004 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1007 ## Retrieve PCD declarations for given type
1008 def _GetPcd(self
, Type
):
1011 # tdict is a special kind of dict, used for selecting correct
1012 # PCD declaration for given ARCH
1014 PcdDict
= tdict(True, 3)
1015 # for summarizing PCD
1017 # find out all PCDs of the 'type'
1018 RecordList
= self
._RawData
[Type
, self
._Arch
]
1019 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Dummy1
, Dummy2
in RecordList
:
1020 PcdDict
[Arch
, PcdCName
, TokenSpaceGuid
] = Setting
1021 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1023 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1024 ValueList
= ['', '', '']
1026 # limit the ARCH to self._Arch, if no self._Arch found, tdict
1027 # will automatically turn to 'common' ARCH and try again
1029 Setting
= PcdDict
[self
._Arch
, PcdCName
, TokenSpaceGuid
]
1032 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
1033 ValueList
[0:len(TokenList
)] = TokenList
1034 DefaultValue
, DatumType
, TokenNumber
= ValueList
1035 Pcds
[PcdCName
, TokenSpaceGuid
, self
._PCD
_TYPE
_STRING
_[Type
]] = PcdClassObject(
1038 self
._PCD
_TYPE
_STRING
_[Type
],
1049 Arch
= property(_GetArch
, _SetArch
)
1050 PackageName
= property(_GetPackageName
)
1051 Guid
= property(_GetFileGuid
)
1052 Version
= property(_GetVersion
)
1054 Protocols
= property(_GetProtocol
)
1055 Ppis
= property(_GetPpi
)
1056 Guids
= property(_GetGuid
)
1057 Includes
= property(_GetInclude
)
1058 LibraryClasses
= property(_GetLibraryClass
)
1059 Pcds
= property(_GetPcds
)
1061 ## Module build information from INF file
1063 # This class is used to retrieve information stored in database and convert them
1064 # into ModuleBuildClassObject form for easier use for AutoGen.
1066 class InfBuildData(ModuleBuildClassObject
):
1067 # dict used to convert PCD type in database to string used by build tool
1068 _PCD_TYPE_STRING_
= {
1069 MODEL_PCD_FIXED_AT_BUILD
: "FixedAtBuild",
1070 MODEL_PCD_PATCHABLE_IN_MODULE
: "PatchableInModule",
1071 MODEL_PCD_FEATURE_FLAG
: "FeatureFlag",
1072 MODEL_PCD_DYNAMIC
: "Dynamic",
1073 MODEL_PCD_DYNAMIC_DEFAULT
: "Dynamic",
1074 MODEL_PCD_DYNAMIC_HII
: "DynamicHii",
1075 MODEL_PCD_DYNAMIC_VPD
: "DynamicVpd",
1076 MODEL_PCD_DYNAMIC_EX
: "DynamicEx",
1077 MODEL_PCD_DYNAMIC_EX_DEFAULT
: "DynamicEx",
1078 MODEL_PCD_DYNAMIC_EX_HII
: "DynamicExHii",
1079 MODEL_PCD_DYNAMIC_EX_VPD
: "DynamicExVpd",
1082 # dict used to convert part of [Defines] to members of InfBuildData directly
1087 TAB_INF_DEFINES_BASE_NAME
: "_BaseName",
1088 TAB_INF_DEFINES_FILE_GUID
: "_Guid",
1089 TAB_INF_DEFINES_MODULE_TYPE
: "_ModuleType",
1093 TAB_INF_DEFINES_INF_VERSION
: "_AutoGenVersion",
1094 TAB_INF_DEFINES_COMPONENT_TYPE
: "_ComponentType",
1095 TAB_INF_DEFINES_MAKEFILE_NAME
: "_MakefileName",
1096 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
1097 TAB_INF_DEFINES_VERSION_NUMBER
: "_Version",
1098 TAB_INF_DEFINES_VERSION_STRING
: "_Version",
1099 TAB_INF_DEFINES_VERSION
: "_Version",
1100 TAB_INF_DEFINES_PCD_IS_DRIVER
: "_PcdIsDriver",
1101 TAB_INF_DEFINES_SHADOW
: "_Shadow",
1103 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH
: "_SourceOverridePath",
1106 # dict used to convert Component type to Module type
1109 "SECURITY_CORE" : "SEC",
1110 "PEI_CORE" : "PEI_CORE",
1111 "COMBINED_PEIM_DRIVER" : "PEIM",
1112 "PIC_PEIM" : "PEIM",
1113 "RELOCATABLE_PEIM" : "PEIM",
1114 "PE32_PEIM" : "PEIM",
1115 "BS_DRIVER" : "DXE_DRIVER",
1116 "RT_DRIVER" : "DXE_RUNTIME_DRIVER",
1117 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER",
1118 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER",
1119 # "SMM_DRIVER" : "DXE_SMM_DRIVER",
1120 # "BS_DRIVER" : "DXE_SMM_DRIVER",
1121 # "BS_DRIVER" : "UEFI_DRIVER",
1122 "APPLICATION" : "UEFI_APPLICATION",
1126 # regular expression for converting XXX_FLAGS in [nmake] section to new type
1127 _NMAKE_FLAG_PATTERN_
= re
.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re
.UNICODE
)
1128 # dict used to convert old tool name used in [nmake] section to new ones
1136 ## Constructor of DscBuildData
1138 # Initialize object of DscBuildData
1140 # @param FilePath The path of platform description file
1141 # @param RawData The raw data of DSC file
1142 # @param BuildDataBase Database used to retrieve module/package information
1143 # @param Arch The target architecture
1144 # @param Platform The name of platform employing this module
1145 # @param Macros Macros used for replacement in DSC file
1147 def __init__(self
, FilePath
, RawData
, BuildDatabase
, Arch
='COMMON', Platform
='COMMON', Macros
={}):
1148 self
.MetaFile
= FilePath
1149 self
._ModuleDir
= FilePath
.Dir
1150 self
._RawData
= RawData
1151 self
._Bdb
= BuildDatabase
1153 self
._Platform
= 'COMMON'
1154 self
._Macros
= Macros
1155 self
._SourceOverridePath
= None
1156 if FilePath
.Key
in GlobalData
.gOverrideDir
:
1157 self
._SourceOverridePath
= GlobalData
.gOverrideDir
[FilePath
.Key
]
1161 def __setitem__(self
, key
, value
):
1162 self
.__dict
__[self
._PROPERTY
_[key
]] = value
1165 def __getitem__(self
, key
):
1166 return self
.__dict
__[self
._PROPERTY
_[key
]]
1168 ## "in" test support
1169 def __contains__(self
, key
):
1170 return key
in self
._PROPERTY
_
1172 ## Set all internal used members of InfBuildData to None
1174 self
._Header
_ = None
1175 self
._AutoGenVersion
= None
1176 self
._BaseName
= None
1177 self
._ModuleType
= None
1178 self
._ComponentType
= None
1179 self
._BuildType
= None
1181 self
._Version
= None
1182 self
._PcdIsDriver
= None
1183 self
._BinaryModule
= None
1185 self
._MakefileName
= None
1186 self
._CustomMakefile
= None
1187 self
._Specification
= None
1188 self
._LibraryClass
= None
1189 self
._ModuleEntryPointList
= None
1190 self
._ModuleUnloadImageList
= None
1191 self
._ConstructorList
= None
1192 self
._DestructorList
= None
1194 self
._Binaries
= None
1195 self
._Sources
= None
1196 self
._LibraryClasses
= None
1197 self
._Libraries
= None
1198 self
._Protocols
= None
1201 self
._Includes
= None
1202 self
._Packages
= None
1204 self
._BuildOptions
= None
1206 self
._DepexExpression
= None
1207 #self._SourceOverridePath = None
1215 # Changing the default ARCH to another may affect all other information
1216 # because all information in a platform may be ARCH-related. That's
1217 # why we need to clear all internal used members, in order to cause all
1218 # information to be re-retrieved.
1220 # @param Value The value of ARCH
1222 def _SetArch(self
, Value
):
1223 if self
._Arch
== Value
:
1228 ## Return the name of platform employing this module
1229 def _GetPlatform(self
):
1230 return self
._Platform
1232 ## Change the name of platform employing this module
1234 # Changing the default name of platform to another may affect some information
1235 # because they may be PLATFORM-related. That's why we need to clear all internal
1236 # used members, in order to cause all information to be re-retrieved.
1238 def _SetPlatform(self
, Value
):
1239 if self
._Platform
== Value
:
1241 self
._Platform
= Value
1244 ## Retrieve all information in [Defines] section
1246 # (Retriving all [Defines] information in one-shot is just to save time.)
1248 def _GetHeaderInfo(self
):
1249 RecordList
= self
._RawData
[MODEL_META_DATA_HEADER
, self
._Arch
, self
._Platform
]
1250 for Record
in RecordList
:
1251 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1253 # items defined _PROPERTY_ don't need additional processing
1255 self
[Name
] = Record
[1]
1256 # some special items in [Defines] section need special treatment
1257 elif Name
== 'EFI_SPECIFICATION_VERSION':
1258 if self
._Specification
== None:
1259 self
._Specification
= sdict()
1260 self
._Specification
[Name
] = Record
[1]
1261 elif Name
== 'EDK_RELEASE_VERSION':
1262 if self
._Specification
== None:
1263 self
._Specification
= sdict()
1264 self
._Specification
[Name
] = Record
[1]
1265 elif Name
== 'PI_SPECIFICATION_VERSION':
1266 if self
._Specification
== None:
1267 self
._Specification
= sdict()
1268 self
._Specification
[Name
] = Record
[1]
1269 elif Name
== 'LIBRARY_CLASS':
1270 if self
._LibraryClass
== None:
1271 self
._LibraryClass
= []
1272 ValueList
= GetSplitValueList(Record
[1])
1273 LibraryClass
= ValueList
[0]
1274 if len(ValueList
) > 1:
1275 SupModuleList
= GetSplitValueList(ValueList
[1], ' ')
1277 SupModuleList
= SUP_MODULE_LIST
1278 self
._LibraryClass
.append(LibraryClassObject(LibraryClass
, SupModuleList
))
1279 elif Name
== 'ENTRY_POINT':
1280 if self
._ModuleEntryPointList
== None:
1281 self
._ModuleEntryPointList
= []
1282 self
._ModuleEntryPointList
.append(Record
[1])
1283 elif Name
== 'UNLOAD_IMAGE':
1284 if self
._ModuleUnloadImageList
== None:
1285 self
._ModuleUnloadImageList
= []
1288 self
._ModuleUnloadImageList
.append(Record
[1])
1289 elif Name
== 'CONSTRUCTOR':
1290 if self
._ConstructorList
== None:
1291 self
._ConstructorList
= []
1294 self
._ConstructorList
.append(Record
[1])
1295 elif Name
== 'DESTRUCTOR':
1296 if self
._DestructorList
== None:
1297 self
._DestructorList
= []
1300 self
._DestructorList
.append(Record
[1])
1301 elif Name
== TAB_INF_DEFINES_CUSTOM_MAKEFILE
:
1302 TokenList
= GetSplitValueList(Record
[1])
1303 if self
._CustomMakefile
== None:
1304 self
._CustomMakefile
= {}
1305 if len(TokenList
) < 2:
1306 self
._CustomMakefile
['MSFT'] = TokenList
[0]
1307 self
._CustomMakefile
['GCC'] = TokenList
[0]
1309 if TokenList
[0] not in ['MSFT', 'GCC']:
1310 EdkLogger
.error("build", FORMAT_NOT_SUPPORTED
,
1311 "No supported family [%s]" % TokenList
[0],
1312 File
=self
.MetaFile
, Line
=Record
[-1])
1313 self
._CustomMakefile
[TokenList
[0]] = TokenList
[1]
1315 if self
._Defs
== None:
1316 self
._Defs
= sdict()
1317 self
._Defs
[Name
] = Record
[1]
1320 # Retrieve information in sections specific to R8.x modules
1322 if self
._AutoGenVersion
>= 0x00010005: # _AutoGenVersion may be None, which is less than anything
1323 if not self
._ModuleType
:
1324 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1325 "MODULE_TYPE is not given", File
=self
.MetaFile
)
1326 if (self
._Specification
== None) or (not 'PI_SPECIFICATION_VERSION' in self
._Specification
) or (self
._Specification
['PI_SPECIFICATION_VERSION'] < 0x0001000A):
1327 if self
._ModuleType
== SUP_MODULE_SMM_CORE
:
1328 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
)
1329 if self
._Defs
and 'PCI_DEVICE_ID' in self
._Defs
and 'PCI_VENDOR_ID' in self
._Defs \
1330 and 'PCI_CLASS_CODE' in self
._Defs
:
1331 self
._BuildType
= 'UEFI_OPTIONROM'
1332 elif self
._Defs
and 'UEFI_HII_RESOURCE_SECTION' in self
._Defs \
1333 and self
._Defs
['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
1334 self
._BuildType
= 'UEFI_HII'
1336 self
._BuildType
= self
._ModuleType
.upper()
1338 self
._BuildType
= self
._ComponentType
.upper()
1339 if not self
._ComponentType
:
1340 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1341 "COMPONENT_TYPE is not given", File
=self
.MetaFile
)
1342 if self
._ComponentType
in self
._MODULE
_TYPE
_:
1343 self
._ModuleType
= self
._MODULE
_TYPE
_[self
._ComponentType
]
1344 if self
._ComponentType
== 'LIBRARY':
1345 self
._LibraryClass
= [LibraryClassObject(self
._BaseName
, SUP_MODULE_LIST
)]
1346 # make use some [nmake] section macros
1347 RecordList
= self
._RawData
[MODEL_META_DATA_NMAKE
, self
._Arch
, self
._Platform
]
1348 for Name
,Value
,Dummy
,Arch
,Platform
,ID
,LineNo
in RecordList
:
1349 Value
= Value
.replace('$(PROCESSOR)', self
._Arch
)
1350 Name
= Name
.replace('$(PROCESSOR)', self
._Arch
)
1351 Name
, Value
= ReplaceMacros((Name
, Value
), GlobalData
.gEdkGlobal
, True)
1352 if Name
== "IMAGE_ENTRY_POINT":
1353 if self
._ModuleEntryPointList
== None:
1354 self
._ModuleEntryPointList
= []
1355 self
._ModuleEntryPointList
.append(Value
)
1356 elif Name
== "DPX_SOURCE":
1357 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1358 Macros
.update(self
._Macros
)
1359 File
= PathClass(NormPath(Value
, Macros
), self
._ModuleDir
, Arch
=self
._Arch
)
1360 # check the file validation
1361 ErrorCode
, ErrorInfo
= File
.Validate(".dxs", CaseSensitive
=False)
1363 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
,
1364 File
=self
.MetaFile
, Line
=LineNo
)
1365 if self
.Sources
== None:
1367 self
._Sources
.append(File
)
1369 ToolList
= self
._NMAKE
_FLAG
_PATTERN
_.findall(Name
)
1370 if len(ToolList
) == 0 or len(ToolList
) != 1:
1372 # EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name,
1373 # File=self.MetaFile, Line=LineNo)
1375 if self
._BuildOptions
== None:
1376 self
._BuildOptions
= sdict()
1378 if ToolList
[0] in self
._TOOL
_CODE
_:
1379 Tool
= self
._TOOL
_CODE
_[ToolList
[0]]
1382 ToolChain
= "*_*_*_%s_FLAGS" % Tool
1383 ToolChainFamily
= 'MSFT' # R8.x only support MSFT tool chain
1384 #ignore not replaced macros in value
1385 ValueList
= GetSplitValueList(' ' + Value
, '/D')
1386 Dummy
= ValueList
[0]
1387 for Index
in range(1, len(ValueList
)):
1388 if ValueList
[Index
][-1] == '=' or ValueList
[Index
] == '':
1390 Dummy
= Dummy
+ ' /D ' + ValueList
[Index
]
1391 Value
= Dummy
.strip()
1392 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1393 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Value
1395 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1396 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Value
1397 # set _Header to non-None in order to avoid database re-querying
1398 self
._Header
_ = 'DUMMY'
1400 ## Retrieve file version
1401 def _GetInfVersion(self
):
1402 if self
._AutoGenVersion
== None:
1403 if self
._Header
_ == None:
1404 self
._GetHeaderInfo
()
1405 if self
._AutoGenVersion
== None:
1406 self
._AutoGenVersion
= 0x00010000
1407 return self
._AutoGenVersion
1409 ## Retrieve BASE_NAME
1410 def _GetBaseName(self
):
1411 if self
._BaseName
== None:
1412 if self
._Header
_ == None:
1413 self
._GetHeaderInfo
()
1414 if self
._BaseName
== None:
1415 EdkLogger
.error('build', ATTRIBUTE_NOT_AVAILABLE
, "No BASE_NAME name", File
=self
.MetaFile
)
1416 return self
._BaseName
1418 ## Retrieve MODULE_TYPE
1419 def _GetModuleType(self
):
1420 if self
._ModuleType
== None:
1421 if self
._Header
_ == None:
1422 self
._GetHeaderInfo
()
1423 if self
._ModuleType
== None:
1424 self
._ModuleType
= 'BASE'
1425 if self
._ModuleType
not in SUP_MODULE_LIST
:
1426 self
._ModuleType
= "USER_DEFINED"
1427 return self
._ModuleType
1429 ## Retrieve COMPONENT_TYPE
1430 def _GetComponentType(self
):
1431 if self
._ComponentType
== None:
1432 if self
._Header
_ == None:
1433 self
._GetHeaderInfo
()
1434 if self
._ComponentType
== None:
1435 self
._ComponentType
= 'USER_DEFINED'
1436 return self
._ComponentType
1438 ## Retrieve "BUILD_TYPE"
1439 def _GetBuildType(self
):
1440 if self
._BuildType
== None:
1441 if self
._Header
_ == None:
1442 self
._GetHeaderInfo
()
1443 if not self
._BuildType
:
1444 self
._BuildType
= "BASE"
1445 return self
._BuildType
1447 ## Retrieve file guid
1448 def _GetFileGuid(self
):
1449 if self
._Guid
== None:
1450 if self
._Header
_ == None:
1451 self
._GetHeaderInfo
()
1452 if self
._Guid
== None:
1453 self
._Guid
= '00000000-0000-0000-000000000000'
1456 ## Retrieve module version
1457 def _GetVersion(self
):
1458 if self
._Version
== None:
1459 if self
._Header
_ == None:
1460 self
._GetHeaderInfo
()
1461 if self
._Version
== None:
1462 self
._Version
= '0.0'
1463 return self
._Version
1465 ## Retrieve PCD_IS_DRIVER
1466 def _GetPcdIsDriver(self
):
1467 if self
._PcdIsDriver
== None:
1468 if self
._Header
_ == None:
1469 self
._GetHeaderInfo
()
1470 if self
._PcdIsDriver
== None:
1471 self
._PcdIsDriver
= ''
1472 return self
._PcdIsDriver
1475 def _GetShadow(self
):
1476 if self
._Shadow
== None:
1477 if self
._Header
_ == None:
1478 self
._GetHeaderInfo
()
1479 if self
._Shadow
!= None and self
._Shadow
.upper() == 'TRUE':
1482 self
._Shadow
= False
1485 ## Retrieve CUSTOM_MAKEFILE
1486 def _GetMakefile(self
):
1487 if self
._CustomMakefile
== None:
1488 if self
._Header
_ == None:
1489 self
._GetHeaderInfo
()
1490 if self
._CustomMakefile
== None:
1491 self
._CustomMakefile
= {}
1492 return self
._CustomMakefile
1494 ## Retrieve EFI_SPECIFICATION_VERSION
1496 if self
._Specification
== None:
1497 if self
._Header
_ == None:
1498 self
._GetHeaderInfo
()
1499 if self
._Specification
== None:
1500 self
._Specification
= {}
1501 return self
._Specification
1503 ## Retrieve LIBRARY_CLASS
1504 def _GetLibraryClass(self
):
1505 if self
._LibraryClass
== None:
1506 if self
._Header
_ == None:
1507 self
._GetHeaderInfo
()
1508 if self
._LibraryClass
== None:
1509 self
._LibraryClass
= []
1510 return self
._LibraryClass
1512 ## Retrieve ENTRY_POINT
1513 def _GetEntryPoint(self
):
1514 if self
._ModuleEntryPointList
== None:
1515 if self
._Header
_ == None:
1516 self
._GetHeaderInfo
()
1517 if self
._ModuleEntryPointList
== None:
1518 self
._ModuleEntryPointList
= []
1519 return self
._ModuleEntryPointList
1521 ## Retrieve UNLOAD_IMAGE
1522 def _GetUnloadImage(self
):
1523 if self
._ModuleUnloadImageList
== None:
1524 if self
._Header
_ == None:
1525 self
._GetHeaderInfo
()
1526 if self
._ModuleUnloadImageList
== None:
1527 self
._ModuleUnloadImageList
= []
1528 return self
._ModuleUnloadImageList
1530 ## Retrieve CONSTRUCTOR
1531 def _GetConstructor(self
):
1532 if self
._ConstructorList
== None:
1533 if self
._Header
_ == None:
1534 self
._GetHeaderInfo
()
1535 if self
._ConstructorList
== None:
1536 self
._ConstructorList
= []
1537 return self
._ConstructorList
1539 ## Retrieve DESTRUCTOR
1540 def _GetDestructor(self
):
1541 if self
._DestructorList
== None:
1542 if self
._Header
_ == None:
1543 self
._GetHeaderInfo
()
1544 if self
._DestructorList
== None:
1545 self
._DestructorList
= []
1546 return self
._DestructorList
1548 ## Retrieve definies other than above ones
1549 def _GetDefines(self
):
1550 if self
._Defs
== None:
1551 if self
._Header
_ == None:
1552 self
._GetHeaderInfo
()
1553 if self
._Defs
== None:
1554 self
._Defs
= sdict()
1557 ## Retrieve binary files
1558 def _GetBinaryFiles(self
):
1559 if self
._Binaries
== None:
1561 RecordList
= self
._RawData
[MODEL_EFI_BINARY_FILE
, self
._Arch
, self
._Platform
]
1562 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
, 'PROCESSOR':self
._Arch
}
1563 Macros
.update(self
._Macros
)
1564 for Record
in RecordList
:
1565 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1566 FileType
= Record
[0]
1571 TokenList
= GetSplitValueList(Record
[2], TAB_VALUE_SPLIT
)
1573 Target
= TokenList
[0]
1574 if len(TokenList
) > 1:
1575 FeatureFlag
= Record
[1:]
1577 File
= PathClass(NormPath(Record
[1], Macros
), self
._ModuleDir
, '', FileType
, True, self
._Arch
, '', Target
)
1578 # check the file validation
1579 ErrorCode
, ErrorInfo
= File
.Validate()
1581 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1582 self
._Binaries
.append(File
)
1583 return self
._Binaries
1585 ## Retrieve source files
1586 def _GetSourceFiles(self
):
1587 if self
._Sources
== None:
1589 RecordList
= self
._RawData
[MODEL_EFI_SOURCE_FILE
, self
._Arch
, self
._Platform
]
1590 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
, 'PROCESSOR':self
._Arch
}
1591 Macros
.update(self
._Macros
)
1592 for Record
in RecordList
:
1593 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1595 ToolChainFamily
= Record
[1]
1597 ToolCode
= Record
[3]
1598 FeatureFlag
= Record
[4]
1599 if self
._AutoGenVersion
< 0x00010005:
1600 # old module source files (R8)
1601 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, self
._SourceOverridePath
,
1602 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1603 # check the file validation
1604 ErrorCode
, ErrorInfo
= File
.Validate(CaseSensitive
=False)
1606 if File
.Ext
.lower() == '.h':
1607 EdkLogger
.warn('build', 'Include file not found', ExtraData
=ErrorInfo
,
1608 File
=self
.MetaFile
, Line
=LineNo
)
1611 EdkLogger
.error('build', ErrorCode
, ExtraData
=File
, File
=self
.MetaFile
, Line
=LineNo
)
1613 File
= PathClass(NormPath(Record
[0], Macros
), self
._ModuleDir
, '',
1614 '', False, self
._Arch
, ToolChainFamily
, '', TagName
, ToolCode
)
1615 # check the file validation
1616 ErrorCode
, ErrorInfo
= File
.Validate()
1618 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1620 self
._Sources
.append(File
)
1621 return self
._Sources
1623 ## Retrieve library classes employed by this module
1624 def _GetLibraryClassUses(self
):
1625 if self
._LibraryClasses
== None:
1626 self
._LibraryClasses
= sdict()
1627 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_CLASS
, self
._Arch
, self
._Platform
]
1628 for Record
in RecordList
:
1629 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1631 Instance
= Record
[1]
1632 if Instance
!= None and Instance
!= '':
1633 Instance
= NormPath(Instance
, self
._Macros
)
1634 self
._LibraryClasses
[Lib
] = Instance
1635 return self
._LibraryClasses
1637 ## Retrieve library names (for R8.x style of modules)
1638 def _GetLibraryNames(self
):
1639 if self
._Libraries
== None:
1640 self
._Libraries
= []
1641 RecordList
= self
._RawData
[MODEL_EFI_LIBRARY_INSTANCE
, self
._Arch
, self
._Platform
]
1642 for Record
in RecordList
:
1643 # in case of name with '.lib' extension, which is unusual in R8.x inf
1644 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1645 LibraryName
= os
.path
.splitext(Record
[0])[0]
1646 if LibraryName
not in self
._Libraries
:
1647 self
._Libraries
.append(LibraryName
)
1648 return self
._Libraries
1650 ## Retrieve protocols consumed/produced by this module
1651 def _GetProtocols(self
):
1652 if self
._Protocols
== None:
1653 self
._Protocols
= sdict()
1654 RecordList
= self
._RawData
[MODEL_EFI_PROTOCOL
, self
._Arch
, self
._Platform
]
1655 for Record
in RecordList
:
1657 Value
= ProtocolValue(CName
, self
.Packages
)
1659 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1660 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1661 "Value of Protocol [%s] is not found under [Protocols] section in" % CName
,
1662 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1663 self
._Protocols
[CName
] = Value
1664 return self
._Protocols
1666 ## Retrieve PPIs consumed/produced by this module
1668 if self
._Ppis
== None:
1669 self
._Ppis
= sdict()
1670 RecordList
= self
._RawData
[MODEL_EFI_PPI
, self
._Arch
, self
._Platform
]
1671 for Record
in RecordList
:
1673 Value
= PpiValue(CName
, self
.Packages
)
1675 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1676 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1677 "Value of PPI [%s] is not found under [Ppis] section in " % CName
,
1678 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1679 self
._Ppis
[CName
] = Value
1682 ## Retrieve GUIDs consumed/produced by this module
1683 def _GetGuids(self
):
1684 if self
._Guids
== None:
1685 self
._Guids
= sdict()
1686 RecordList
= self
._RawData
[MODEL_EFI_GUID
, self
._Arch
, self
._Platform
]
1687 for Record
in RecordList
:
1689 Value
= GuidValue(CName
, self
.Packages
)
1691 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1692 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1693 "Value of Guid [%s] is not found under [Guids] section in" % CName
,
1694 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1695 self
._Guids
[CName
] = Value
1698 ## Retrieve include paths necessary for this module (for R8.x style of modules)
1699 def _GetIncludes(self
):
1700 if self
._Includes
== None:
1702 if self
._SourceOverridePath
:
1703 self
._Includes
.append(self
._SourceOverridePath
)
1704 RecordList
= self
._RawData
[MODEL_EFI_INCLUDE
, self
._Arch
, self
._Platform
]
1705 # [includes] section must be used only in old (R8.x) inf file
1706 if self
.AutoGenVersion
>= 0x00010005 and len(RecordList
) > 0:
1707 EdkLogger
.error('build', FORMAT_NOT_SUPPORTED
, "No [include] section allowed",
1708 File
=self
.MetaFile
, Line
=RecordList
[0][-1]-1)
1709 for Record
in RecordList
:
1710 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1711 Record
[0] = Record
[0].replace('$(PROCESSOR)', self
._Arch
)
1712 Record
[0] = ReplaceMacro(Record
[0], {'EFI_SOURCE' : GlobalData
.gEfiSource
}, False)
1713 if Record
[0].find('EDK_SOURCE') > -1:
1714 File
= NormPath(ReplaceMacro(Record
[0], {'EDK_SOURCE' : GlobalData
.gEcpSource
}, False), self
._Macros
)
1716 File
= os
.path
.join(self
._ModuleDir
, File
)
1718 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1719 File
= RealPath(os
.path
.normpath(File
))
1721 self
._Includes
.append(File
)
1723 #TRICK: let compiler to choose correct header file
1724 File
= NormPath(ReplaceMacro(Record
[0], {'EDK_SOURCE' : GlobalData
.gEdkSource
}, False), self
._Macros
)
1726 File
= os
.path
.join(self
._ModuleDir
, File
)
1728 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1729 File
= RealPath(os
.path
.normpath(File
))
1731 self
._Includes
.append(File
)
1733 File
= NormPath(Record
[0], self
._Macros
)
1735 File
= os
.path
.join(self
._ModuleDir
, File
)
1737 File
= os
.path
.join(GlobalData
.gWorkspace
, File
)
1738 File
= RealPath(os
.path
.normpath(File
))
1740 self
._Includes
.append(File
)
1741 return self
._Includes
1743 ## Retrieve packages this module depends on
1744 def _GetPackages(self
):
1745 if self
._Packages
== None:
1747 RecordList
= self
._RawData
[MODEL_META_DATA_PACKAGE
, self
._Arch
, self
._Platform
]
1748 Macros
= {"EDK_SOURCE":GlobalData
.gEcpSource
, "EFI_SOURCE":GlobalData
.gEfiSource
}
1749 Macros
.update(self
._Macros
)
1750 for Record
in RecordList
:
1751 File
= PathClass(NormPath(Record
[0], Macros
), GlobalData
.gWorkspace
, Arch
=self
._Arch
)
1753 # check the file validation
1754 ErrorCode
, ErrorInfo
= File
.Validate('.dec')
1756 EdkLogger
.error('build', ErrorCode
, ExtraData
=ErrorInfo
, File
=self
.MetaFile
, Line
=LineNo
)
1757 # parse this package now. we need it to get protocol/ppi/guid value
1758 Package
= self
._Bdb
[File
, self
._Arch
]
1759 self
._Packages
.append(Package
)
1760 return self
._Packages
1762 ## Retrieve PCDs used in this module
1764 if self
._Pcds
== None:
1766 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FIXED_AT_BUILD
))
1767 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_PATCHABLE_IN_MODULE
))
1768 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_FEATURE_FLAG
))
1769 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC
))
1770 self
._Pcds
.update(self
._GetPcd
(MODEL_PCD_DYNAMIC_EX
))
1773 ## Retrieve build options specific to this module
1774 def _GetBuildOptions(self
):
1775 if self
._BuildOptions
== None:
1776 self
._BuildOptions
= sdict()
1777 RecordList
= self
._RawData
[MODEL_META_DATA_BUILD_OPTION
, self
._Arch
, self
._Platform
]
1778 for Record
in RecordList
:
1779 ToolChainFamily
= Record
[0]
1780 ToolChain
= Record
[1]
1782 if (ToolChainFamily
, ToolChain
) not in self
._BuildOptions
:
1783 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = Option
1785 # concatenate the option string if they're for the same tool
1786 OptionString
= self
._BuildOptions
[ToolChainFamily
, ToolChain
]
1787 self
._BuildOptions
[ToolChainFamily
, ToolChain
] = OptionString
+ " " + Option
1788 return self
._BuildOptions
1790 ## Retrieve depedency expression
1791 def _GetDepex(self
):
1792 if self
._Depex
== None:
1793 self
._Depex
= tdict(False, 2)
1794 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1796 # PEIM and DXE drivers must have a valid [Depex] section
1797 if len(self
.LibraryClass
) == 0 and len(RecordList
) == 0:
1798 if self
.ModuleType
== 'DXE_DRIVER' or self
.ModuleType
== 'PEIM' or self
.ModuleType
== 'DXE_SMM_DRIVER' or \
1799 self
.ModuleType
== 'DXE_SAL_DRIVER' or self
.ModuleType
== 'DXE_RUNTIME_DRIVER':
1800 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
1801 % self
.ModuleType
, File
=self
.MetaFile
)
1804 for Record
in RecordList
:
1805 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1807 ModuleType
= Record
[4]
1808 TokenList
= Record
[0].split()
1809 if (Arch
, ModuleType
) not in Depex
:
1810 Depex
[Arch
, ModuleType
] = []
1811 DepexList
= Depex
[Arch
, ModuleType
]
1812 for Token
in TokenList
:
1813 if Token
in DEPEX_SUPPORTED_OPCODE
:
1814 DepexList
.append(Token
)
1815 elif Token
.endswith(".inf"): # module file name
1816 ModuleFile
= os
.path
.normpath(Token
)
1817 Module
= self
.BuildDatabase
[ModuleFile
]
1819 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "Module is not found in active platform",
1820 ExtraData
=Token
, File
=self
.MetaFile
, Line
=Record
[-1])
1821 DepexList
.append(Module
.Guid
)
1823 # get the GUID value now
1824 Value
= ProtocolValue(Token
, self
.Packages
)
1826 Value
= PpiValue(Token
, self
.Packages
)
1828 Value
= GuidValue(Token
, self
.Packages
)
1830 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1831 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1832 "Value of [%s] is not found in" % Token
,
1833 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=Record
[-1])
1834 DepexList
.append(Value
)
1835 for Arch
, ModuleType
in Depex
:
1836 self
._Depex
[Arch
, ModuleType
] = Depex
[Arch
, ModuleType
]
1839 ## Retrieve depedency expression
1840 def _GetDepexExpression(self
):
1841 if self
._DepexExpression
== None:
1842 self
._DepexExpression
= tdict(False, 2)
1843 RecordList
= self
._RawData
[MODEL_EFI_DEPEX
, self
._Arch
]
1844 DepexExpression
= {}
1845 for Record
in RecordList
:
1846 Record
= ReplaceMacros(Record
, GlobalData
.gEdkGlobal
, False)
1848 ModuleType
= Record
[4]
1849 TokenList
= Record
[0].split()
1850 if (Arch
, ModuleType
) not in DepexExpression
:
1851 DepexExpression
[Arch
, ModuleType
] = ''
1852 for Token
in TokenList
:
1853 DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
] + Token
.strip() + ' '
1854 for Arch
, ModuleType
in DepexExpression
:
1855 self
._DepexExpression
[Arch
, ModuleType
] = DepexExpression
[Arch
, ModuleType
]
1856 return self
._DepexExpression
1858 ## Retrieve PCD for given type
1859 def _GetPcd(self
, Type
):
1861 PcdDict
= tdict(True, 4)
1863 RecordList
= self
._RawData
[Type
, self
._Arch
, self
._Platform
]
1864 for TokenSpaceGuid
, PcdCName
, Setting
, Arch
, Platform
, Dummy1
, LineNo
in RecordList
:
1865 PcdDict
[Arch
, Platform
, PcdCName
, TokenSpaceGuid
] = (Setting
, LineNo
)
1866 PcdSet
.add((PcdCName
, TokenSpaceGuid
))
1867 # get the guid value
1868 if TokenSpaceGuid
not in self
.Guids
:
1869 Value
= GuidValue(TokenSpaceGuid
, self
.Packages
)
1871 PackageList
= "\n\t".join([str(P
) for P
in self
.Packages
])
1872 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
,
1873 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid
,
1874 ExtraData
=PackageList
, File
=self
.MetaFile
, Line
=LineNo
)
1875 self
.Guids
[TokenSpaceGuid
] = Value
1877 # resolve PCD type, value, datum info, etc. by getting its definition from package
1878 for PcdCName
, TokenSpaceGuid
in PcdSet
:
1879 ValueList
= ['', '']
1880 Setting
, LineNo
= PcdDict
[self
._Arch
, self
.Platform
, PcdCName
, TokenSpaceGuid
]
1883 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
1884 ValueList
[0:len(TokenList
)] = TokenList
1885 DefaultValue
= ValueList
[0]
1886 Pcd
= PcdClassObject(
1895 self
.Guids
[TokenSpaceGuid
]
1898 # get necessary info from package declaring this PCD
1899 for Package
in self
.Packages
:
1901 # 'dynamic' in INF means its type is determined by platform;
1902 # if platform doesn't give its type, use 'lowest' one in the
1903 # following order, if any
1905 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"
1907 PcdType
= self
._PCD
_TYPE
_STRING
_[Type
]
1908 if Type
in [MODEL_PCD_DYNAMIC
, MODEL_PCD_DYNAMIC_EX
]:
1910 for T
in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
1911 if (PcdCName
, TokenSpaceGuid
, T
) in Package
.Pcds
:
1917 if (PcdCName
, TokenSpaceGuid
, PcdType
) in Package
.Pcds
:
1918 PcdInPackage
= Package
.Pcds
[PcdCName
, TokenSpaceGuid
, PcdType
]
1920 Pcd
.TokenValue
= PcdInPackage
.TokenValue
1921 Pcd
.DatumType
= PcdInPackage
.DatumType
1922 Pcd
.MaxDatumSize
= PcdInPackage
.MaxDatumSize
1923 Pcd
.InfDefaultValue
= Pcd
.DefaultValue
1924 if Pcd
.DefaultValue
in [None, '']:
1925 Pcd
.DefaultValue
= PcdInPackage
.DefaultValue
1931 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid
, PcdCName
, self
.MetaFile
),
1932 File
=self
.MetaFile
, Line
=LineNo
,
1933 ExtraData
="\t%s" % '\n\t'.join([str(P
) for P
in self
.Packages
])
1935 Pcds
[PcdCName
, TokenSpaceGuid
] = Pcd
1938 Arch
= property(_GetArch
, _SetArch
)
1939 Platform
= property(_GetPlatform
, _SetPlatform
)
1941 AutoGenVersion
= property(_GetInfVersion
)
1942 BaseName
= property(_GetBaseName
)
1943 ModuleType
= property(_GetModuleType
)
1944 ComponentType
= property(_GetComponentType
)
1945 BuildType
= property(_GetBuildType
)
1946 Guid
= property(_GetFileGuid
)
1947 Version
= property(_GetVersion
)
1948 PcdIsDriver
= property(_GetPcdIsDriver
)
1949 Shadow
= property(_GetShadow
)
1950 CustomMakefile
= property(_GetMakefile
)
1951 Specification
= property(_GetSpec
)
1952 LibraryClass
= property(_GetLibraryClass
)
1953 ModuleEntryPointList
= property(_GetEntryPoint
)
1954 ModuleUnloadImageList
= property(_GetUnloadImage
)
1955 ConstructorList
= property(_GetConstructor
)
1956 DestructorList
= property(_GetDestructor
)
1957 Defines
= property(_GetDefines
)
1959 Binaries
= property(_GetBinaryFiles
)
1960 Sources
= property(_GetSourceFiles
)
1961 LibraryClasses
= property(_GetLibraryClassUses
)
1962 Libraries
= property(_GetLibraryNames
)
1963 Protocols
= property(_GetProtocols
)
1964 Ppis
= property(_GetPpis
)
1965 Guids
= property(_GetGuids
)
1966 Includes
= property(_GetIncludes
)
1967 Packages
= property(_GetPackages
)
1968 Pcds
= property(_GetPcds
)
1969 BuildOptions
= property(_GetBuildOptions
)
1970 Depex
= property(_GetDepex
)
1971 DepexExpression
= property(_GetDepexExpression
)
1975 # This class defined the build databse for all modules, packages and platform.
1976 # It will call corresponding parser for the given file if it cannot find it in
1979 # @param DbPath Path of database file
1980 # @param GlobalMacros Global macros used for replacement during file parsing
1981 # @prarm RenewDb=False Create new database file if it's already there
1983 class WorkspaceDatabase(object):
1986 MODEL_FILE_INF
: InfParser
,
1987 MODEL_FILE_DEC
: DecParser
,
1988 MODEL_FILE_DSC
: DscParser
,
1989 MODEL_FILE_FDF
: None, #FdfParser,
1990 MODEL_FILE_CIF
: None
1995 MODEL_FILE_INF
: ModuleTable
,
1996 MODEL_FILE_DEC
: PackageTable
,
1997 MODEL_FILE_DSC
: PlatformTable
,
2000 # default database file path
2001 _DB_PATH_
= "Conf/.cache/build.db"
2004 # internal class used for call corresponding file parser and caching the result
2005 # to avoid unnecessary re-parsing
2007 class BuildObjectFactory(object):
2009 ".inf" : MODEL_FILE_INF
,
2010 ".dec" : MODEL_FILE_DEC
,
2011 ".dsc" : MODEL_FILE_DSC
,
2012 ".fdf" : MODEL_FILE_FDF
,
2015 # convert to xxxBuildData object
2017 MODEL_FILE_INF
: InfBuildData
,
2018 MODEL_FILE_DEC
: DecBuildData
,
2019 MODEL_FILE_DSC
: DscBuildData
,
2020 MODEL_FILE_FDF
: None #FlashDefTable,
2023 _CACHE_
= {} # (FilePath, Arch) : <object>
2026 def __init__(self
, WorkspaceDb
):
2027 self
.WorkspaceDb
= WorkspaceDb
2029 # key = (FilePath, Arch='COMMON')
2030 def __contains__(self
, Key
):
2035 return (FilePath
, Arch
) in self
._CACHE
_
2037 # key = (FilePath, Arch='COMMON')
2038 def __getitem__(self
, Key
):
2047 # if it's generated before, just return the cached one
2048 Key
= (FilePath
, Arch
)
2049 if Key
in self
._CACHE
_:
2050 return self
._CACHE
_[Key
]
2053 Ext
= FilePath
.Ext
.lower()
2054 if Ext
not in self
._FILE
_TYPE
_:
2056 FileType
= self
._FILE
_TYPE
_[Ext
]
2057 if FileType
not in self
._GENERATOR
_:
2060 # get table for current file
2061 MetaFile
= self
.WorkspaceDb
[FilePath
, FileType
, self
.WorkspaceDb
._GlobalMacros
]
2062 BuildObject
= self
._GENERATOR
_[FileType
](
2068 self
.WorkspaceDb
._GlobalMacros
,
2070 self
._CACHE
_[Key
] = BuildObject
2073 # placeholder for file format conversion
2074 class TransformObjectFactory
:
2075 def __init__(self
, WorkspaceDb
):
2076 self
.WorkspaceDb
= WorkspaceDb
2078 # key = FilePath, Arch
2079 def __getitem__(self
, Key
):
2082 ## Constructor of WorkspaceDatabase
2084 # @param DbPath Path of database file
2085 # @param GlobalMacros Global macros used for replacement during file parsing
2086 # @prarm RenewDb=False Create new database file if it's already there
2088 def __init__(self
, DbPath
, GlobalMacros
={}, RenewDb
=False):
2089 self
._GlobalMacros
= GlobalMacros
2091 if DbPath
== None or DbPath
== '':
2092 DbPath
= os
.path
.normpath(os
.path
.join(GlobalData
.gWorkspace
, self
._DB
_PATH
_))
2094 # don't create necessary path for db in memory
2095 if DbPath
!= ':memory:':
2096 DbDir
= os
.path
.split(DbPath
)[0]
2097 if not os
.path
.exists(DbDir
):
2100 # remove db file in case inconsistency between db and file in file system
2101 if self
._CheckWhetherDbNeedRenew
(RenewDb
, DbPath
):
2104 # create db with optimized parameters
2105 self
.Conn
= sqlite3
.connect(DbPath
, isolation_level
='DEFERRED')
2106 self
.Conn
.execute("PRAGMA synchronous=OFF")
2107 self
.Conn
.execute("PRAGMA temp_store=MEMORY")
2108 self
.Conn
.execute("PRAGMA count_changes=OFF")
2109 self
.Conn
.execute("PRAGMA cache_size=8192")
2110 #self.Conn.execute("PRAGMA page_size=8192")
2112 # to avoid non-ascii character conversion issue
2113 self
.Conn
.text_factory
= str
2114 self
.Cur
= self
.Conn
.cursor()
2116 # create table for internal uses
2117 self
.TblDataModel
= TableDataModel(self
.Cur
)
2118 self
.TblFile
= TableFile(self
.Cur
)
2120 # conversion object for build or file format conversion purpose
2121 self
.BuildObject
= WorkspaceDatabase
.BuildObjectFactory(self
)
2122 self
.TransformObject
= WorkspaceDatabase
.TransformObjectFactory(self
)
2124 ## Check whether workspace database need to be renew.
2125 # The renew reason maybe:
2126 # 1) If user force to renew;
2127 # 2) If user do not force renew, and
2128 # a) If the time of last modified python source is newer than database file;
2129 # b) If the time of last modified frozen executable file is newer than database file;
2131 # @param force User force renew database
2132 # @param DbPath The absolute path of workspace database file
2134 # @return Bool value for whether need renew workspace databse
2136 def _CheckWhetherDbNeedRenew (self
, force
, DbPath
):
2137 DbDir
= os
.path
.split(DbPath
)[0]
2138 MacroFilePath
= os
.path
.normpath(os
.path
.join(DbDir
, "build.mac"))
2140 if os
.path
.exists(MacroFilePath
) and os
.path
.isfile(MacroFilePath
):
2143 f
= open(MacroFilePath
,'r')
2144 LastMacros
= pickle
.load(f
)
2151 if LastMacros
!= None and type(LastMacros
) is DictType
:
2152 if LastMacros
== self
._GlobalMacros
:
2154 for Macro
in LastMacros
.keys():
2155 if not (Macro
in self
._GlobalMacros
and LastMacros
[Macro
] == self
._GlobalMacros
[Macro
]):
2160 # save command line macros to file
2162 f
= open(MacroFilePath
,'w')
2163 pickle
.dump(self
._GlobalMacros
, f
, 2)
2172 # if database does not exist, we need do nothing
2173 if not os
.path
.exists(DbPath
): return False
2175 # if user force to renew database, then not check whether database is out of date
2176 if force
: return True
2179 # Check the time of last modified source file or build.exe
2180 # if is newer than time of database, then database need to be re-created.
2182 timeOfToolModified
= 0
2183 if hasattr(sys
, "frozen"):
2184 exePath
= os
.path
.abspath(sys
.executable
)
2185 timeOfToolModified
= os
.stat(exePath
).st_mtime
2187 curPath
= os
.path
.dirname(__file__
) # curPath is the path of WorkspaceDatabase.py
2188 rootPath
= os
.path
.split(curPath
)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python
2189 if rootPath
== "" or rootPath
== None:
2190 EdkLogger
.verbose("\nFail to find the root path of build.exe or python sources, so can not \
2191 determine whether database file is out of date!\n")
2193 # walk the root path of source or build's binary to get the time last modified.
2195 for root
, dirs
, files
in os
.walk (rootPath
):
2197 # bypass source control folder
2198 if dir.lower() in [".svn", "_svn", "cvs"]:
2202 ext
= os
.path
.splitext(file)[1]
2203 if ext
.lower() == ".py": # only check .py files
2204 fd
= os
.stat(os
.path
.join(root
, file))
2205 if timeOfToolModified
< fd
.st_mtime
:
2206 timeOfToolModified
= fd
.st_mtime
2207 if timeOfToolModified
> os
.stat(DbPath
).st_mtime
:
2208 EdkLogger
.verbose("\nWorkspace database is out of data!")
2213 ## Initialize build database
2214 def InitDatabase(self
):
2215 EdkLogger
.verbose("\nInitialize build database started ...")
2220 self
.TblDataModel
.Create(False)
2221 self
.TblFile
.Create(False)
2224 # Initialize table DataModel
2226 self
.TblDataModel
.InitTable()
2227 EdkLogger
.verbose("Initialize build database ... DONE!")
2231 # @param Table: The instance of the table to be queried
2233 def QueryTable(self
, Table
):
2236 ## Close entire database
2239 # Close the connection and cursor
2246 ## Get unique file ID for the gvien file
2247 def GetFileId(self
, FilePath
):
2248 return self
.TblFile
.GetFileId(FilePath
)
2250 ## Get file type value for the gvien file ID
2251 def GetFileType(self
, FileId
):
2252 return self
.TblFile
.GetFileType(FileId
)
2254 ## Get time stamp stored in file table
2255 def GetTimeStamp(self
, FileId
):
2256 return self
.TblFile
.GetFileTimeStamp(FileId
)
2258 ## Update time stamp in file table
2259 def SetTimeStamp(self
, FileId
, TimeStamp
):
2260 return self
.TblFile
.SetFileTimeStamp(FileId
, TimeStamp
)
2262 ## Check if a table integrity flag exists or not
2263 def CheckIntegrity(self
, TableName
):
2265 Result
= self
.Cur
.execute("select min(ID) from %s" % (TableName
)).fetchall()
2266 if Result
[0][0] != -1:
2272 ## Compose table name for given file type and file ID
2273 def GetTableName(self
, FileType
, FileId
):
2274 return "_%s_%s" % (FileType
, FileId
)
2276 ## Return a temp table containing all content of the given file
2278 # @param FileInfo The tuple containing path and type of a file
2280 def __getitem__(self
, FileInfo
):
2281 FilePath
, FileType
, Macros
= FileInfo
2282 if FileType
not in self
._FILE
_TABLE
_:
2285 # flag used to indicate if it's parsed or not
2286 FilePath
= str(FilePath
)
2288 FileId
= self
.GetFileId(FilePath
)
2290 TimeStamp
= os
.stat(FilePath
)[8]
2291 TableName
= self
.GetTableName(FileType
, FileId
)
2292 if TimeStamp
!= self
.GetTimeStamp(FileId
):
2293 # update the timestamp in database
2294 self
.SetTimeStamp(FileId
, TimeStamp
)
2296 # if the table exists and is integrity, don't parse it
2297 Parsed
= self
.CheckIntegrity(TableName
)
2299 FileId
= self
.TblFile
.InsertFile(FilePath
, FileType
)
2300 TableName
= self
.GetTableName(FileType
, FileId
)
2302 FileTable
= self
._FILE
_TABLE
_[FileType
](self
.Cur
, TableName
, FileId
)
2303 FileTable
.Create(not Parsed
)
2304 Parser
= self
._FILE
_PARSER
_[FileType
](FilePath
, FileType
, FileTable
, Macros
)
2305 # set the "Finished" flag in parser in order to avoid re-parsing (if parsed)
2306 Parser
.Finished
= Parsed
2309 ## Summarize all packages in the database
2310 def _GetPackageList(self
):
2312 for Module
in self
.ModuleList
:
2313 for Package
in Module
.Packages
:
2314 if Package
not in PackageList
:
2315 PackageList
.append(Package
)
2318 ## Summarize all platforms in the database
2319 def _GetPlatformList(self
):
2321 for PlatformFile
in self
.TblFile
.GetFileList(MODEL_FILE_DSC
):
2323 Platform
= self
.BuildObject
[PathClass(PlatformFile
), 'COMMON']
2326 if Platform
!= None:
2327 PlatformList
.append(Platform
)
2330 ## Summarize all modules in the database
2331 def _GetModuleList(self
):
2333 for ModuleFile
in self
.TblFile
.GetFileList(MODEL_FILE_INF
):
2335 Module
= self
.BuildObject
[PathClass(ModuleFile
), 'COMMON']
2339 ModuleList
.append(Module
)
2342 PlatformList
= property(_GetPlatformList
)
2343 PackageList
= property(_GetPackageList
)
2344 ModuleList
= property(_GetModuleList
)
2348 # This acts like the main() function for the script, unless it is 'import'ed into another
2351 if __name__
== '__main__':