2 # Generate AutoGen.h, AutoGen.c and *.depex files
4 # Copyright (c) 2007 - 2018, 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.
16 import Common
.LongFilePathOs
as os
18 import os
.path
as path
25 from StringIO
import StringIO
27 from StrGather
import *
28 from BuildEngine
import BuildRule
30 from Common
.LongFilePathSupport
import CopyLongFilePath
31 from Common
.BuildToolError
import *
32 from Common
.DataType
import *
33 from Common
.Misc
import *
34 from Common
.String
import *
35 import Common
.GlobalData
as GlobalData
36 from GenFds
.FdfParser
import *
37 from CommonDataClass
.CommonClass
import SkuInfoClass
38 from Workspace
.BuildClassObject
import *
39 from GenPatchPcdTable
.GenPatchPcdTable
import parsePcdInfoFromMapFile
40 import Common
.VpdInfoFile
as VpdInfoFile
41 from GenPcdDb
import CreatePcdDatabaseCode
42 from Workspace
.MetaFileCommentParser
import UsageList
43 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
44 import InfSectionParser
47 from GenVar
import VariableMgr
,var_info
49 ## Regular expression for splitting Dependency Expression string into tokens
50 gDepexTokenPattern
= re
.compile("(\(|\)|\w+| \S+\.inf)")
53 # Match name = variable
55 gEfiVarStoreNamePattern
= re
.compile("\s*name\s*=\s*(\w+)")
57 # The format of guid in efivarstore statement likes following and must be correct:
58 # guid = {0xA04A27f4, 0xDF00, 0x4D42, {0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D}}
60 gEfiVarStoreGuidPattern
= re
.compile("\s*guid\s*=\s*({.*?{.*?}\s*})")
62 ## Mapping Makefile type
63 gMakeTypeMap
= {"MSFT":"nmake", "GCC":"gmake"}
66 ## Build rule configuration file
67 gDefaultBuildRuleFile
= 'build_rule.txt'
69 ## Tools definition configuration file
70 gDefaultToolsDefFile
= 'tools_def.txt'
72 ## Build rule default version
73 AutoGenReqBuildRuleVerNum
= "0.1"
75 ## default file name for AutoGen
76 gAutoGenCodeFileName
= "AutoGen.c"
77 gAutoGenHeaderFileName
= "AutoGen.h"
78 gAutoGenStringFileName
= "%(module_name)sStrDefs.h"
79 gAutoGenStringFormFileName
= "%(module_name)sStrDefs.hpk"
80 gAutoGenDepexFileName
= "%(module_name)s.depex"
81 gAutoGenImageDefFileName
= "%(module_name)sImgDefs.h"
82 gAutoGenIdfFileName
= "%(module_name)sIdf.hpk"
83 gInfSpecVersion
= "0x00010017"
86 # Template string to generic AsBuilt INF
88 gAsBuiltInfHeaderString
= TemplateString("""${header_comments}
94 INF_VERSION = ${module_inf_version}
95 BASE_NAME = ${module_name}
96 FILE_GUID = ${module_guid}
97 MODULE_TYPE = ${module_module_type}${BEGIN}
98 VERSION_STRING = ${module_version_string}${END}${BEGIN}
99 PCD_IS_DRIVER = ${pcd_is_driver_string}${END}${BEGIN}
100 UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN}
101 PI_SPECIFICATION_VERSION = ${module_pi_specification_version}${END}${BEGIN}
102 ENTRY_POINT = ${module_entry_point}${END}${BEGIN}
103 UNLOAD_IMAGE = ${module_unload_image}${END}${BEGIN}
104 CONSTRUCTOR = ${module_constructor}${END}${BEGIN}
105 DESTRUCTOR = ${module_destructor}${END}${BEGIN}
106 SHADOW = ${module_shadow}${END}${BEGIN}
107 PCI_VENDOR_ID = ${module_pci_vendor_id}${END}${BEGIN}
108 PCI_DEVICE_ID = ${module_pci_device_id}${END}${BEGIN}
109 PCI_CLASS_CODE = ${module_pci_class_code}${END}${BEGIN}
110 PCI_REVISION = ${module_pci_revision}${END}${BEGIN}
111 BUILD_NUMBER = ${module_build_number}${END}${BEGIN}
112 SPEC = ${module_spec}${END}${BEGIN}
113 UEFI_HII_RESOURCE_SECTION = ${module_uefi_hii_resource_section}${END}${BEGIN}
114 MODULE_UNI_FILE = ${module_uni_file}${END}
116 [Packages.${module_arch}]${BEGIN}
117 ${package_item}${END}
119 [Binaries.${module_arch}]${BEGIN}
122 [PatchPcd.${module_arch}]${BEGIN}
126 [Protocols.${module_arch}]${BEGIN}
130 [Ppis.${module_arch}]${BEGIN}
134 [Guids.${module_arch}]${BEGIN}
138 [PcdEx.${module_arch}]${BEGIN}
142 [LibraryClasses.${module_arch}]
143 ## @LIB_INSTANCES${BEGIN}
144 # ${libraryclasses_item}${END}
148 ${userextension_tianocore_item}
152 [BuildOptions.${module_arch}]
154 ## ${flags_item}${END}
157 ## Base class for AutoGen
159 # This class just implements the cache mechanism of AutoGen objects.
161 class AutoGen(object):
162 # database to maintain the objects of xxxAutoGen
163 _CACHE_
= {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}
167 # @param Class class object of real AutoGen class
168 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
169 # @param Workspace Workspace directory or WorkspaceAutoGen object
170 # @param MetaFile The path of meta file
171 # @param Target Build target
172 # @param Toolchain Tool chain name
173 # @param Arch Target arch
174 # @param *args The specific class related parameters
175 # @param **kwargs The specific class related dict parameters
177 def __new__(Class
, Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
178 # check if the object has been created
179 Key
= (Target
, Toolchain
)
180 if Key
not in Class
._CACHE
_ or Arch
not in Class
._CACHE
_[Key
] \
181 or MetaFile
not in Class
._CACHE
_[Key
][Arch
]:
182 AutoGenObject
= super(AutoGen
, Class
).__new
__(Class
)
183 # call real constructor
184 if not AutoGenObject
._Init
(Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
186 if Key
not in Class
._CACHE
_:
187 Class
._CACHE
_[Key
] = {}
188 if Arch
not in Class
._CACHE
_[Key
]:
189 Class
._CACHE
_[Key
][Arch
] = {}
190 Class
._CACHE
_[Key
][Arch
][MetaFile
] = AutoGenObject
192 AutoGenObject
= Class
._CACHE
_[Key
][Arch
][MetaFile
]
198 # The file path of platform file will be used to represent hash value of this object
200 # @retval int Hash value of the file path of platform file
203 return hash(self
.MetaFile
)
207 # The file path of platform file will be used to represent this object
209 # @retval string String of platform file path
212 return str(self
.MetaFile
)
215 def __eq__(self
, Other
):
216 return Other
and self
.MetaFile
== Other
218 ## Workspace AutoGen class
220 # This class is used mainly to control the whole platform build for different
221 # architecture. This class will generate top level makefile.
223 class WorkspaceAutoGen(AutoGen
):
224 ## Real constructor of WorkspaceAutoGen
226 # This method behaves the same as __init__ except that it needs explicit invoke
227 # (in super class's __new__ method)
229 # @param WorkspaceDir Root directory of workspace
230 # @param ActivePlatform Meta-file of active platform
231 # @param Target Build target
232 # @param Toolchain Tool chain name
233 # @param ArchList List of architecture of current build
234 # @param MetaFileDb Database containing meta-files
235 # @param BuildConfig Configuration of build
236 # @param ToolDefinition Tool chain definitions
237 # @param FlashDefinitionFile File of flash definition
238 # @param Fds FD list to be generated
239 # @param Fvs FV list to be generated
240 # @param Caps Capsule list to be generated
241 # @param SkuId SKU id from command line
243 def _Init(self
, WorkspaceDir
, ActivePlatform
, Target
, Toolchain
, ArchList
, MetaFileDb
,
244 BuildConfig
, ToolDefinition
, FlashDefinitionFile
='', Fds
=None, Fvs
=None, Caps
=None, SkuId
='', UniFlag
=None,
245 Progress
=None, BuildModule
=None):
252 self
.BuildDatabase
= MetaFileDb
253 self
.MetaFile
= ActivePlatform
254 self
.WorkspaceDir
= WorkspaceDir
255 self
.Platform
= self
.BuildDatabase
[self
.MetaFile
, 'COMMON', Target
, Toolchain
]
256 GlobalData
.gActivePlatform
= self
.Platform
257 self
.BuildTarget
= Target
258 self
.ToolChain
= Toolchain
259 self
.ArchList
= ArchList
261 self
.UniFlag
= UniFlag
263 self
.TargetTxt
= BuildConfig
264 self
.ToolDef
= ToolDefinition
265 self
.FdfFile
= FlashDefinitionFile
266 self
.FdTargetList
= Fds
267 self
.FvTargetList
= Fvs
268 self
.CapTargetList
= Caps
269 self
.AutoGenObjectList
= []
270 self
._BuildDir
= None
272 self
._MakeFileDir
= None
273 self
._BuildCommand
= None
276 # there's many relative directory operations, so ...
277 os
.chdir(self
.WorkspaceDir
)
282 if not self
.ArchList
:
283 ArchList
= set(self
.Platform
.SupArchList
)
285 ArchList
= set(self
.ArchList
) & set(self
.Platform
.SupArchList
)
287 EdkLogger
.error("build", PARAMETER_INVALID
,
288 ExtraData
= "Invalid ARCH specified. [Valid ARCH: %s]" % (" ".join(self
.Platform
.SupArchList
)))
289 elif self
.ArchList
and len(ArchList
) != len(self
.ArchList
):
290 SkippedArchList
= set(self
.ArchList
).symmetric_difference(set(self
.Platform
.SupArchList
))
291 EdkLogger
.verbose("\nArch [%s] is ignored because the platform supports [%s] only!"
292 % (" ".join(SkippedArchList
), " ".join(self
.Platform
.SupArchList
)))
293 self
.ArchList
= tuple(ArchList
)
295 # Validate build target
296 if self
.BuildTarget
not in self
.Platform
.BuildTargets
:
297 EdkLogger
.error("build", PARAMETER_INVALID
,
298 ExtraData
="Build target [%s] is not supported by the platform. [Valid target: %s]"
299 % (self
.BuildTarget
, " ".join(self
.Platform
.BuildTargets
)))
302 # parse FDF file to get PCDs in it, if any
304 self
.FdfFile
= self
.Platform
.FlashDefinition
308 EdkLogger
.info('%-16s = %s' % ("Architecture(s)", ' '.join(self
.ArchList
)))
309 EdkLogger
.info('%-16s = %s' % ("Build target", self
.BuildTarget
))
310 EdkLogger
.info('%-16s = %s' % ("Toolchain", self
.ToolChain
))
312 EdkLogger
.info('\n%-24s = %s' % ("Active Platform", self
.Platform
))
314 EdkLogger
.info('%-24s = %s' % ("Active Module", BuildModule
))
317 EdkLogger
.info('%-24s = %s' % ("Flash Image Definition", self
.FdfFile
))
319 EdkLogger
.verbose("\nFLASH_DEFINITION = %s" % self
.FdfFile
)
322 Progress
.Start("\nProcessing meta-data")
326 # Mark now build in AutoGen Phase
328 GlobalData
.gAutoGenPhase
= True
329 Fdf
= FdfParser(self
.FdfFile
.Path
)
331 GlobalData
.gFdfParser
= Fdf
332 GlobalData
.gAutoGenPhase
= False
333 PcdSet
= Fdf
.Profile
.PcdDict
334 if Fdf
.CurrentFdName
and Fdf
.CurrentFdName
in Fdf
.Profile
.FdDict
:
335 FdDict
= Fdf
.Profile
.FdDict
[Fdf
.CurrentFdName
]
336 for FdRegion
in FdDict
.RegionList
:
337 if str(FdRegion
.RegionType
) is 'FILE' and self
.Platform
.VpdToolGuid
in str(FdRegion
.RegionDataList
):
338 if int(FdRegion
.Offset
) % 8 != 0:
339 EdkLogger
.error("build", FORMAT_INVALID
, 'The VPD Base Address %s must be 8-byte aligned.' % (FdRegion
.Offset
))
340 ModuleList
= Fdf
.Profile
.InfList
341 self
.FdfProfile
= Fdf
.Profile
342 for fvname
in self
.FvTargetList
:
343 if fvname
.upper() not in self
.FdfProfile
.FvDict
:
344 EdkLogger
.error("build", OPTION_VALUE_INVALID
,
345 "No such an FV in FDF file: %s" % fvname
)
347 # In DSC file may use FILE_GUID to override the module, then in the Platform.Modules use FILE_GUIDmodule.inf as key,
348 # but the path (self.MetaFile.Path) is the real path
349 for key
in self
.FdfProfile
.InfDict
:
353 for Arch
in self
.ArchList
:
354 Platform_cache
[Arch
] = self
.BuildDatabase
[self
.MetaFile
, Arch
, Target
, Toolchain
]
355 MetaFile_cache
[Arch
] = []
356 for Pkey
in Platform_cache
[Arch
].Modules
.keys():
357 MetaFile_cache
[Arch
].append(Platform_cache
[Arch
].Modules
[Pkey
].MetaFile
)
358 for Inf
in self
.FdfProfile
.InfDict
[key
]:
359 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
)
360 for Arch
in self
.ArchList
:
361 if ModuleFile
in MetaFile_cache
[Arch
]:
364 ModuleData
= self
.BuildDatabase
[ModuleFile
, Arch
, Target
, Toolchain
]
365 if not ModuleData
.IsBinaryModule
:
366 EdkLogger
.error('build', PARSER_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile
)
369 for Arch
in self
.ArchList
:
371 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
, Target
, Toolchain
]
373 for Pkey
in Platform
.Modules
.keys():
374 MetaFileList
.append(Platform
.Modules
[Pkey
].MetaFile
)
375 for Inf
in self
.FdfProfile
.InfDict
[key
]:
376 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
)
377 if ModuleFile
in MetaFileList
:
379 ModuleData
= self
.BuildDatabase
[ModuleFile
, Arch
, Target
, Toolchain
]
380 if not ModuleData
.IsBinaryModule
:
381 EdkLogger
.error('build', PARSER_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile
)
386 self
.FdfProfile
= None
387 if self
.FdTargetList
:
388 EdkLogger
.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self
.FdTargetList
))
389 self
.FdTargetList
= []
390 if self
.FvTargetList
:
391 EdkLogger
.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self
.FvTargetList
))
392 self
.FvTargetList
= []
393 if self
.CapTargetList
:
394 EdkLogger
.info("No flash definition file found. Capsule [%s] will be ignored." % " ".join(self
.CapTargetList
))
395 self
.CapTargetList
= []
397 # apply SKU and inject PCDs from Flash Definition file
398 for Arch
in self
.ArchList
:
399 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
, Target
, Toolchain
]
403 PGen
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
404 if GlobalData
.BuildOptionPcd
:
405 for i
, pcd
in enumerate(GlobalData
.BuildOptionPcd
):
406 if type(pcd
) is tuple:
408 (pcdname
, pcdvalue
) = pcd
.split('=')
410 EdkLogger
.error('build', AUTOGEN_ERROR
, "No Value specified for the PCD %s." % (pcdname
))
412 (TokenSpaceGuidCName
, TokenCName
) = pcdname
.split('.')
416 TokenSpaceGuidCName
= ''
417 HasTokenSpace
= False
418 TokenSpaceGuidCNameList
= []
422 for package
in PGen
.PackageList
:
423 Guids
= package
.Guids
424 self
._GuidDict
.update(Guids
)
425 for package
in PGen
.PackageList
:
426 for key
in package
.Pcds
:
427 PcdItem
= package
.Pcds
[key
]
429 if (PcdItem
.TokenCName
, PcdItem
.TokenSpaceGuidCName
) == (TokenCName
, TokenSpaceGuidCName
):
430 PcdDatumType
= PcdItem
.DatumType
431 if pcdvalue
.startswith('H'):
433 pcdvalue
= ValueExpressionEx(pcdvalue
[1:], PcdDatumType
, self
._GuidDict
)(True)
434 except BadExpression
, Value
:
436 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %
437 (TokenSpaceGuidCName
, TokenCName
, pcdvalue
, Value
))
438 pcdvalue
= 'H' + pcdvalue
439 NewValue
= BuildOptionPcdValueFormat(TokenSpaceGuidCName
, TokenCName
, PcdDatumType
, pcdvalue
)
442 if PcdItem
.TokenCName
== TokenCName
:
443 if not PcdItem
.TokenSpaceGuidCName
in TokenSpaceGuidCNameList
:
444 if len (TokenSpaceGuidCNameList
) < 1:
445 TokenSpaceGuidCNameList
.append(PcdItem
.TokenSpaceGuidCName
)
446 PcdDatumType
= PcdItem
.DatumType
447 TokenSpaceGuidCName
= PcdItem
.TokenSpaceGuidCName
448 if pcdvalue
.startswith('H'):
450 pcdvalue
= ValueExpressionEx(pcdvalue
[1:], PcdDatumType
, self
._GuidDict
)(True)
451 except BadExpression
, Value
:
452 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %
453 (TokenSpaceGuidCName
, TokenCName
, pcdvalue
, Value
))
454 pcdvalue
= 'H' + pcdvalue
455 NewValue
= BuildOptionPcdValueFormat(TokenSpaceGuidCName
, TokenCName
, PcdDatumType
, pcdvalue
)
461 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName
, PcdItem
.TokenSpaceGuidCName
, TokenSpaceGuidCNameList
[0])
464 GlobalData
.BuildOptionPcd
[i
] = (TokenSpaceGuidCName
, TokenCName
, NewValue
)
468 EdkLogger
.error('build', AUTOGEN_ERROR
, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName
, TokenCName
))
470 EdkLogger
.error('build', AUTOGEN_ERROR
, "The Pcd %s is not found in the DEC file." % (TokenCName
))
472 for BuildData
in PGen
.BuildDatabase
._CACHE
_.values():
473 if BuildData
.Arch
!= Arch
:
475 if BuildData
.MetaFile
.Ext
== '.dec':
477 for key
in BuildData
.Pcds
:
478 PcdItem
= BuildData
.Pcds
[key
]
479 if (TokenSpaceGuidCName
, TokenCName
) == (PcdItem
.TokenSpaceGuidCName
, PcdItem
.TokenCName
):
480 PcdItem
.DefaultValue
= NewValue
482 if (TokenCName
, TokenSpaceGuidCName
) in PcdSet
:
483 PcdSet
[(TokenCName
, TokenSpaceGuidCName
)] = NewValue
485 SourcePcdDict
= {'DynamicEx':[], 'PatchableInModule':[],'Dynamic':[],'FixedAtBuild':[]}
486 BinaryPcdDict
= {'DynamicEx':[], 'PatchableInModule':[]}
487 SourcePcdDict_Keys
= SourcePcdDict
.keys()
488 BinaryPcdDict_Keys
= BinaryPcdDict
.keys()
490 # generate the SourcePcdDict and BinaryPcdDict
491 for BuildData
in PGen
.BuildDatabase
._CACHE
_.values():
492 if BuildData
.Arch
!= Arch
:
494 if BuildData
.MetaFile
.Ext
== '.inf':
495 for key
in BuildData
.Pcds
:
496 if BuildData
.Pcds
[key
].Pending
:
497 if key
in Platform
.Pcds
:
498 PcdInPlatform
= Platform
.Pcds
[key
]
499 if PcdInPlatform
.Type
not in [None, '']:
500 BuildData
.Pcds
[key
].Type
= PcdInPlatform
.Type
502 if BuildData
.MetaFile
in Platform
.Modules
:
503 PlatformModule
= Platform
.Modules
[str(BuildData
.MetaFile
)]
504 if key
in PlatformModule
.Pcds
:
505 PcdInPlatform
= PlatformModule
.Pcds
[key
]
506 if PcdInPlatform
.Type
not in [None, '']:
507 BuildData
.Pcds
[key
].Type
= PcdInPlatform
.Type
509 if 'DynamicEx' in BuildData
.Pcds
[key
].Type
:
510 if BuildData
.IsBinaryModule
:
511 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in BinaryPcdDict
['DynamicEx']:
512 BinaryPcdDict
['DynamicEx'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
514 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in SourcePcdDict
['DynamicEx']:
515 SourcePcdDict
['DynamicEx'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
517 elif 'PatchableInModule' in BuildData
.Pcds
[key
].Type
:
518 if BuildData
.MetaFile
.Ext
== '.inf':
519 if BuildData
.IsBinaryModule
:
520 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in BinaryPcdDict
['PatchableInModule']:
521 BinaryPcdDict
['PatchableInModule'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
523 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in SourcePcdDict
['PatchableInModule']:
524 SourcePcdDict
['PatchableInModule'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
526 elif 'Dynamic' in BuildData
.Pcds
[key
].Type
:
527 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in SourcePcdDict
['Dynamic']:
528 SourcePcdDict
['Dynamic'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
529 elif 'FixedAtBuild' in BuildData
.Pcds
[key
].Type
:
530 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in SourcePcdDict
['FixedAtBuild']:
531 SourcePcdDict
['FixedAtBuild'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
535 # A PCD can only use one type for all source modules
537 for i
in SourcePcdDict_Keys
:
538 for j
in SourcePcdDict_Keys
:
540 IntersectionList
= list(set(SourcePcdDict
[i
]).intersection(set(SourcePcdDict
[j
])))
541 if len(IntersectionList
) > 0:
545 "Building modules from source INFs, following PCD use %s and %s access method. It must be corrected to use only one access method." % (i
, j
),
546 ExtraData
="%s" % '\n\t'.join([str(P
[1]+'.'+P
[0]) for P
in IntersectionList
])
552 # intersection the BinaryPCD for Mixed PCD
554 for i
in BinaryPcdDict_Keys
:
555 for j
in BinaryPcdDict_Keys
:
557 IntersectionList
= list(set(BinaryPcdDict
[i
]).intersection(set(BinaryPcdDict
[j
])))
558 for item
in IntersectionList
:
559 NewPcd1
= (item
[0] + '_' + i
, item
[1])
560 NewPcd2
= (item
[0] + '_' + j
, item
[1])
561 if item
not in GlobalData
.MixedPcd
:
562 GlobalData
.MixedPcd
[item
] = [NewPcd1
, NewPcd2
]
564 if NewPcd1
not in GlobalData
.MixedPcd
[item
]:
565 GlobalData
.MixedPcd
[item
].append(NewPcd1
)
566 if NewPcd2
not in GlobalData
.MixedPcd
[item
]:
567 GlobalData
.MixedPcd
[item
].append(NewPcd2
)
572 # intersection the SourcePCD and BinaryPCD for Mixed PCD
574 for i
in SourcePcdDict_Keys
:
575 for j
in BinaryPcdDict_Keys
:
577 IntersectionList
= list(set(SourcePcdDict
[i
]).intersection(set(BinaryPcdDict
[j
])))
578 for item
in IntersectionList
:
579 NewPcd1
= (item
[0] + '_' + i
, item
[1])
580 NewPcd2
= (item
[0] + '_' + j
, item
[1])
581 if item
not in GlobalData
.MixedPcd
:
582 GlobalData
.MixedPcd
[item
] = [NewPcd1
, NewPcd2
]
584 if NewPcd1
not in GlobalData
.MixedPcd
[item
]:
585 GlobalData
.MixedPcd
[item
].append(NewPcd1
)
586 if NewPcd2
not in GlobalData
.MixedPcd
[item
]:
587 GlobalData
.MixedPcd
[item
].append(NewPcd2
)
591 for BuildData
in PGen
.BuildDatabase
._CACHE
_.values():
592 if BuildData
.Arch
!= Arch
:
594 for key
in BuildData
.Pcds
:
595 for SinglePcd
in GlobalData
.MixedPcd
:
596 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) == SinglePcd
:
597 for item
in GlobalData
.MixedPcd
[SinglePcd
]:
598 Pcd_Type
= item
[0].split('_')[-1]
599 if (Pcd_Type
== BuildData
.Pcds
[key
].Type
) or (Pcd_Type
== TAB_PCDS_DYNAMIC_EX
and BuildData
.Pcds
[key
].Type
in GenC
.gDynamicExPcd
) or \
600 (Pcd_Type
== TAB_PCDS_DYNAMIC
and BuildData
.Pcds
[key
].Type
in GenC
.gDynamicPcd
):
601 Value
= BuildData
.Pcds
[key
]
602 Value
.TokenCName
= BuildData
.Pcds
[key
].TokenCName
+ '_' + Pcd_Type
604 newkey
= (Value
.TokenCName
, key
[1])
606 newkey
= (Value
.TokenCName
, key
[1], key
[2])
607 del BuildData
.Pcds
[key
]
608 BuildData
.Pcds
[newkey
] = Value
616 # handle the mixed pcd in FDF file
618 if key
in GlobalData
.MixedPcd
:
621 for item
in GlobalData
.MixedPcd
[key
]:
624 #Collect package set information from INF of FDF
626 for Inf
in ModuleList
:
627 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
)
628 if ModuleFile
in Platform
.Modules
:
630 ModuleData
= self
.BuildDatabase
[ModuleFile
, Arch
, Target
, Toolchain
]
631 PkgSet
.update(ModuleData
.Packages
)
632 Pkgs
= list(PkgSet
) + list(PGen
.PackageList
)
635 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
636 DecPcdsKey
.add((Pcd
[0], Pcd
[1], Pcd
[2]))
638 Platform
.SkuName
= self
.SkuId
639 for Name
, Guid
in PcdSet
:
640 if (Name
, Guid
) not in DecPcds
:
644 "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid
, Name
),
645 File
= self
.FdfProfile
.PcdFileLineDict
[Name
, Guid
][0],
646 Line
= self
.FdfProfile
.PcdFileLineDict
[Name
, Guid
][1]
649 # Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message.
650 if (Name
, Guid
, TAB_PCDS_FIXED_AT_BUILD
) in DecPcdsKey \
651 or (Name
, Guid
, TAB_PCDS_PATCHABLE_IN_MODULE
) in DecPcdsKey \
652 or (Name
, Guid
, TAB_PCDS_FEATURE_FLAG
) in DecPcdsKey
:
653 Platform
.AddPcd(Name
, Guid
, PcdSet
[Name
, Guid
])
655 elif (Name
, Guid
, TAB_PCDS_DYNAMIC
) in DecPcdsKey
or (Name
, Guid
, TAB_PCDS_DYNAMIC_EX
) in DecPcdsKey
:
659 "Using Dynamic or DynamicEx type of PCD [%s.%s] in FDF file is not allowed." % (Guid
, Name
),
660 File
= self
.FdfProfile
.PcdFileLineDict
[Name
, Guid
][0],
661 Line
= self
.FdfProfile
.PcdFileLineDict
[Name
, Guid
][1]
664 Pa
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
666 # Explicitly collect platform's dynamic PCDs
668 Pa
.CollectPlatformDynamicPcds()
669 Pa
.CollectFixedAtBuildPcds()
670 self
.AutoGenObjectList
.append(Pa
)
673 # Generate Package level hash value
675 GlobalData
.gPackageHash
[Arch
] = {}
676 if GlobalData
.gUseHashCache
:
678 self
._GenPkgLevelHash
(Pkg
)
681 # Check PCDs token value conflict in each DEC file.
683 self
._CheckAllPcdsTokenValueConflict
()
686 # Check PCD type and definition between DSC and DEC
688 self
._CheckPcdDefineAndType
()
691 # self._CheckDuplicateInFV(Fdf)
694 # Create BuildOptions Macro & PCD metafile, also add the Active Platform and FDF file.
696 content
= 'gCommandLineDefines: '
697 content
+= str(GlobalData
.gCommandLineDefines
)
698 content
+= os
.linesep
699 content
+= 'BuildOptionPcd: '
700 content
+= str(GlobalData
.BuildOptionPcd
)
701 content
+= os
.linesep
702 content
+= 'Active Platform: '
703 content
+= str(self
.Platform
)
704 content
+= os
.linesep
706 content
+= 'Flash Image Definition: '
707 content
+= str(self
.FdfFile
)
708 content
+= os
.linesep
709 SaveFileOnChange(os
.path
.join(self
.BuildDir
, 'BuildOptions'), content
, False)
712 # Create PcdToken Number file for Dynamic/DynamicEx Pcd.
714 PcdTokenNumber
= 'PcdTokenNumber: '
715 if Pa
.PcdTokenNumber
:
716 if Pa
.DynamicPcdList
:
717 for Pcd
in Pa
.DynamicPcdList
:
718 PcdTokenNumber
+= os
.linesep
719 PcdTokenNumber
+= str((Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
))
720 PcdTokenNumber
+= ' : '
721 PcdTokenNumber
+= str(Pa
.PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
])
722 SaveFileOnChange(os
.path
.join(self
.BuildDir
, 'PcdTokenNumber'), PcdTokenNumber
, False)
725 # Get set of workspace metafiles
727 AllWorkSpaceMetaFiles
= self
._GetMetaFiles
(Target
, Toolchain
, Arch
)
730 # Retrieve latest modified time of all metafiles
733 for f
in AllWorkSpaceMetaFiles
:
734 if os
.stat(f
)[8] > SrcTimeStamp
:
735 SrcTimeStamp
= os
.stat(f
)[8]
736 self
._SrcTimeStamp
= SrcTimeStamp
738 if GlobalData
.gUseHashCache
:
740 for files
in AllWorkSpaceMetaFiles
:
741 if files
.endswith('.dec'):
747 SaveFileOnChange(os
.path
.join(self
.BuildDir
, 'AutoGen.hash'), m
.hexdigest(), True)
748 GlobalData
.gPlatformHash
= m
.hexdigest()
751 # Write metafile list to build directory
753 AutoGenFilePath
= os
.path
.join(self
.BuildDir
, 'AutoGen')
754 if os
.path
.exists (AutoGenFilePath
):
755 os
.remove(AutoGenFilePath
)
756 if not os
.path
.exists(self
.BuildDir
):
757 os
.makedirs(self
.BuildDir
)
758 with
open(os
.path
.join(self
.BuildDir
, 'AutoGen'), 'w+') as file:
759 for f
in AllWorkSpaceMetaFiles
:
763 def _GenPkgLevelHash(self
, Pkg
):
764 PkgDir
= os
.path
.join(self
.BuildDir
, Pkg
.Arch
, Pkg
.PackageName
)
765 CreateDirectory(PkgDir
)
766 HashFile
= os
.path
.join(PkgDir
, Pkg
.PackageName
+ '.hash')
768 # Get .dec file's hash value
769 f
= open(Pkg
.MetaFile
.Path
, 'r')
773 # Get include files hash value
775 for inc
in Pkg
.Includes
:
776 for Root
, Dirs
, Files
in os
.walk(str(inc
)):
778 File_Path
= os
.path
.join(Root
, File
)
779 f
= open(File_Path
, 'r')
783 SaveFileOnChange(HashFile
, m
.hexdigest(), True)
784 if Pkg
.PackageName
not in GlobalData
.gPackageHash
[Pkg
.Arch
]:
785 GlobalData
.gPackageHash
[Pkg
.Arch
][Pkg
.PackageName
] = m
.hexdigest()
787 def _GetMetaFiles(self
, Target
, Toolchain
, Arch
):
788 AllWorkSpaceMetaFiles
= set()
793 AllWorkSpaceMetaFiles
.add (self
.FdfFile
.Path
)
795 FdfFiles
= GlobalData
.gFdfParser
.GetAllIncludedFile()
797 AllWorkSpaceMetaFiles
.add (f
.FileName
)
801 AllWorkSpaceMetaFiles
.add(self
.MetaFile
.Path
)
804 # add build_rule.txt & tools_def.txt
806 AllWorkSpaceMetaFiles
.add(os
.path
.join(GlobalData
.gConfDirectory
, gDefaultBuildRuleFile
))
807 AllWorkSpaceMetaFiles
.add(os
.path
.join(GlobalData
.gConfDirectory
, gDefaultToolsDefFile
))
809 # add BuildOption metafile
811 AllWorkSpaceMetaFiles
.add(os
.path
.join(self
.BuildDir
, 'BuildOptions'))
813 # add PcdToken Number file for Dynamic/DynamicEx Pcd
815 AllWorkSpaceMetaFiles
.add(os
.path
.join(self
.BuildDir
, 'PcdTokenNumber'))
817 for Arch
in self
.ArchList
:
818 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
, Target
, Toolchain
]
819 PGen
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
824 for Package
in PGen
.PackageList
:
825 AllWorkSpaceMetaFiles
.add(Package
.MetaFile
.Path
)
830 for filePath
in Platform
._RawData
.IncludedFiles
:
831 AllWorkSpaceMetaFiles
.add(filePath
.Path
)
833 return AllWorkSpaceMetaFiles
835 ## _CheckDuplicateInFV() method
837 # Check whether there is duplicate modules/files exist in FV section.
838 # The check base on the file GUID;
840 def _CheckDuplicateInFV(self
, Fdf
):
841 for Fv
in Fdf
.Profile
.FvDict
:
843 for FfsFile
in Fdf
.Profile
.FvDict
[Fv
].FfsList
:
844 if FfsFile
.InfFileName
and FfsFile
.NameGuid
== None:
849 for Pa
in self
.AutoGenObjectList
:
852 for Module
in Pa
.ModuleAutoGenList
:
853 if path
.normpath(Module
.MetaFile
.File
) == path
.normpath(FfsFile
.InfFileName
):
855 if not Module
.Guid
.upper() in _GuidDict
.keys():
856 _GuidDict
[Module
.Guid
.upper()] = FfsFile
859 EdkLogger
.error("build",
861 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile
.CurrentLineNum
,
862 FfsFile
.CurrentLineContent
,
863 _GuidDict
[Module
.Guid
.upper()].CurrentLineNum
,
864 _GuidDict
[Module
.Guid
.upper()].CurrentLineContent
,
865 Module
.Guid
.upper()),
866 ExtraData
=self
.FdfFile
)
868 # Some INF files not have entity in DSC file.
871 if FfsFile
.InfFileName
.find('$') == -1:
872 InfPath
= NormPath(FfsFile
.InfFileName
)
873 if not os
.path
.exists(InfPath
):
874 EdkLogger
.error('build', GENFDS_ERROR
, "Non-existant Module %s !" % (FfsFile
.InfFileName
))
876 PathClassObj
= PathClass(FfsFile
.InfFileName
, self
.WorkspaceDir
)
878 # Here we just need to get FILE_GUID from INF file, use 'COMMON' as ARCH attribute. and use
879 # BuildObject from one of AutoGenObjectList is enough.
881 InfObj
= self
.AutoGenObjectList
[0].BuildDatabase
.WorkspaceDb
.BuildObject
[PathClassObj
, 'COMMON', self
.BuildTarget
, self
.ToolChain
]
882 if not InfObj
.Guid
.upper() in _GuidDict
.keys():
883 _GuidDict
[InfObj
.Guid
.upper()] = FfsFile
885 EdkLogger
.error("build",
887 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile
.CurrentLineNum
,
888 FfsFile
.CurrentLineContent
,
889 _GuidDict
[InfObj
.Guid
.upper()].CurrentLineNum
,
890 _GuidDict
[InfObj
.Guid
.upper()].CurrentLineContent
,
891 InfObj
.Guid
.upper()),
892 ExtraData
=self
.FdfFile
)
895 if FfsFile
.NameGuid
!= None:
896 _CheckPCDAsGuidPattern
= re
.compile("^PCD\(.+\..+\)$")
899 # If the NameGuid reference a PCD name.
900 # The style must match: PCD(xxxx.yyy)
902 if _CheckPCDAsGuidPattern
.match(FfsFile
.NameGuid
):
904 # Replace the PCD value.
906 _PcdName
= FfsFile
.NameGuid
.lstrip("PCD(").rstrip(")")
908 for Pa
in self
.AutoGenObjectList
:
910 for PcdItem
in Pa
.AllPcdList
:
911 if (PcdItem
.TokenSpaceGuidCName
+ "." + PcdItem
.TokenCName
) == _PcdName
:
913 # First convert from CFormatGuid to GUID string
915 _PcdGuidString
= GuidStructureStringToGuidString(PcdItem
.DefaultValue
)
917 if not _PcdGuidString
:
919 # Then try Byte array.
921 _PcdGuidString
= GuidStructureByteArrayToGuidString(PcdItem
.DefaultValue
)
923 if not _PcdGuidString
:
925 # Not Byte array or CFormat GUID, raise error.
927 EdkLogger
.error("build",
929 "The format of PCD value is incorrect. PCD: %s , Value: %s\n" % (_PcdName
, PcdItem
.DefaultValue
),
930 ExtraData
=self
.FdfFile
)
932 if not _PcdGuidString
.upper() in _GuidDict
.keys():
933 _GuidDict
[_PcdGuidString
.upper()] = FfsFile
937 EdkLogger
.error("build",
939 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile
.CurrentLineNum
,
940 FfsFile
.CurrentLineContent
,
941 _GuidDict
[_PcdGuidString
.upper()].CurrentLineNum
,
942 _GuidDict
[_PcdGuidString
.upper()].CurrentLineContent
,
943 FfsFile
.NameGuid
.upper()),
944 ExtraData
=self
.FdfFile
)
946 if not FfsFile
.NameGuid
.upper() in _GuidDict
.keys():
947 _GuidDict
[FfsFile
.NameGuid
.upper()] = FfsFile
950 # Two raw file GUID conflict.
952 EdkLogger
.error("build",
954 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile
.CurrentLineNum
,
955 FfsFile
.CurrentLineContent
,
956 _GuidDict
[FfsFile
.NameGuid
.upper()].CurrentLineNum
,
957 _GuidDict
[FfsFile
.NameGuid
.upper()].CurrentLineContent
,
958 FfsFile
.NameGuid
.upper()),
959 ExtraData
=self
.FdfFile
)
962 def _CheckPcdDefineAndType(self
):
964 "FixedAtBuild", "PatchableInModule", "FeatureFlag",
965 "Dynamic", #"DynamicHii", "DynamicVpd",
966 "DynamicEx", # "DynamicExHii", "DynamicExVpd"
969 # This dict store PCDs which are not used by any modules with specified arches
971 for Pa
in self
.AutoGenObjectList
:
972 # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid
973 for Pcd
in Pa
.Platform
.Pcds
:
974 PcdType
= Pa
.Platform
.Pcds
[Pcd
].Type
976 # If no PCD type, this PCD comes from FDF
980 # Try to remove Hii and Vpd suffix
981 if PcdType
.startswith("DynamicEx"):
982 PcdType
= "DynamicEx"
983 elif PcdType
.startswith("Dynamic"):
986 for Package
in Pa
.PackageList
:
987 # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType
988 if (Pcd
[0], Pcd
[1], PcdType
) in Package
.Pcds
:
990 for Type
in PcdTypeList
:
991 if (Pcd
[0], Pcd
[1], Type
) in Package
.Pcds
:
995 "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \
996 % (Pa
.Platform
.Pcds
[Pcd
].Type
, Pcd
[1], Pcd
[0], Type
),
1001 UnusedPcd
.setdefault(Pcd
, []).append(Pa
.Arch
)
1003 for Pcd
in UnusedPcd
:
1006 "The PCD was not specified by any INF module in the platform for the given architecture.\n"
1007 "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"
1008 % (Pcd
[1], Pcd
[0], os
.path
.basename(str(self
.MetaFile
)), str(UnusedPcd
[Pcd
])),
1013 return "%s [%s]" % (self
.MetaFile
, ", ".join(self
.ArchList
))
1015 ## Return the directory to store FV files
1016 def _GetFvDir(self
):
1017 if self
._FvDir
== None:
1018 self
._FvDir
= path
.join(self
.BuildDir
, 'FV')
1021 ## Return the directory to store all intermediate and final files built
1022 def _GetBuildDir(self
):
1023 if self
._BuildDir
== None:
1024 return self
.AutoGenObjectList
[0].BuildDir
1026 ## Return the build output directory platform specifies
1027 def _GetOutputDir(self
):
1028 return self
.Platform
.OutputDirectory
1030 ## Return platform name
1032 return self
.Platform
.PlatformName
1034 ## Return meta-file GUID
1036 return self
.Platform
.Guid
1038 ## Return platform version
1039 def _GetVersion(self
):
1040 return self
.Platform
.Version
1042 ## Return paths of tools
1043 def _GetToolDefinition(self
):
1044 return self
.AutoGenObjectList
[0].ToolDefinition
1046 ## Return directory of platform makefile
1048 # @retval string Makefile directory
1050 def _GetMakeFileDir(self
):
1051 if self
._MakeFileDir
== None:
1052 self
._MakeFileDir
= self
.BuildDir
1053 return self
._MakeFileDir
1055 ## Return build command string
1057 # @retval string Build command string
1059 def _GetBuildCommand(self
):
1060 if self
._BuildCommand
== None:
1061 # BuildCommand should be all the same. So just get one from platform AutoGen
1062 self
._BuildCommand
= self
.AutoGenObjectList
[0].BuildCommand
1063 return self
._BuildCommand
1065 ## Check the PCDs token value conflict in each DEC file.
1067 # Will cause build break and raise error message while two PCDs conflict.
1071 def _CheckAllPcdsTokenValueConflict(self
):
1072 for Pa
in self
.AutoGenObjectList
:
1073 for Package
in Pa
.PackageList
:
1074 PcdList
= Package
.Pcds
.values()
1075 PcdList
.sort(lambda x
, y
: cmp(int(x
.TokenValue
, 0), int(y
.TokenValue
, 0)))
1077 while (Count
< len(PcdList
) - 1) :
1078 Item
= PcdList
[Count
]
1079 ItemNext
= PcdList
[Count
+ 1]
1081 # Make sure in the same token space the TokenValue should be unique
1083 if (int(Item
.TokenValue
, 0) == int(ItemNext
.TokenValue
, 0)):
1084 SameTokenValuePcdList
= []
1085 SameTokenValuePcdList
.append(Item
)
1086 SameTokenValuePcdList
.append(ItemNext
)
1087 RemainPcdListLength
= len(PcdList
) - Count
- 2
1088 for ValueSameCount
in range(RemainPcdListLength
):
1089 if int(PcdList
[len(PcdList
) - RemainPcdListLength
+ ValueSameCount
].TokenValue
, 0) == int(Item
.TokenValue
, 0):
1090 SameTokenValuePcdList
.append(PcdList
[len(PcdList
) - RemainPcdListLength
+ ValueSameCount
])
1094 # Sort same token value PCD list with TokenGuid and TokenCName
1096 SameTokenValuePcdList
.sort(lambda x
, y
: cmp("%s.%s" % (x
.TokenSpaceGuidCName
, x
.TokenCName
), "%s.%s" % (y
.TokenSpaceGuidCName
, y
.TokenCName
)))
1097 SameTokenValuePcdListCount
= 0
1098 while (SameTokenValuePcdListCount
< len(SameTokenValuePcdList
) - 1):
1100 TemListItem
= SameTokenValuePcdList
[SameTokenValuePcdListCount
]
1101 TemListItemNext
= SameTokenValuePcdList
[SameTokenValuePcdListCount
+ 1]
1103 if (TemListItem
.TokenSpaceGuidCName
== TemListItemNext
.TokenSpaceGuidCName
) and (TemListItem
.TokenCName
!= TemListItemNext
.TokenCName
):
1104 for PcdItem
in GlobalData
.MixedPcd
:
1105 if (TemListItem
.TokenCName
, TemListItem
.TokenSpaceGuidCName
) in GlobalData
.MixedPcd
[PcdItem
] or \
1106 (TemListItemNext
.TokenCName
, TemListItemNext
.TokenSpaceGuidCName
) in GlobalData
.MixedPcd
[PcdItem
]:
1112 "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\
1113 % (TemListItem
.TokenValue
, TemListItem
.TokenSpaceGuidCName
, TemListItem
.TokenCName
, TemListItemNext
.TokenSpaceGuidCName
, TemListItemNext
.TokenCName
, Package
),
1116 SameTokenValuePcdListCount
+= 1
1117 Count
+= SameTokenValuePcdListCount
1120 PcdList
= Package
.Pcds
.values()
1121 PcdList
.sort(lambda x
, y
: cmp("%s.%s" % (x
.TokenSpaceGuidCName
, x
.TokenCName
), "%s.%s" % (y
.TokenSpaceGuidCName
, y
.TokenCName
)))
1123 while (Count
< len(PcdList
) - 1) :
1124 Item
= PcdList
[Count
]
1125 ItemNext
= PcdList
[Count
+ 1]
1127 # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.
1129 if (Item
.TokenSpaceGuidCName
== ItemNext
.TokenSpaceGuidCName
) and (Item
.TokenCName
== ItemNext
.TokenCName
) and (int(Item
.TokenValue
, 0) != int(ItemNext
.TokenValue
, 0)):
1133 "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\
1134 % (Item
.TokenValue
, Item
.TokenSpaceGuidCName
, Item
.TokenCName
, Package
),
1138 ## Generate fds command
1139 def _GenFdsCommand(self
):
1140 return (GenMake
.TopLevelMakefile(self
)._TEMPLATE
_.Replace(GenMake
.TopLevelMakefile(self
)._TemplateDict
)).strip()
1142 ## Create makefile for the platform and modules in it
1144 # @param CreateDepsMakeFile Flag indicating if the makefile for
1145 # modules will be created as well
1147 def CreateMakeFile(self
, CreateDepsMakeFile
=False):
1148 if CreateDepsMakeFile
:
1149 for Pa
in self
.AutoGenObjectList
:
1150 Pa
.CreateMakeFile(CreateDepsMakeFile
)
1152 ## Create autogen code for platform and modules
1154 # Since there's no autogen code for platform, this method will do nothing
1155 # if CreateModuleCodeFile is set to False.
1157 # @param CreateDepsCodeFile Flag indicating if creating module's
1158 # autogen code file or not
1160 def CreateCodeFile(self
, CreateDepsCodeFile
=False):
1161 if not CreateDepsCodeFile
:
1163 for Pa
in self
.AutoGenObjectList
:
1164 Pa
.CreateCodeFile(CreateDepsCodeFile
)
1166 ## Create AsBuilt INF file the platform
1168 def CreateAsBuiltInf(self
):
1171 Name
= property(_GetName
)
1172 Guid
= property(_GetGuid
)
1173 Version
= property(_GetVersion
)
1174 OutputDir
= property(_GetOutputDir
)
1176 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
1178 BuildDir
= property(_GetBuildDir
)
1179 FvDir
= property(_GetFvDir
)
1180 MakeFileDir
= property(_GetMakeFileDir
)
1181 BuildCommand
= property(_GetBuildCommand
)
1182 GenFdsCommand
= property(_GenFdsCommand
)
1184 ## AutoGen class for platform
1186 # PlatformAutoGen class will process the original information in platform
1187 # file in order to generate makefile for platform.
1189 class PlatformAutoGen(AutoGen
):
1191 # Used to store all PCDs for both PEI and DXE phase, in order to generate
1192 # correct PCD database
1195 _NonDynaPcdList_
= []
1199 # The priority list while override build option
1201 PrioList
= {"0x11111" : 16, # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)
1202 "0x01111" : 15, # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
1203 "0x10111" : 14, # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE
1204 "0x00111" : 13, # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE
1205 "0x11011" : 12, # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
1206 "0x01011" : 11, # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
1207 "0x10011" : 10, # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE
1208 "0x00011" : 9, # ******_*********_****_COMMANDTYPE_ATTRIBUTE
1209 "0x11101" : 8, # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE
1210 "0x01101" : 7, # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE
1211 "0x10101" : 6, # TARGET_*********_ARCH_***********_ATTRIBUTE
1212 "0x00101" : 5, # ******_*********_ARCH_***********_ATTRIBUTE
1213 "0x11001" : 4, # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE
1214 "0x01001" : 3, # ******_TOOLCHAIN_****_***********_ATTRIBUTE
1215 "0x10001" : 2, # TARGET_*********_****_***********_ATTRIBUTE
1216 "0x00001" : 1} # ******_*********_****_***********_ATTRIBUTE (Lowest)
1218 ## The real constructor of PlatformAutoGen
1220 # This method is not supposed to be called by users of PlatformAutoGen. It's
1221 # only used by factory method __new__() to do real initialization work for an
1222 # object of PlatformAutoGen
1224 # @param Workspace WorkspaceAutoGen object
1225 # @param PlatformFile Platform file (DSC file)
1226 # @param Target Build target (DEBUG, RELEASE)
1227 # @param Toolchain Name of tool chain
1228 # @param Arch arch of the platform supports
1230 def _Init(self
, Workspace
, PlatformFile
, Target
, Toolchain
, Arch
):
1231 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen platform [%s] [%s]" % (PlatformFile
, Arch
))
1232 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (PlatformFile
, Arch
, Toolchain
, Target
)
1234 self
.MetaFile
= PlatformFile
1235 self
.Workspace
= Workspace
1236 self
.WorkspaceDir
= Workspace
.WorkspaceDir
1237 self
.ToolChain
= Toolchain
1238 self
.BuildTarget
= Target
1240 self
.SourceDir
= PlatformFile
.SubDir
1241 self
.SourceOverrideDir
= None
1242 self
.FdTargetList
= self
.Workspace
.FdTargetList
1243 self
.FvTargetList
= self
.Workspace
.FvTargetList
1244 self
.AllPcdList
= []
1245 # get the original module/package/platform objects
1246 self
.BuildDatabase
= Workspace
.BuildDatabase
1247 self
.DscBuildDataObj
= Workspace
.Platform
1248 self
._GuidDict
= Workspace
._GuidDict
1250 # flag indicating if the makefile/C-code file has been created or not
1251 self
.IsMakeFileCreated
= False
1252 self
.IsCodeFileCreated
= False
1254 self
._Platform
= None
1257 self
._Version
= None
1259 self
._BuildRule
= None
1260 self
._SourceDir
= None
1261 self
._BuildDir
= None
1262 self
._OutputDir
= None
1264 self
._MakeFileDir
= None
1265 self
._FdfFile
= None
1267 self
._PcdTokenNumber
= None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
1268 self
._DynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1269 self
._NonDynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1270 self
._NonDynamicPcdDict
= {}
1272 self
._ToolDefinitions
= None
1273 self
._ToolDefFile
= None # toolcode : tool path
1274 self
._ToolChainFamily
= None
1275 self
._BuildRuleFamily
= None
1276 self
._BuildOption
= None # toolcode : option
1277 self
._EdkBuildOption
= None # edktoolcode : option
1278 self
._EdkIIBuildOption
= None # edkiitoolcode : option
1279 self
._PackageList
= None
1280 self
._ModuleAutoGenList
= None
1281 self
._LibraryAutoGenList
= None
1282 self
._BuildCommand
= None
1283 self
._AsBuildInfList
= []
1284 self
._AsBuildModuleList
= []
1286 self
.VariableInfo
= None
1288 if GlobalData
.gFdfParser
!= None:
1289 self
._AsBuildInfList
= GlobalData
.gFdfParser
.Profile
.InfList
1290 for Inf
in self
._AsBuildInfList
:
1291 InfClass
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, self
.Arch
)
1292 M
= self
.BuildDatabase
[InfClass
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
1293 if not M
.IsSupportedArch
:
1295 self
._AsBuildModuleList
.append(InfClass
)
1296 # get library/modules for build
1297 self
.LibraryBuildDirectoryList
= []
1298 self
.ModuleBuildDirectoryList
= []
1303 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
1305 ## Create autogen code for platform and modules
1307 # Since there's no autogen code for platform, this method will do nothing
1308 # if CreateModuleCodeFile is set to False.
1310 # @param CreateModuleCodeFile Flag indicating if creating module's
1311 # autogen code file or not
1313 def CreateCodeFile(self
, CreateModuleCodeFile
=False):
1314 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
1315 if self
.IsCodeFileCreated
or not CreateModuleCodeFile
:
1318 for Ma
in self
.ModuleAutoGenList
:
1319 Ma
.CreateCodeFile(True)
1321 # don't do this twice
1322 self
.IsCodeFileCreated
= True
1324 ## Generate Fds Command
1325 def _GenFdsCommand(self
):
1326 return self
.Workspace
.GenFdsCommand
1328 ## Create makefile for the platform and mdoules in it
1330 # @param CreateModuleMakeFile Flag indicating if the makefile for
1331 # modules will be created as well
1333 def CreateMakeFile(self
, CreateModuleMakeFile
=False, FfsCommand
= {}):
1334 if CreateModuleMakeFile
:
1335 for ModuleFile
in self
.Platform
.Modules
:
1336 Ma
= ModuleAutoGen(self
.Workspace
, ModuleFile
, self
.BuildTarget
,
1337 self
.ToolChain
, self
.Arch
, self
.MetaFile
)
1338 if (ModuleFile
.File
, self
.Arch
) in FfsCommand
:
1339 Ma
.CreateMakeFile(True, FfsCommand
[ModuleFile
.File
, self
.Arch
])
1341 Ma
.CreateMakeFile(True)
1342 #Ma.CreateAsBuiltInf()
1344 # no need to create makefile for the platform more than once
1345 if self
.IsMakeFileCreated
:
1348 # create library/module build dirs for platform
1349 Makefile
= GenMake
.PlatformMakefile(self
)
1350 self
.LibraryBuildDirectoryList
= Makefile
.GetLibraryBuildDirectoryList()
1351 self
.ModuleBuildDirectoryList
= Makefile
.GetModuleBuildDirectoryList()
1353 self
.IsMakeFileCreated
= True
1355 ## Deal with Shared FixedAtBuild Pcds
1357 def CollectFixedAtBuildPcds(self
):
1358 for LibAuto
in self
.LibraryAutoGenList
:
1359 FixedAtBuildPcds
= {}
1360 ShareFixedAtBuildPcdsSameValue
= {}
1361 for Module
in LibAuto
._ReferenceModules
:
1362 for Pcd
in Module
.FixedAtBuildPcds
+ LibAuto
.FixedAtBuildPcds
:
1363 key
= ".".join((Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
))
1364 if key
not in FixedAtBuildPcds
:
1365 ShareFixedAtBuildPcdsSameValue
[key
] = True
1366 FixedAtBuildPcds
[key
] = Pcd
.DefaultValue
1368 if FixedAtBuildPcds
[key
] != Pcd
.DefaultValue
:
1369 ShareFixedAtBuildPcdsSameValue
[key
] = False
1370 for Pcd
in LibAuto
.FixedAtBuildPcds
:
1371 key
= ".".join((Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
))
1372 if (Pcd
.TokenCName
,Pcd
.TokenSpaceGuidCName
) not in self
.NonDynamicPcdDict
:
1375 DscPcd
= self
.NonDynamicPcdDict
[(Pcd
.TokenCName
,Pcd
.TokenSpaceGuidCName
)]
1376 if DscPcd
.Type
!= "FixedAtBuild":
1378 if key
in ShareFixedAtBuildPcdsSameValue
and ShareFixedAtBuildPcdsSameValue
[key
]:
1379 LibAuto
.ConstPcd
[key
] = Pcd
.DefaultValue
1381 def CollectVariables(self
, DynamicPcdSet
):
1385 if self
.Workspace
.FdfFile
:
1386 FdDict
= self
.Workspace
.FdfProfile
.FdDict
[GlobalData
.gFdfParser
.CurrentFdName
]
1387 for FdRegion
in FdDict
.RegionList
:
1388 for item
in FdRegion
.RegionDataList
:
1389 if self
.Platform
.VpdToolGuid
.strip() and self
.Platform
.VpdToolGuid
in item
:
1390 VpdRegionSize
= FdRegion
.Size
1391 VpdRegionBase
= FdRegion
.Offset
1395 VariableInfo
= VariableMgr(self
.DscBuildDataObj
._GetDefaultStores
(),self
.DscBuildDataObj
._GetSkuIds
())
1396 VariableInfo
.SetVpdRegionMaxSize(VpdRegionSize
)
1397 VariableInfo
.SetVpdRegionOffset(VpdRegionBase
)
1399 for Pcd
in DynamicPcdSet
:
1400 pcdname
= ".".join((Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
))
1401 for SkuName
in Pcd
.SkuInfoList
:
1402 Sku
= Pcd
.SkuInfoList
[SkuName
]
1404 if SkuId
== None or SkuId
== '':
1406 if len(Sku
.VariableName
) > 0:
1407 VariableGuidStructure
= Sku
.VariableGuidValue
1408 VariableGuid
= GuidStructureStringToGuidString(VariableGuidStructure
)
1409 for StorageName
in Sku
.DefaultStoreDict
:
1410 VariableInfo
.append_variable(var_info(Index
,pcdname
,StorageName
,SkuName
, StringToArray(Sku
.VariableName
),VariableGuid
, Sku
.VariableOffset
, Sku
.VariableAttribute
, Sku
.HiiDefaultValue
,Sku
.DefaultStoreDict
[StorageName
],Pcd
.DatumType
))
1414 def UpdateNVStoreMaxSize(self
,OrgVpdFile
):
1415 if self
.VariableInfo
:
1416 VpdMapFilePath
= os
.path
.join(self
.BuildDir
, "FV", "%s.map" % self
.Platform
.VpdToolGuid
)
1417 PcdNvStoreDfBuffer
= [item
for item
in self
._DynamicPcdList
if item
.TokenCName
== "PcdNvStoreDefaultValueBuffer" and item
.TokenSpaceGuidCName
== "gEfiMdeModulePkgTokenSpaceGuid"]
1419 if PcdNvStoreDfBuffer
:
1420 if os
.path
.exists(VpdMapFilePath
):
1421 OrgVpdFile
.Read(VpdMapFilePath
)
1422 PcdItems
= OrgVpdFile
.GetOffset(PcdNvStoreDfBuffer
[0])
1423 NvStoreOffset
= PcdItems
.values()[0].strip() if PcdItems
else '0'
1425 EdkLogger
.error("build", FILE_READ_FAILURE
, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath
)
1427 NvStoreOffset
= int(NvStoreOffset
,16) if NvStoreOffset
.upper().startswith("0X") else int(NvStoreOffset
)
1428 default_skuobj
= PcdNvStoreDfBuffer
[0].SkuInfoList
.get("DEFAULT")
1429 maxsize
= self
.VariableInfo
.VpdRegionSize
- NvStoreOffset
if self
.VariableInfo
.VpdRegionSize
else len(default_skuobj
.DefaultValue
.split(","))
1430 var_data
= self
.VariableInfo
.PatchNVStoreDefaultMaxSize(maxsize
)
1432 if var_data
and default_skuobj
:
1433 default_skuobj
.DefaultValue
= var_data
1434 PcdNvStoreDfBuffer
[0].DefaultValue
= var_data
1435 PcdNvStoreDfBuffer
[0].SkuInfoList
.clear()
1436 PcdNvStoreDfBuffer
[0].SkuInfoList
['DEFAULT'] = default_skuobj
1437 PcdNvStoreDfBuffer
[0].MaxDatumSize
= str(len(default_skuobj
.DefaultValue
.split(",")))
1441 ## Collect dynamic PCDs
1443 # Gather dynamic PCDs list from each module and their settings from platform
1444 # This interface should be invoked explicitly when platform action is created.
1446 def CollectPlatformDynamicPcds(self
):
1447 # Override the platform Pcd's value by build option
1448 if GlobalData
.BuildOptionPcd
:
1449 for key
in self
.Platform
.Pcds
:
1450 PlatformPcd
= self
.Platform
.Pcds
[key
]
1451 for PcdItem
in GlobalData
.BuildOptionPcd
:
1452 if (PlatformPcd
.TokenSpaceGuidCName
, PlatformPcd
.TokenCName
) == (PcdItem
[0], PcdItem
[1]):
1453 PlatformPcd
.DefaultValue
= PcdItem
[2]
1454 if PlatformPcd
.SkuInfoList
:
1455 Sku
= PlatformPcd
.SkuInfoList
[PlatformPcd
.SkuInfoList
.keys()[0]]
1456 Sku
.DefaultValue
= PcdItem
[2]
1459 for key
in self
.Platform
.Pcds
:
1460 for SinglePcd
in GlobalData
.MixedPcd
:
1461 if (self
.Platform
.Pcds
[key
].TokenCName
, self
.Platform
.Pcds
[key
].TokenSpaceGuidCName
) == SinglePcd
:
1462 for item
in GlobalData
.MixedPcd
[SinglePcd
]:
1463 Pcd_Type
= item
[0].split('_')[-1]
1464 if (Pcd_Type
== self
.Platform
.Pcds
[key
].Type
) or (Pcd_Type
== TAB_PCDS_DYNAMIC_EX
and self
.Platform
.Pcds
[key
].Type
in GenC
.gDynamicExPcd
) or \
1465 (Pcd_Type
== TAB_PCDS_DYNAMIC
and self
.Platform
.Pcds
[key
].Type
in GenC
.gDynamicPcd
):
1466 Value
= self
.Platform
.Pcds
[key
]
1467 Value
.TokenCName
= self
.Platform
.Pcds
[key
].TokenCName
+ '_' + Pcd_Type
1469 newkey
= (Value
.TokenCName
, key
[1])
1471 newkey
= (Value
.TokenCName
, key
[1], key
[2])
1472 del self
.Platform
.Pcds
[key
]
1473 self
.Platform
.Pcds
[newkey
] = Value
1481 # for gathering error information
1482 NoDatumTypePcdList
= set()
1484 self
._GuidValue
= {}
1486 for InfName
in self
._AsBuildInfList
:
1487 InfName
= mws
.join(self
.WorkspaceDir
, InfName
)
1488 FdfModuleList
.append(os
.path
.normpath(InfName
))
1489 for F
in self
.Platform
.Modules
.keys():
1490 M
= ModuleAutoGen(self
.Workspace
, F
, self
.BuildTarget
, self
.ToolChain
, self
.Arch
, self
.MetaFile
)
1491 #GuidValue.update(M.Guids)
1493 self
.Platform
.Modules
[F
].M
= M
1495 for PcdFromModule
in M
.ModulePcdList
+ M
.LibraryPcdList
:
1496 # make sure that the "VOID*" kind of datum has MaxDatumSize set
1497 if PcdFromModule
.DatumType
== "VOID*" and PcdFromModule
.MaxDatumSize
in [None, '']:
1498 NoDatumTypePcdList
.add("%s.%s [%s]" % (PcdFromModule
.TokenSpaceGuidCName
, PcdFromModule
.TokenCName
, F
))
1500 # Check the PCD from Binary INF or Source INF
1501 if M
.IsBinaryModule
== True:
1502 PcdFromModule
.IsFromBinaryInf
= True
1504 # Check the PCD from DSC or not
1505 if (PcdFromModule
.TokenCName
, PcdFromModule
.TokenSpaceGuidCName
) in self
.Platform
.Pcds
.keys():
1506 PcdFromModule
.IsFromDsc
= True
1508 PcdFromModule
.IsFromDsc
= False
1509 if PcdFromModule
.Type
in GenC
.gDynamicPcd
or PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
1510 if F
.Path
not in FdfModuleList
:
1511 # If one of the Source built modules listed in the DSC is not listed
1512 # in FDF modules, and the INF lists a PCD can only use the PcdsDynamic
1513 # access method (it is only listed in the DEC file that declares the
1514 # PCD as PcdsDynamic), then build tool will report warning message
1515 # notify the PI that they are attempting to build a module that must
1516 # be included in a flash image in order to be functional. These Dynamic
1517 # PCD will not be added into the Database unless it is used by other
1518 # modules that are included in the FDF file.
1519 if PcdFromModule
.Type
in GenC
.gDynamicPcd
and \
1520 PcdFromModule
.IsFromBinaryInf
== False:
1521 # Print warning message to let the developer make a determine.
1522 if PcdFromModule
not in PcdNotInDb
:
1523 PcdNotInDb
.append(PcdFromModule
)
1525 # If one of the Source built modules listed in the DSC is not listed in
1526 # FDF modules, and the INF lists a PCD can only use the PcdsDynamicEx
1527 # access method (it is only listed in the DEC file that declares the
1528 # PCD as PcdsDynamicEx), then DO NOT break the build; DO NOT add the
1529 # PCD to the Platform's PCD Database.
1530 if PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
1531 if PcdFromModule
not in PcdNotInDb
:
1532 PcdNotInDb
.append(PcdFromModule
)
1535 # If a dynamic PCD used by a PEM module/PEI module & DXE module,
1536 # it should be stored in Pcd PEI database, If a dynamic only
1537 # used by DXE module, it should be stored in DXE PCD database.
1538 # The default Phase is DXE
1540 if M
.ModuleType
in ["PEIM", "PEI_CORE"]:
1541 PcdFromModule
.Phase
= "PEI"
1542 if PcdFromModule
not in self
._DynaPcdList
_:
1543 self
._DynaPcdList
_.append(PcdFromModule
)
1544 elif PcdFromModule
.Phase
== 'PEI':
1545 # overwrite any the same PCD existing, if Phase is PEI
1546 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
1547 self
._DynaPcdList
_[Index
] = PcdFromModule
1548 elif PcdFromModule
not in self
._NonDynaPcdList
_:
1549 self
._NonDynaPcdList
_.append(PcdFromModule
)
1550 elif PcdFromModule
in self
._NonDynaPcdList
_ and PcdFromModule
.IsFromBinaryInf
== True:
1551 Index
= self
._NonDynaPcdList
_.index(PcdFromModule
)
1552 if self
._NonDynaPcdList
_[Index
].IsFromBinaryInf
== False:
1553 #The PCD from Binary INF will override the same one from source INF
1554 self
._NonDynaPcdList
_.remove (self
._NonDynaPcdList
_[Index
])
1555 PcdFromModule
.Pending
= False
1556 self
._NonDynaPcdList
_.append (PcdFromModule
)
1557 # Parse the DynamicEx PCD from the AsBuild INF module list of FDF.
1559 for ModuleInf
in self
.Platform
.Modules
.keys():
1560 DscModuleList
.append (os
.path
.normpath(ModuleInf
.Path
))
1561 # add the PCD from modules that listed in FDF but not in DSC to Database
1562 for InfName
in FdfModuleList
:
1563 if InfName
not in DscModuleList
:
1564 InfClass
= PathClass(InfName
)
1565 M
= self
.BuildDatabase
[InfClass
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
1566 # If a module INF in FDF but not in current arch's DSC module list, it must be module (either binary or source)
1567 # for different Arch. PCDs in source module for different Arch is already added before, so skip the source module here.
1568 # For binary module, if in current arch, we need to list the PCDs into database.
1569 if not M
.IsSupportedArch
:
1571 # Override the module PCD setting by platform setting
1572 ModulePcdList
= self
.ApplyPcdSetting(M
, M
.Pcds
)
1573 for PcdFromModule
in ModulePcdList
:
1574 PcdFromModule
.IsFromBinaryInf
= True
1575 PcdFromModule
.IsFromDsc
= False
1576 # Only allow the DynamicEx and Patchable PCD in AsBuild INF
1577 if PcdFromModule
.Type
not in GenC
.gDynamicExPcd
and PcdFromModule
.Type
not in TAB_PCDS_PATCHABLE_IN_MODULE
:
1578 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
1580 ExtraData
="\n\tExisted %s PCD %s in:\n\t\t%s\n"
1581 % (PcdFromModule
.Type
, PcdFromModule
.TokenCName
, InfName
))
1582 # make sure that the "VOID*" kind of datum has MaxDatumSize set
1583 if PcdFromModule
.DatumType
== "VOID*" and PcdFromModule
.MaxDatumSize
in [None, '']:
1584 NoDatumTypePcdList
.add("%s.%s [%s]" % (PcdFromModule
.TokenSpaceGuidCName
, PcdFromModule
.TokenCName
, InfName
))
1585 if M
.ModuleType
in ["PEIM", "PEI_CORE"]:
1586 PcdFromModule
.Phase
= "PEI"
1587 if PcdFromModule
not in self
._DynaPcdList
_ and PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
1588 self
._DynaPcdList
_.append(PcdFromModule
)
1589 elif PcdFromModule
not in self
._NonDynaPcdList
_ and PcdFromModule
.Type
in TAB_PCDS_PATCHABLE_IN_MODULE
:
1590 self
._NonDynaPcdList
_.append(PcdFromModule
)
1591 if PcdFromModule
in self
._DynaPcdList
_ and PcdFromModule
.Phase
== 'PEI' and PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
1592 # Overwrite the phase of any the same PCD existing, if Phase is PEI.
1593 # It is to solve the case that a dynamic PCD used by a PEM module/PEI
1594 # module & DXE module at a same time.
1595 # Overwrite the type of the PCDs in source INF by the type of AsBuild
1596 # INF file as DynamicEx.
1597 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
1598 self
._DynaPcdList
_[Index
].Phase
= PcdFromModule
.Phase
1599 self
._DynaPcdList
_[Index
].Type
= PcdFromModule
.Type
1600 for PcdFromModule
in self
._NonDynaPcdList
_:
1601 # If a PCD is not listed in the DSC file, but binary INF files used by
1602 # this platform all (that use this PCD) list the PCD in a [PatchPcds]
1603 # section, AND all source INF files used by this platform the build
1604 # that use the PCD list the PCD in either a [Pcds] or [PatchPcds]
1605 # section, then the tools must NOT add the PCD to the Platform's PCD
1606 # Database; the build must assign the access method for this PCD as
1607 # PcdsPatchableInModule.
1608 if PcdFromModule
not in self
._DynaPcdList
_:
1610 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
1611 if PcdFromModule
.IsFromDsc
== False and \
1612 PcdFromModule
.Type
in TAB_PCDS_PATCHABLE_IN_MODULE
and \
1613 PcdFromModule
.IsFromBinaryInf
== True and \
1614 self
._DynaPcdList
_[Index
].IsFromBinaryInf
== False:
1615 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
1616 self
._DynaPcdList
_.remove (self
._DynaPcdList
_[Index
])
1618 # print out error information and break the build, if error found
1619 if len(NoDatumTypePcdList
) > 0:
1620 NoDatumTypePcdListString
= "\n\t\t".join(NoDatumTypePcdList
)
1621 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
1623 ExtraData
="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
1624 % NoDatumTypePcdListString
)
1625 self
._NonDynamicPcdList
= self
._NonDynaPcdList
_
1626 self
._DynamicPcdList
= self
._DynaPcdList
_
1628 # Sort dynamic PCD list to:
1629 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should
1630 # try to be put header of dynamicd List
1631 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD
1633 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
1635 UnicodePcdArray
= set()
1637 OtherPcdArray
= set()
1639 VpdFile
= VpdInfoFile
.VpdInfoFile()
1640 NeedProcessVpdMapFile
= False
1642 for pcd
in self
.Platform
.Pcds
.keys():
1643 if pcd
not in self
._PlatformPcds
.keys():
1644 self
._PlatformPcds
[pcd
] = self
.Platform
.Pcds
[pcd
]
1646 for item
in self
._PlatformPcds
:
1647 if self
._PlatformPcds
[item
].DatumType
and self
._PlatformPcds
[item
].DatumType
not in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
, TAB_VOID
, "BOOLEAN"]:
1648 self
._PlatformPcds
[item
].DatumType
= "VOID*"
1650 if (self
.Workspace
.ArchList
[-1] == self
.Arch
):
1651 for Pcd
in self
._DynamicPcdList
:
1652 # just pick the a value to determine whether is unicode string type
1653 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
1654 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
1656 if Pcd
.DatumType
not in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
, TAB_VOID
, "BOOLEAN"]:
1657 Pcd
.DatumType
= "VOID*"
1659 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
1660 # if found HII type PCD then insert to right of UnicodeIndex
1661 if Pcd
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
]:
1662 VpdPcdDict
[(Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
)] = Pcd
1664 #Collect DynamicHii PCD values and assign it to DynamicExVpd PCD gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer
1665 PcdNvStoreDfBuffer
= VpdPcdDict
.get(("PcdNvStoreDefaultValueBuffer","gEfiMdeModulePkgTokenSpaceGuid"))
1666 if PcdNvStoreDfBuffer
:
1667 self
.VariableInfo
= self
.CollectVariables(self
._DynamicPcdList
)
1668 vardump
= self
.VariableInfo
.dump()
1670 PcdNvStoreDfBuffer
.DefaultValue
= vardump
1671 for skuname
in PcdNvStoreDfBuffer
.SkuInfoList
:
1672 PcdNvStoreDfBuffer
.SkuInfoList
[skuname
].DefaultValue
= vardump
1673 PcdNvStoreDfBuffer
.MaxDatumSize
= str(len(vardump
.split(",")))
1675 PlatformPcds
= self
._PlatformPcds
.keys()
1678 # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.
1681 for PcdKey
in PlatformPcds
:
1682 Pcd
= self
._PlatformPcds
[PcdKey
]
1683 if Pcd
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
] and \
1684 PcdKey
in VpdPcdDict
:
1685 Pcd
= VpdPcdDict
[PcdKey
]
1687 DefaultSku
= Pcd
.SkuInfoList
.get('DEFAULT')
1689 PcdValue
= DefaultSku
.DefaultValue
1690 if PcdValue
not in SkuValueMap
:
1691 SkuValueMap
[PcdValue
] = []
1692 VpdFile
.Add(Pcd
, 'DEFAULT',DefaultSku
.VpdOffset
)
1693 SkuValueMap
[PcdValue
].append(DefaultSku
)
1695 for (SkuName
,Sku
) in Pcd
.SkuInfoList
.items():
1696 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
1697 PcdValue
= Sku
.DefaultValue
1699 PcdValue
= Pcd
.DefaultValue
1700 if Sku
.VpdOffset
!= '*':
1701 if PcdValue
.startswith("{"):
1703 elif PcdValue
.startswith("L"):
1708 VpdOffset
= int(Sku
.VpdOffset
)
1711 VpdOffset
= int(Sku
.VpdOffset
, 16)
1713 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid offset value %s for PCD %s.%s." % (Sku
.VpdOffset
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
1714 if VpdOffset
% Alignment
!= 0:
1715 if PcdValue
.startswith("{"):
1716 EdkLogger
.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
), File
=self
.MetaFile
)
1718 EdkLogger
.error("build", FORMAT_INVALID
, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Alignment
))
1719 if PcdValue
not in SkuValueMap
:
1720 SkuValueMap
[PcdValue
] = []
1721 VpdFile
.Add(Pcd
, SkuName
,Sku
.VpdOffset
)
1722 SkuValueMap
[PcdValue
].append(Sku
)
1723 # if the offset of a VPD is *, then it need to be fixed up by third party tool.
1724 if not NeedProcessVpdMapFile
and Sku
.VpdOffset
== "*":
1725 NeedProcessVpdMapFile
= True
1726 if self
.Platform
.VpdToolGuid
== None or self
.Platform
.VpdToolGuid
== '':
1727 EdkLogger
.error("Build", FILE_NOT_FOUND
, \
1728 "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
1730 VpdSkuMap
[PcdKey
] = SkuValueMap
1732 # Fix the PCDs define in VPD PCD section that never referenced by module.
1733 # An example is PCD for signature usage.
1735 for DscPcd
in PlatformPcds
:
1736 DscPcdEntry
= self
._PlatformPcds
[DscPcd
]
1737 if DscPcdEntry
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
]:
1738 if not (self
.Platform
.VpdToolGuid
== None or self
.Platform
.VpdToolGuid
== ''):
1740 for VpdPcd
in VpdFile
._VpdArray
.keys():
1741 # This PCD has been referenced by module
1742 if (VpdPcd
.TokenSpaceGuidCName
== DscPcdEntry
.TokenSpaceGuidCName
) and \
1743 (VpdPcd
.TokenCName
== DscPcdEntry
.TokenCName
):
1746 # Not found, it should be signature
1748 # just pick the a value to determine whether is unicode string type
1750 SkuObjList
= DscPcdEntry
.SkuInfoList
.items()
1751 DefaultSku
= DscPcdEntry
.SkuInfoList
.get('DEFAULT')
1753 defaultindex
= SkuObjList
.index(('DEFAULT',DefaultSku
))
1754 SkuObjList
[0],SkuObjList
[defaultindex
] = SkuObjList
[defaultindex
],SkuObjList
[0]
1755 for (SkuName
,Sku
) in SkuObjList
:
1756 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
1758 # Need to iterate DEC pcd information to get the value & datumtype
1759 for eachDec
in self
.PackageList
:
1760 for DecPcd
in eachDec
.Pcds
:
1761 DecPcdEntry
= eachDec
.Pcds
[DecPcd
]
1762 if (DecPcdEntry
.TokenSpaceGuidCName
== DscPcdEntry
.TokenSpaceGuidCName
) and \
1763 (DecPcdEntry
.TokenCName
== DscPcdEntry
.TokenCName
):
1764 # Print warning message to let the developer make a determine.
1765 EdkLogger
.warn("build", "Unreferenced vpd pcd used!",
1766 File
=self
.MetaFile
, \
1767 ExtraData
= "PCD: %s.%s used in the DSC file %s is unreferenced." \
1768 %(DscPcdEntry
.TokenSpaceGuidCName
, DscPcdEntry
.TokenCName
, self
.Platform
.MetaFile
.Path
))
1770 DscPcdEntry
.DatumType
= DecPcdEntry
.DatumType
1771 DscPcdEntry
.DefaultValue
= DecPcdEntry
.DefaultValue
1772 DscPcdEntry
.TokenValue
= DecPcdEntry
.TokenValue
1773 DscPcdEntry
.TokenSpaceGuidValue
= eachDec
.Guids
[DecPcdEntry
.TokenSpaceGuidCName
]
1774 # Only fix the value while no value provided in DSC file.
1775 if (Sku
.DefaultValue
== "" or Sku
.DefaultValue
==None):
1776 DscPcdEntry
.SkuInfoList
[DscPcdEntry
.SkuInfoList
.keys()[0]].DefaultValue
= DecPcdEntry
.DefaultValue
1778 if DscPcdEntry
not in self
._DynamicPcdList
:
1779 self
._DynamicPcdList
.append(DscPcdEntry
)
1780 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
1781 PcdValue
= Sku
.DefaultValue
1783 PcdValue
= DscPcdEntry
.DefaultValue
1784 if Sku
.VpdOffset
!= '*':
1785 if PcdValue
.startswith("{"):
1787 elif PcdValue
.startswith("L"):
1792 VpdOffset
= int(Sku
.VpdOffset
)
1795 VpdOffset
= int(Sku
.VpdOffset
, 16)
1797 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid offset value %s for PCD %s.%s." % (Sku
.VpdOffset
, DscPcdEntry
.TokenSpaceGuidCName
, DscPcdEntry
.TokenCName
))
1798 if VpdOffset
% Alignment
!= 0:
1799 if PcdValue
.startswith("{"):
1800 EdkLogger
.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(DscPcdEntry
.TokenSpaceGuidCName
, DscPcdEntry
.TokenCName
), File
=self
.MetaFile
)
1802 EdkLogger
.error("build", FORMAT_INVALID
, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (DscPcdEntry
.TokenSpaceGuidCName
, DscPcdEntry
.TokenCName
, Alignment
))
1803 if PcdValue
not in SkuValueMap
:
1804 SkuValueMap
[PcdValue
] = []
1805 VpdFile
.Add(DscPcdEntry
, SkuName
,Sku
.VpdOffset
)
1806 SkuValueMap
[PcdValue
].append(Sku
)
1807 if not NeedProcessVpdMapFile
and Sku
.VpdOffset
== "*":
1808 NeedProcessVpdMapFile
= True
1809 if DscPcdEntry
.DatumType
== 'VOID*' and PcdValue
.startswith("L"):
1810 UnicodePcdArray
.add(DscPcdEntry
)
1811 elif len(Sku
.VariableName
) > 0:
1812 HiiPcdArray
.add(DscPcdEntry
)
1814 OtherPcdArray
.add(DscPcdEntry
)
1816 # if the offset of a VPD is *, then it need to be fixed up by third party tool.
1817 VpdSkuMap
[DscPcd
] = SkuValueMap
1818 if (self
.Platform
.FlashDefinition
== None or self
.Platform
.FlashDefinition
== '') and \
1819 VpdFile
.GetCount() != 0:
1820 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1821 "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self
.Platform
.MetaFile
))
1823 if VpdFile
.GetCount() != 0:
1825 self
.FixVpdOffset(VpdFile
)
1827 self
.FixVpdOffset(self
.UpdateNVStoreMaxSize(VpdFile
))
1829 # Process VPD map file generated by third party BPDG tool
1830 if NeedProcessVpdMapFile
:
1831 VpdMapFilePath
= os
.path
.join(self
.BuildDir
, "FV", "%s.map" % self
.Platform
.VpdToolGuid
)
1832 if os
.path
.exists(VpdMapFilePath
):
1833 VpdFile
.Read(VpdMapFilePath
)
1836 for pcd
in VpdSkuMap
:
1837 vpdinfo
= VpdFile
.GetVpdInfo(pcd
)
1839 # just pick the a value to determine whether is unicode string type
1841 for pcdvalue
in VpdSkuMap
[pcd
]:
1842 for sku
in VpdSkuMap
[pcd
][pcdvalue
]:
1843 for item
in vpdinfo
:
1844 if item
[2] == pcdvalue
:
1845 sku
.VpdOffset
= item
[1]
1847 EdkLogger
.error("build", FILE_READ_FAILURE
, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath
)
1849 # Delete the DynamicPcdList At the last time enter into this function
1850 for Pcd
in self
._DynamicPcdList
:
1851 # just pick the a value to determine whether is unicode string type
1852 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
1853 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
1855 if Pcd
.DatumType
not in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
, TAB_VOID
, "BOOLEAN"]:
1856 Pcd
.DatumType
= "VOID*"
1858 PcdValue
= Sku
.DefaultValue
1859 if Pcd
.DatumType
== 'VOID*' and PcdValue
.startswith("L"):
1860 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
1861 UnicodePcdArray
.add(Pcd
)
1862 elif len(Sku
.VariableName
) > 0:
1863 # if found HII type PCD then insert to right of UnicodeIndex
1864 HiiPcdArray
.add(Pcd
)
1866 OtherPcdArray
.add(Pcd
)
1867 del self
._DynamicPcdList
[:]
1868 self
._DynamicPcdList
.extend(list(UnicodePcdArray
))
1869 self
._DynamicPcdList
.extend(list(HiiPcdArray
))
1870 self
._DynamicPcdList
.extend(list(OtherPcdArray
))
1871 allskuset
= [(SkuName
,Sku
.SkuId
) for pcd
in self
._DynamicPcdList
for (SkuName
,Sku
) in pcd
.SkuInfoList
.items()]
1872 for pcd
in self
._DynamicPcdList
:
1873 if len(pcd
.SkuInfoList
) == 1:
1874 for (SkuName
,SkuId
) in allskuset
:
1875 if type(SkuId
) in (str,unicode) and eval(SkuId
) == 0 or SkuId
== 0:
1877 pcd
.SkuInfoList
[SkuName
] = copy
.deepcopy(pcd
.SkuInfoList
['DEFAULT'])
1878 pcd
.SkuInfoList
[SkuName
].SkuId
= SkuId
1879 self
.AllPcdList
= self
._NonDynamicPcdList
+ self
._DynamicPcdList
1881 def FixVpdOffset(self
,VpdFile
):
1882 FvPath
= os
.path
.join(self
.BuildDir
, "FV")
1883 if not os
.path
.exists(FvPath
):
1887 EdkLogger
.error("build", FILE_WRITE_FAILURE
, "Fail to create FV folder under %s" % self
.BuildDir
)
1889 VpdFilePath
= os
.path
.join(FvPath
, "%s.txt" % self
.Platform
.VpdToolGuid
)
1891 if VpdFile
.Write(VpdFilePath
):
1892 # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.
1894 for ToolDef
in self
.ToolDefinition
.values():
1895 if ToolDef
.has_key("GUID") and ToolDef
["GUID"] == self
.Platform
.VpdToolGuid
:
1896 if not ToolDef
.has_key("PATH"):
1897 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self
.Platform
.VpdToolGuid
)
1898 BPDGToolName
= ToolDef
["PATH"]
1900 # Call third party GUID BPDG tool.
1901 if BPDGToolName
!= None:
1902 VpdInfoFile
.CallExtenalBPDGTool(BPDGToolName
, VpdFilePath
)
1904 EdkLogger
.error("Build", FILE_NOT_FOUND
, "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
1906 ## Return the platform build data object
1907 def _GetPlatform(self
):
1908 if self
._Platform
== None:
1909 self
._Platform
= self
.BuildDatabase
[self
.MetaFile
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
1910 return self
._Platform
1912 ## Return platform name
1914 return self
.Platform
.PlatformName
1916 ## Return the meta file GUID
1918 return self
.Platform
.Guid
1920 ## Return the platform version
1921 def _GetVersion(self
):
1922 return self
.Platform
.Version
1924 ## Return the FDF file name
1925 def _GetFdfFile(self
):
1926 if self
._FdfFile
== None:
1927 if self
.Workspace
.FdfFile
!= "":
1928 self
._FdfFile
= mws
.join(self
.WorkspaceDir
, self
.Workspace
.FdfFile
)
1931 return self
._FdfFile
1933 ## Return the build output directory platform specifies
1934 def _GetOutputDir(self
):
1935 return self
.Platform
.OutputDirectory
1937 ## Return the directory to store all intermediate and final files built
1938 def _GetBuildDir(self
):
1939 if self
._BuildDir
== None:
1940 if os
.path
.isabs(self
.OutputDir
):
1941 self
._BuildDir
= path
.join(
1942 path
.abspath(self
.OutputDir
),
1943 self
.BuildTarget
+ "_" + self
.ToolChain
,
1946 self
._BuildDir
= path
.join(
1949 self
.BuildTarget
+ "_" + self
.ToolChain
,
1951 GlobalData
.gBuildDirectory
= self
._BuildDir
1952 return self
._BuildDir
1954 ## Return directory of platform makefile
1956 # @retval string Makefile directory
1958 def _GetMakeFileDir(self
):
1959 if self
._MakeFileDir
== None:
1960 self
._MakeFileDir
= path
.join(self
.BuildDir
, self
.Arch
)
1961 return self
._MakeFileDir
1963 ## Return build command string
1965 # @retval string Build command string
1967 def _GetBuildCommand(self
):
1968 if self
._BuildCommand
== None:
1969 self
._BuildCommand
= []
1970 if "MAKE" in self
.ToolDefinition
and "PATH" in self
.ToolDefinition
["MAKE"]:
1971 self
._BuildCommand
+= SplitOption(self
.ToolDefinition
["MAKE"]["PATH"])
1972 if "FLAGS" in self
.ToolDefinition
["MAKE"]:
1973 NewOption
= self
.ToolDefinition
["MAKE"]["FLAGS"].strip()
1975 self
._BuildCommand
+= SplitOption(NewOption
)
1976 return self
._BuildCommand
1978 ## Get tool chain definition
1980 # Get each tool defition for given tool chain from tools_def.txt and platform
1982 def _GetToolDefinition(self
):
1983 if self
._ToolDefinitions
== None:
1984 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDictionary
1985 if TAB_TOD_DEFINES_COMMAND_TYPE
not in self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
:
1986 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No tools found in configuration",
1987 ExtraData
="[%s]" % self
.MetaFile
)
1988 self
._ToolDefinitions
= {}
1990 for Def
in ToolDefinition
:
1991 Target
, Tag
, Arch
, Tool
, Attr
= Def
.split("_")
1992 if Target
!= self
.BuildTarget
or Tag
!= self
.ToolChain
or Arch
!= self
.Arch
:
1995 Value
= ToolDefinition
[Def
]
1996 # don't record the DLL
1998 DllPathList
.add(Value
)
2001 if Tool
not in self
._ToolDefinitions
:
2002 self
._ToolDefinitions
[Tool
] = {}
2003 self
._ToolDefinitions
[Tool
][Attr
] = Value
2007 if GlobalData
.gOptions
.SilentMode
and "MAKE" in self
._ToolDefinitions
:
2008 if "FLAGS" not in self
._ToolDefinitions
["MAKE"]:
2009 self
._ToolDefinitions
["MAKE"]["FLAGS"] = ""
2010 self
._ToolDefinitions
["MAKE"]["FLAGS"] += " -s"
2012 for Tool
in self
._ToolDefinitions
:
2013 for Attr
in self
._ToolDefinitions
[Tool
]:
2014 Value
= self
._ToolDefinitions
[Tool
][Attr
]
2015 if Tool
in self
.BuildOption
and Attr
in self
.BuildOption
[Tool
]:
2016 # check if override is indicated
2017 if self
.BuildOption
[Tool
][Attr
].startswith('='):
2018 Value
= self
.BuildOption
[Tool
][Attr
][1:]
2021 Value
+= " " + self
.BuildOption
[Tool
][Attr
]
2023 Value
= self
.BuildOption
[Tool
][Attr
]
2026 # Don't put MAKE definition in the file
2030 ToolsDef
+= "%s = %s\n" % (Tool
, Value
)
2032 # Don't put MAKE definition in the file
2037 ToolsDef
+= "%s_%s = %s\n" % (Tool
, Attr
, Value
)
2040 SaveFileOnChange(self
.ToolDefinitionFile
, ToolsDef
)
2041 for DllPath
in DllPathList
:
2042 os
.environ
["PATH"] = DllPath
+ os
.pathsep
+ os
.environ
["PATH"]
2043 os
.environ
["MAKE_FLAGS"] = MakeFlags
2045 return self
._ToolDefinitions
2047 ## Return the paths of tools
2048 def _GetToolDefFile(self
):
2049 if self
._ToolDefFile
== None:
2050 self
._ToolDefFile
= os
.path
.join(self
.MakeFileDir
, "TOOLS_DEF." + self
.Arch
)
2051 return self
._ToolDefFile
2053 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
2054 def _GetToolChainFamily(self
):
2055 if self
._ToolChainFamily
== None:
2056 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
2057 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
2058 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
2059 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]:
2060 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
2062 self
._ToolChainFamily
= "MSFT"
2064 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]
2065 return self
._ToolChainFamily
2067 def _GetBuildRuleFamily(self
):
2068 if self
._BuildRuleFamily
== None:
2069 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
2070 if TAB_TOD_DEFINES_BUILDRULEFAMILY
not in ToolDefinition \
2071 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
2072 or not ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]:
2073 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
2075 self
._BuildRuleFamily
= "MSFT"
2077 self
._BuildRuleFamily
= ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]
2078 return self
._BuildRuleFamily
2080 ## Return the build options specific for all modules in this platform
2081 def _GetBuildOptions(self
):
2082 if self
._BuildOption
== None:
2083 self
._BuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
)
2084 return self
._BuildOption
2086 ## Return the build options specific for EDK modules in this platform
2087 def _GetEdkBuildOptions(self
):
2088 if self
._EdkBuildOption
== None:
2089 self
._EdkBuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
, EDK_NAME
)
2090 return self
._EdkBuildOption
2092 ## Return the build options specific for EDKII modules in this platform
2093 def _GetEdkIIBuildOptions(self
):
2094 if self
._EdkIIBuildOption
== None:
2095 self
._EdkIIBuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
, EDKII_NAME
)
2096 return self
._EdkIIBuildOption
2098 ## Parse build_rule.txt in Conf Directory.
2100 # @retval BuildRule object
2102 def _GetBuildRule(self
):
2103 if self
._BuildRule
== None:
2104 BuildRuleFile
= None
2105 if TAB_TAT_DEFINES_BUILD_RULE_CONF
in self
.Workspace
.TargetTxt
.TargetTxtDictionary
:
2106 BuildRuleFile
= self
.Workspace
.TargetTxt
.TargetTxtDictionary
[TAB_TAT_DEFINES_BUILD_RULE_CONF
]
2107 if BuildRuleFile
in [None, '']:
2108 BuildRuleFile
= gDefaultBuildRuleFile
2109 self
._BuildRule
= BuildRule(BuildRuleFile
)
2110 if self
._BuildRule
._FileVersion
== "":
2111 self
._BuildRule
._FileVersion
= AutoGenReqBuildRuleVerNum
2113 if self
._BuildRule
._FileVersion
< AutoGenReqBuildRuleVerNum
:
2114 # If Build Rule's version is less than the version number required by the tools, halting the build.
2115 EdkLogger
.error("build", AUTOGEN_ERROR
,
2116 ExtraData
="The version number [%s] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [%s])"\
2117 % (self
._BuildRule
._FileVersion
, AutoGenReqBuildRuleVerNum
))
2119 return self
._BuildRule
2121 ## Summarize the packages used by modules in this platform
2122 def _GetPackageList(self
):
2123 if self
._PackageList
== None:
2124 self
._PackageList
= set()
2125 for La
in self
.LibraryAutoGenList
:
2126 self
._PackageList
.update(La
.DependentPackageList
)
2127 for Ma
in self
.ModuleAutoGenList
:
2128 self
._PackageList
.update(Ma
.DependentPackageList
)
2129 #Collect package set information from INF of FDF
2131 for ModuleFile
in self
._AsBuildModuleList
:
2132 if ModuleFile
in self
.Platform
.Modules
:
2134 ModuleData
= self
.BuildDatabase
[ModuleFile
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
2135 PkgSet
.update(ModuleData
.Packages
)
2136 self
._PackageList
= list(self
._PackageList
) + list (PkgSet
)
2137 return self
._PackageList
2139 def _GetNonDynamicPcdDict(self
):
2140 if self
._NonDynamicPcdDict
:
2141 return self
._NonDynamicPcdDict
2142 for Pcd
in self
.NonDynamicPcdList
:
2143 self
._NonDynamicPcdDict
[(Pcd
.TokenCName
,Pcd
.TokenSpaceGuidCName
)] = Pcd
2144 return self
._NonDynamicPcdDict
2146 ## Get list of non-dynamic PCDs
2147 def _GetNonDynamicPcdList(self
):
2148 if self
._NonDynamicPcdList
== None:
2149 self
.CollectPlatformDynamicPcds()
2150 return self
._NonDynamicPcdList
2152 ## Get list of dynamic PCDs
2153 def _GetDynamicPcdList(self
):
2154 if self
._DynamicPcdList
== None:
2155 self
.CollectPlatformDynamicPcds()
2156 return self
._DynamicPcdList
2158 ## Generate Token Number for all PCD
2159 def _GetPcdTokenNumbers(self
):
2160 if self
._PcdTokenNumber
== None:
2161 self
._PcdTokenNumber
= sdict()
2164 # Make the Dynamic and DynamicEx PCD use within different TokenNumber area.
2168 # TokenNumber 0 ~ 10
2170 # TokeNumber 11 ~ 20
2172 for Pcd
in self
.DynamicPcdList
:
2173 if Pcd
.Phase
== "PEI":
2174 if Pcd
.Type
in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
2175 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
2176 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
2179 for Pcd
in self
.DynamicPcdList
:
2180 if Pcd
.Phase
== "PEI":
2181 if Pcd
.Type
in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
2182 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
2183 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
2186 for Pcd
in self
.DynamicPcdList
:
2187 if Pcd
.Phase
== "DXE":
2188 if Pcd
.Type
in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
2189 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
2190 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
2193 for Pcd
in self
.DynamicPcdList
:
2194 if Pcd
.Phase
== "DXE":
2195 if Pcd
.Type
in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
2196 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
2197 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
2200 for Pcd
in self
.NonDynamicPcdList
:
2201 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
2203 return self
._PcdTokenNumber
2205 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
2206 def _GetAutoGenObjectList(self
):
2207 self
._ModuleAutoGenList
= []
2208 self
._LibraryAutoGenList
= []
2209 for ModuleFile
in self
.Platform
.Modules
:
2218 if Ma
not in self
._ModuleAutoGenList
:
2219 self
._ModuleAutoGenList
.append(Ma
)
2220 for La
in Ma
.LibraryAutoGenList
:
2221 if La
not in self
._LibraryAutoGenList
:
2222 self
._LibraryAutoGenList
.append(La
)
2223 if Ma
not in La
._ReferenceModules
:
2224 La
._ReferenceModules
.append(Ma
)
2226 ## Summarize ModuleAutoGen objects of all modules to be built for this platform
2227 def _GetModuleAutoGenList(self
):
2228 if self
._ModuleAutoGenList
== None:
2229 self
._GetAutoGenObjectList
()
2230 return self
._ModuleAutoGenList
2232 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
2233 def _GetLibraryAutoGenList(self
):
2234 if self
._LibraryAutoGenList
== None:
2235 self
._GetAutoGenObjectList
()
2236 return self
._LibraryAutoGenList
2238 ## Test if a module is supported by the platform
2240 # An error will be raised directly if the module or its arch is not supported
2241 # by the platform or current configuration
2243 def ValidModule(self
, Module
):
2244 return Module
in self
.Platform
.Modules
or Module
in self
.Platform
.LibraryInstances \
2245 or Module
in self
._AsBuildModuleList
2247 ## Resolve the library classes in a module to library instances
2249 # This method will not only resolve library classes but also sort the library
2250 # instances according to the dependency-ship.
2252 # @param Module The module from which the library classes will be resolved
2254 # @retval library_list List of library instances sorted
2256 def ApplyLibraryInstance(self
, Module
):
2257 # Cover the case that the binary INF file is list in the FDF file but not DSC file, return empty list directly
2258 if str(Module
) not in self
.Platform
.Modules
:
2261 ModuleType
= Module
.ModuleType
2263 # for overridding library instances with module specific setting
2264 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
2266 # add forced library instances (specified under LibraryClasses sections)
2268 # If a module has a MODULE_TYPE of USER_DEFINED,
2269 # do not link in NULL library class instances from the global [LibraryClasses.*] sections.
2271 if Module
.ModuleType
!= SUP_MODULE_USER_DEFINED
:
2272 for LibraryClass
in self
.Platform
.LibraryClasses
.GetKeys():
2273 if LibraryClass
.startswith("NULL") and self
.Platform
.LibraryClasses
[LibraryClass
, Module
.ModuleType
]:
2274 Module
.LibraryClasses
[LibraryClass
] = self
.Platform
.LibraryClasses
[LibraryClass
, Module
.ModuleType
]
2276 # add forced library instances (specified in module overrides)
2277 for LibraryClass
in PlatformModule
.LibraryClasses
:
2278 if LibraryClass
.startswith("NULL"):
2279 Module
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
2282 LibraryConsumerList
= [Module
]
2284 ConsumedByList
= sdict()
2285 LibraryInstance
= sdict()
2287 EdkLogger
.verbose("")
2288 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
2289 while len(LibraryConsumerList
) > 0:
2290 M
= LibraryConsumerList
.pop()
2291 for LibraryClassName
in M
.LibraryClasses
:
2292 if LibraryClassName
not in LibraryInstance
:
2293 # override library instance for this module
2294 if LibraryClassName
in PlatformModule
.LibraryClasses
:
2295 LibraryPath
= PlatformModule
.LibraryClasses
[LibraryClassName
]
2297 LibraryPath
= self
.Platform
.LibraryClasses
[LibraryClassName
, ModuleType
]
2298 if LibraryPath
== None or LibraryPath
== "":
2299 LibraryPath
= M
.LibraryClasses
[LibraryClassName
]
2300 if LibraryPath
== None or LibraryPath
== "":
2301 EdkLogger
.error("build", RESOURCE_NOT_AVAILABLE
,
2302 "Instance of library class [%s] is not found" % LibraryClassName
,
2304 ExtraData
="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M
), self
.Arch
, str(Module
)))
2306 LibraryModule
= self
.BuildDatabase
[LibraryPath
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
2307 # for those forced library instance (NULL library), add a fake library class
2308 if LibraryClassName
.startswith("NULL"):
2309 LibraryModule
.LibraryClass
.append(LibraryClassObject(LibraryClassName
, [ModuleType
]))
2310 elif LibraryModule
.LibraryClass
== None \
2311 or len(LibraryModule
.LibraryClass
) == 0 \
2312 or (ModuleType
!= 'USER_DEFINED'
2313 and ModuleType
not in LibraryModule
.LibraryClass
[0].SupModList
):
2314 # only USER_DEFINED can link against any library instance despite of its SupModList
2315 EdkLogger
.error("build", OPTION_MISSING
,
2316 "Module type [%s] is not supported by library instance [%s]" \
2317 % (ModuleType
, LibraryPath
), File
=self
.MetaFile
,
2318 ExtraData
="consumed by [%s]" % str(Module
))
2320 LibraryInstance
[LibraryClassName
] = LibraryModule
2321 LibraryConsumerList
.append(LibraryModule
)
2322 EdkLogger
.verbose("\t" + str(LibraryClassName
) + " : " + str(LibraryModule
))
2324 LibraryModule
= LibraryInstance
[LibraryClassName
]
2326 if LibraryModule
== None:
2329 if LibraryModule
.ConstructorList
!= [] and LibraryModule
not in Constructor
:
2330 Constructor
.append(LibraryModule
)
2332 if LibraryModule
not in ConsumedByList
:
2333 ConsumedByList
[LibraryModule
] = []
2334 # don't add current module itself to consumer list
2336 if M
in ConsumedByList
[LibraryModule
]:
2338 ConsumedByList
[LibraryModule
].append(M
)
2340 # Initialize the sorted output list to the empty set
2342 SortedLibraryList
= []
2344 # Q <- Set of all nodes with no incoming edges
2346 LibraryList
= [] #LibraryInstance.values()
2348 for LibraryClassName
in LibraryInstance
:
2349 M
= LibraryInstance
[LibraryClassName
]
2350 LibraryList
.append(M
)
2351 if ConsumedByList
[M
] == []:
2355 # start the DAG algorithm
2359 while Q
== [] and EdgeRemoved
:
2361 # for each node Item with a Constructor
2362 for Item
in LibraryList
:
2363 if Item
not in Constructor
:
2365 # for each Node without a constructor with an edge e from Item to Node
2366 for Node
in ConsumedByList
[Item
]:
2367 if Node
in Constructor
:
2369 # remove edge e from the graph if Node has no constructor
2370 ConsumedByList
[Item
].remove(Node
)
2372 if ConsumedByList
[Item
] == []:
2373 # insert Item into Q
2378 # DAG is done if there's no more incoming edge for all nodes
2382 # remove node from Q
2385 SortedLibraryList
.append(Node
)
2387 # for each node Item with an edge e from Node to Item do
2388 for Item
in LibraryList
:
2389 if Node
not in ConsumedByList
[Item
]:
2391 # remove edge e from the graph
2392 ConsumedByList
[Item
].remove(Node
)
2394 if ConsumedByList
[Item
] != []:
2396 # insert Item into Q, if Item has no other incoming edges
2400 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
2402 for Item
in LibraryList
:
2403 if ConsumedByList
[Item
] != [] and Item
in Constructor
and len(Constructor
) > 1:
2404 ErrorMessage
= "\tconsumed by " + "\n\tconsumed by ".join([str(L
) for L
in ConsumedByList
[Item
]])
2405 EdkLogger
.error("build", BUILD_ERROR
, 'Library [%s] with constructors has a cycle' % str(Item
),
2406 ExtraData
=ErrorMessage
, File
=self
.MetaFile
)
2407 if Item
not in SortedLibraryList
:
2408 SortedLibraryList
.append(Item
)
2411 # Build the list of constructor and destructir names
2412 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
2414 SortedLibraryList
.reverse()
2415 return SortedLibraryList
2418 ## Override PCD setting (type, value, ...)
2420 # @param ToPcd The PCD to be overrided
2421 # @param FromPcd The PCD overrideing from
2423 def _OverridePcd(self
, ToPcd
, FromPcd
, Module
=""):
2425 # in case there's PCDs coming from FDF file, which have no type given.
2426 # at this point, ToPcd.Type has the type found from dependent
2429 TokenCName
= ToPcd
.TokenCName
2430 for PcdItem
in GlobalData
.MixedPcd
:
2431 if (ToPcd
.TokenCName
, ToPcd
.TokenSpaceGuidCName
) in GlobalData
.MixedPcd
[PcdItem
]:
2432 TokenCName
= PcdItem
[0]
2435 if GlobalData
.BuildOptionPcd
:
2436 for pcd
in GlobalData
.BuildOptionPcd
:
2437 if (FromPcd
.TokenSpaceGuidCName
, FromPcd
.TokenCName
) == (pcd
[0], pcd
[1]):
2438 FromPcd
.DefaultValue
= pcd
[2]
2440 if ToPcd
.Pending
and FromPcd
.Type
not in [None, '']:
2441 ToPcd
.Type
= FromPcd
.Type
2442 elif (ToPcd
.Type
not in [None, '']) and (FromPcd
.Type
not in [None, ''])\
2443 and (ToPcd
.Type
!= FromPcd
.Type
) and (ToPcd
.Type
in FromPcd
.Type
):
2444 if ToPcd
.Type
.strip() == "DynamicEx":
2445 ToPcd
.Type
= FromPcd
.Type
2446 elif ToPcd
.Type
not in [None, ''] and FromPcd
.Type
not in [None, ''] \
2447 and ToPcd
.Type
!= FromPcd
.Type
:
2448 EdkLogger
.error("build", OPTION_CONFLICT
, "Mismatched PCD type",
2449 ExtraData
="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
2450 % (ToPcd
.TokenSpaceGuidCName
, TokenCName
,
2451 ToPcd
.Type
, Module
, FromPcd
.Type
),
2454 if FromPcd
.MaxDatumSize
not in [None, '']:
2455 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
2456 if FromPcd
.DefaultValue
not in [None, '']:
2457 ToPcd
.DefaultValue
= FromPcd
.DefaultValue
2458 if FromPcd
.TokenValue
not in [None, '']:
2459 ToPcd
.TokenValue
= FromPcd
.TokenValue
2460 if FromPcd
.MaxDatumSize
not in [None, '']:
2461 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
2462 if FromPcd
.DatumType
not in [None, '']:
2463 ToPcd
.DatumType
= FromPcd
.DatumType
2464 if FromPcd
.SkuInfoList
not in [None, '', []]:
2465 ToPcd
.SkuInfoList
= FromPcd
.SkuInfoList
2466 # Add Flexible PCD format parse
2467 if ToPcd
.DefaultValue
:
2469 ToPcd
.DefaultValue
= ValueExpressionEx(ToPcd
.DefaultValue
, ToPcd
.DatumType
, self
._GuidDict
)(True)
2470 except BadExpression
, Value
:
2471 EdkLogger
.error('Parser', FORMAT_INVALID
, 'PCD [%s.%s] Value "%s", %s' %(ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
, ToPcd
.DefaultValue
, Value
),
2474 # check the validation of datum
2475 IsValid
, Cause
= CheckPcdDatum(ToPcd
.DatumType
, ToPcd
.DefaultValue
)
2477 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, File
=self
.MetaFile
,
2478 ExtraData
="%s.%s" % (ToPcd
.TokenSpaceGuidCName
, TokenCName
))
2479 ToPcd
.validateranges
= FromPcd
.validateranges
2480 ToPcd
.validlists
= FromPcd
.validlists
2481 ToPcd
.expressions
= FromPcd
.expressions
2483 if ToPcd
.DatumType
== "VOID*" and ToPcd
.MaxDatumSize
in ['', None]:
2484 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "No MaxDatumSize specified for PCD %s.%s" \
2485 % (ToPcd
.TokenSpaceGuidCName
, TokenCName
))
2486 Value
= ToPcd
.DefaultValue
2487 if Value
in [None, '']:
2488 ToPcd
.MaxDatumSize
= '1'
2489 elif Value
[0] == 'L':
2490 ToPcd
.MaxDatumSize
= str((len(Value
) - 2) * 2)
2491 elif Value
[0] == '{':
2492 ToPcd
.MaxDatumSize
= str(len(Value
.split(',')))
2494 ToPcd
.MaxDatumSize
= str(len(Value
) - 1)
2496 # apply default SKU for dynamic PCDS if specified one is not available
2497 if (ToPcd
.Type
in PCD_DYNAMIC_TYPE_LIST
or ToPcd
.Type
in PCD_DYNAMIC_EX_TYPE_LIST
) \
2498 and ToPcd
.SkuInfoList
in [None, {}, '']:
2499 if self
.Platform
.SkuName
in self
.Platform
.SkuIds
:
2500 SkuName
= self
.Platform
.SkuName
2503 ToPcd
.SkuInfoList
= {
2504 SkuName
: SkuInfoClass(SkuName
, self
.Platform
.SkuIds
[SkuName
][0], '', '', '', '', '', ToPcd
.DefaultValue
)
2507 ## Apply PCD setting defined platform to a module
2509 # @param Module The module from which the PCD setting will be overrided
2511 # @retval PCD_list The list PCDs with settings from platform
2513 def ApplyPcdSetting(self
, Module
, Pcds
):
2514 # for each PCD in module
2515 for Name
, Guid
in Pcds
:
2516 PcdInModule
= Pcds
[Name
, Guid
]
2517 # find out the PCD setting in platform
2518 if (Name
, Guid
) in self
.Platform
.Pcds
:
2519 PcdInPlatform
= self
.Platform
.Pcds
[Name
, Guid
]
2521 PcdInPlatform
= None
2522 # then override the settings if any
2523 self
._OverridePcd
(PcdInModule
, PcdInPlatform
, Module
)
2524 # resolve the VariableGuid value
2525 for SkuId
in PcdInModule
.SkuInfoList
:
2526 Sku
= PcdInModule
.SkuInfoList
[SkuId
]
2527 if Sku
.VariableGuid
== '': continue
2528 Sku
.VariableGuidValue
= GuidValue(Sku
.VariableGuid
, self
.PackageList
, self
.MetaFile
.Path
)
2529 if Sku
.VariableGuidValue
== None:
2530 PackageList
= "\n\t".join([str(P
) for P
in self
.PackageList
])
2533 RESOURCE_NOT_AVAILABLE
,
2534 "Value of GUID [%s] is not found in" % Sku
.VariableGuid
,
2535 ExtraData
=PackageList
+ "\n\t(used with %s.%s from module %s)" \
2536 % (Guid
, Name
, str(Module
)),
2540 # override PCD settings with module specific setting
2541 if Module
in self
.Platform
.Modules
:
2542 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
2543 for Key
in PlatformModule
.Pcds
:
2548 elif Key
in GlobalData
.MixedPcd
:
2549 for PcdItem
in GlobalData
.MixedPcd
[Key
]:
2551 ToPcd
= Pcds
[PcdItem
]
2555 self
._OverridePcd
(ToPcd
, PlatformModule
.Pcds
[Key
], Module
)
2556 return Pcds
.values()
2558 ## Resolve library names to library modules
2560 # (for Edk.x modules)
2562 # @param Module The module from which the library names will be resolved
2564 # @retval library_list The list of library modules
2566 def ResolveLibraryReference(self
, Module
):
2567 EdkLogger
.verbose("")
2568 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
2569 LibraryConsumerList
= [Module
]
2571 # "CompilerStub" is a must for Edk modules
2572 if Module
.Libraries
:
2573 Module
.Libraries
.append("CompilerStub")
2575 while len(LibraryConsumerList
) > 0:
2576 M
= LibraryConsumerList
.pop()
2577 for LibraryName
in M
.Libraries
:
2578 Library
= self
.Platform
.LibraryClasses
[LibraryName
, ':dummy:']
2580 for Key
in self
.Platform
.LibraryClasses
.data
.keys():
2581 if LibraryName
.upper() == Key
.upper():
2582 Library
= self
.Platform
.LibraryClasses
[Key
, ':dummy:']
2585 EdkLogger
.warn("build", "Library [%s] is not found" % LibraryName
, File
=str(M
),
2586 ExtraData
="\t%s [%s]" % (str(Module
), self
.Arch
))
2589 if Library
not in LibraryList
:
2590 LibraryList
.append(Library
)
2591 LibraryConsumerList
.append(Library
)
2592 EdkLogger
.verbose("\t" + LibraryName
+ " : " + str(Library
) + ' ' + str(type(Library
)))
2595 ## Calculate the priority value of the build option
2597 # @param Key Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
2599 # @retval Value Priority value based on the priority list.
2601 def CalculatePriorityValue(self
, Key
):
2602 Target
, ToolChain
, Arch
, CommandType
, Attr
= Key
.split('_')
2603 PriorityValue
= 0x11111
2605 PriorityValue
&= 0x01111
2606 if ToolChain
== "*":
2607 PriorityValue
&= 0x10111
2609 PriorityValue
&= 0x11011
2610 if CommandType
== "*":
2611 PriorityValue
&= 0x11101
2613 PriorityValue
&= 0x11110
2615 return self
.PrioList
["0x%0.5x" % PriorityValue
]
2618 ## Expand * in build option key
2620 # @param Options Options to be expanded
2622 # @retval options Options expanded
2624 def _ExpandBuildOption(self
, Options
, ModuleStyle
=None):
2631 # Construct a list contain the build options which need override.
2635 # Key[0] -- tool family
2636 # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
2638 if (Key
[0] == self
.BuildRuleFamily
and
2639 (ModuleStyle
== None or len(Key
) < 3 or (len(Key
) > 2 and Key
[2] == ModuleStyle
))):
2640 Target
, ToolChain
, Arch
, CommandType
, Attr
= Key
[1].split('_')
2641 if Target
== self
.BuildTarget
or Target
== "*":
2642 if ToolChain
== self
.ToolChain
or ToolChain
== "*":
2643 if Arch
== self
.Arch
or Arch
== "*":
2644 if Options
[Key
].startswith("="):
2645 if OverrideList
.get(Key
[1]) != None:
2646 OverrideList
.pop(Key
[1])
2647 OverrideList
[Key
[1]] = Options
[Key
]
2650 # Use the highest priority value.
2652 if (len(OverrideList
) >= 2):
2653 KeyList
= OverrideList
.keys()
2654 for Index
in range(len(KeyList
)):
2655 NowKey
= KeyList
[Index
]
2656 Target1
, ToolChain1
, Arch1
, CommandType1
, Attr1
= NowKey
.split("_")
2657 for Index1
in range(len(KeyList
) - Index
- 1):
2658 NextKey
= KeyList
[Index1
+ Index
+ 1]
2660 # Compare two Key, if one is included by another, choose the higher priority one
2662 Target2
, ToolChain2
, Arch2
, CommandType2
, Attr2
= NextKey
.split("_")
2663 if Target1
== Target2
or Target1
== "*" or Target2
== "*":
2664 if ToolChain1
== ToolChain2
or ToolChain1
== "*" or ToolChain2
== "*":
2665 if Arch1
== Arch2
or Arch1
== "*" or Arch2
== "*":
2666 if CommandType1
== CommandType2
or CommandType1
== "*" or CommandType2
== "*":
2667 if Attr1
== Attr2
or Attr1
== "*" or Attr2
== "*":
2668 if self
.CalculatePriorityValue(NowKey
) > self
.CalculatePriorityValue(NextKey
):
2669 if Options
.get((self
.BuildRuleFamily
, NextKey
)) != None:
2670 Options
.pop((self
.BuildRuleFamily
, NextKey
))
2672 if Options
.get((self
.BuildRuleFamily
, NowKey
)) != None:
2673 Options
.pop((self
.BuildRuleFamily
, NowKey
))
2676 if ModuleStyle
!= None and len (Key
) > 2:
2677 # Check Module style is EDK or EDKII.
2678 # Only append build option for the matched style module.
2679 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
2681 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
2684 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
2685 # if tool chain family doesn't match, skip it
2686 if Tool
in self
.ToolDefinition
and Family
!= "":
2687 FamilyIsNull
= False
2688 if self
.ToolDefinition
[Tool
].get(TAB_TOD_DEFINES_BUILDRULEFAMILY
, "") != "":
2689 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_BUILDRULEFAMILY
]:
2691 elif Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
2694 # expand any wildcard
2695 if Target
== "*" or Target
== self
.BuildTarget
:
2696 if Tag
== "*" or Tag
== self
.ToolChain
:
2697 if Arch
== "*" or Arch
== self
.Arch
:
2698 if Tool
not in BuildOptions
:
2699 BuildOptions
[Tool
] = {}
2700 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or Options
[Key
].startswith('='):
2701 BuildOptions
[Tool
][Attr
] = Options
[Key
]
2703 # append options for the same tool except PATH
2705 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
2707 BuildOptions
[Tool
][Attr
] = Options
[Key
]
2708 # Build Option Family has been checked, which need't to be checked again for family.
2709 if FamilyMatch
or FamilyIsNull
:
2713 if ModuleStyle
!= None and len (Key
) > 2:
2714 # Check Module style is EDK or EDKII.
2715 # Only append build option for the matched style module.
2716 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
2718 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
2721 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
2722 # if tool chain family doesn't match, skip it
2723 if Tool
not in self
.ToolDefinition
or Family
== "":
2725 # option has been added before
2726 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
2729 # expand any wildcard
2730 if Target
== "*" or Target
== self
.BuildTarget
:
2731 if Tag
== "*" or Tag
== self
.ToolChain
:
2732 if Arch
== "*" or Arch
== self
.Arch
:
2733 if Tool
not in BuildOptions
:
2734 BuildOptions
[Tool
] = {}
2735 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or Options
[Key
].startswith('='):
2736 BuildOptions
[Tool
][Attr
] = Options
[Key
]
2738 # append options for the same tool except PATH
2740 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
2742 BuildOptions
[Tool
][Attr
] = Options
[Key
]
2745 ## Append build options in platform to a module
2747 # @param Module The module to which the build options will be appened
2749 # @retval options The options appended with build options in platform
2751 def ApplyBuildOption(self
, Module
):
2752 # Get the different options for the different style module
2753 if Module
.AutoGenVersion
< 0x00010005:
2754 PlatformOptions
= self
.EdkBuildOption
2755 ModuleTypeOptions
= self
.Platform
.GetBuildOptionsByModuleType(EDK_NAME
, Module
.ModuleType
)
2757 PlatformOptions
= self
.EdkIIBuildOption
2758 ModuleTypeOptions
= self
.Platform
.GetBuildOptionsByModuleType(EDKII_NAME
, Module
.ModuleType
)
2759 ModuleTypeOptions
= self
._ExpandBuildOption
(ModuleTypeOptions
)
2760 ModuleOptions
= self
._ExpandBuildOption
(Module
.BuildOptions
)
2761 if Module
in self
.Platform
.Modules
:
2762 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
2763 PlatformModuleOptions
= self
._ExpandBuildOption
(PlatformModule
.BuildOptions
)
2765 PlatformModuleOptions
= {}
2767 BuildRuleOrder
= None
2768 for Options
in [self
.ToolDefinition
, ModuleOptions
, PlatformOptions
, ModuleTypeOptions
, PlatformModuleOptions
]:
2769 for Tool
in Options
:
2770 for Attr
in Options
[Tool
]:
2771 if Attr
== TAB_TOD_DEFINES_BUILDRULEORDER
:
2772 BuildRuleOrder
= Options
[Tool
][Attr
]
2774 AllTools
= set(ModuleOptions
.keys() + PlatformOptions
.keys() +
2775 PlatformModuleOptions
.keys() + ModuleTypeOptions
.keys() +
2776 self
.ToolDefinition
.keys())
2778 for Tool
in AllTools
:
2779 if Tool
not in BuildOptions
:
2780 BuildOptions
[Tool
] = {}
2782 for Options
in [self
.ToolDefinition
, ModuleOptions
, PlatformOptions
, ModuleTypeOptions
, PlatformModuleOptions
]:
2783 if Tool
not in Options
:
2785 for Attr
in Options
[Tool
]:
2786 Value
= Options
[Tool
][Attr
]
2788 # Do not generate it in Makefile
2790 if Attr
== TAB_TOD_DEFINES_BUILDRULEORDER
:
2792 if Attr
not in BuildOptions
[Tool
]:
2793 BuildOptions
[Tool
][Attr
] = ""
2794 # check if override is indicated
2795 if Value
.startswith('='):
2796 ToolPath
= Value
[1:]
2797 ToolPath
= mws
.handleWsMacro(ToolPath
)
2798 BuildOptions
[Tool
][Attr
] = ToolPath
2800 Value
= mws
.handleWsMacro(Value
)
2802 BuildOptions
[Tool
][Attr
] += " " + Value
2804 BuildOptions
[Tool
][Attr
] = Value
2805 if Module
.AutoGenVersion
< 0x00010005 and self
.Workspace
.UniFlag
!= None:
2807 # Override UNI flag only for EDK module.
2809 if 'BUILD' not in BuildOptions
:
2810 BuildOptions
['BUILD'] = {}
2811 BuildOptions
['BUILD']['FLAGS'] = self
.Workspace
.UniFlag
2812 return BuildOptions
, BuildRuleOrder
2814 Platform
= property(_GetPlatform
)
2815 Name
= property(_GetName
)
2816 Guid
= property(_GetGuid
)
2817 Version
= property(_GetVersion
)
2819 OutputDir
= property(_GetOutputDir
)
2820 BuildDir
= property(_GetBuildDir
)
2821 MakeFileDir
= property(_GetMakeFileDir
)
2822 FdfFile
= property(_GetFdfFile
)
2824 PcdTokenNumber
= property(_GetPcdTokenNumbers
) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
2825 DynamicPcdList
= property(_GetDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
2826 NonDynamicPcdList
= property(_GetNonDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
2827 NonDynamicPcdDict
= property(_GetNonDynamicPcdDict
)
2828 PackageList
= property(_GetPackageList
)
2830 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
2831 ToolDefinitionFile
= property(_GetToolDefFile
) # toolcode : lib path
2832 ToolChainFamily
= property(_GetToolChainFamily
)
2833 BuildRuleFamily
= property(_GetBuildRuleFamily
)
2834 BuildOption
= property(_GetBuildOptions
) # toolcode : option
2835 EdkBuildOption
= property(_GetEdkBuildOptions
) # edktoolcode : option
2836 EdkIIBuildOption
= property(_GetEdkIIBuildOptions
) # edkiitoolcode : option
2838 BuildCommand
= property(_GetBuildCommand
)
2839 BuildRule
= property(_GetBuildRule
)
2840 ModuleAutoGenList
= property(_GetModuleAutoGenList
)
2841 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
2842 GenFdsCommand
= property(_GenFdsCommand
)
2844 ## ModuleAutoGen class
2846 # This class encapsules the AutoGen behaviors for the build tools. In addition to
2847 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
2848 # to the [depex] section in module's inf file.
2850 class ModuleAutoGen(AutoGen
):
2851 ## Cache the timestamps of metafiles of every module in a class variable
2855 ## The real constructor of ModuleAutoGen
2857 # This method is not supposed to be called by users of ModuleAutoGen. It's
2858 # only used by factory method __new__() to do real initialization work for an
2859 # object of ModuleAutoGen
2861 # @param Workspace EdkIIWorkspaceBuild object
2862 # @param ModuleFile The path of module file
2863 # @param Target Build target (DEBUG, RELEASE)
2864 # @param Toolchain Name of tool chain
2865 # @param Arch The arch the module supports
2866 # @param PlatformFile Platform meta-file
2868 def _Init(self
, Workspace
, ModuleFile
, Target
, Toolchain
, Arch
, PlatformFile
):
2869 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen module [%s] [%s]" % (ModuleFile
, Arch
))
2870 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (ModuleFile
, Arch
, Toolchain
, Target
)
2872 self
.Workspace
= Workspace
2873 self
.WorkspaceDir
= Workspace
.WorkspaceDir
2875 self
.MetaFile
= ModuleFile
2876 self
.PlatformInfo
= PlatformAutoGen(Workspace
, PlatformFile
, Target
, Toolchain
, Arch
)
2877 # check if this module is employed by active platform
2878 if not self
.PlatformInfo
.ValidModule(self
.MetaFile
):
2879 EdkLogger
.verbose("Module [%s] for [%s] is not employed by active platform\n" \
2880 % (self
.MetaFile
, Arch
))
2883 self
.SourceDir
= self
.MetaFile
.SubDir
2884 self
.SourceDir
= mws
.relpath(self
.SourceDir
, self
.WorkspaceDir
)
2886 self
.SourceOverrideDir
= None
2887 # use overrided path defined in DSC file
2888 if self
.MetaFile
.Key
in GlobalData
.gOverrideDir
:
2889 self
.SourceOverrideDir
= GlobalData
.gOverrideDir
[self
.MetaFile
.Key
]
2891 self
.ToolChain
= Toolchain
2892 self
.BuildTarget
= Target
2894 self
.ToolChainFamily
= self
.PlatformInfo
.ToolChainFamily
2895 self
.BuildRuleFamily
= self
.PlatformInfo
.BuildRuleFamily
2897 self
.IsMakeFileCreated
= False
2898 self
.IsCodeFileCreated
= False
2899 self
.IsAsBuiltInfCreated
= False
2900 self
.DepexGenerated
= False
2902 self
.BuildDatabase
= self
.Workspace
.BuildDatabase
2903 self
.BuildRuleOrder
= None
2909 self
._Version
= None
2910 self
._ModuleType
= None
2911 self
._ComponentType
= None
2912 self
._PcdIsDriver
= None
2913 self
._AutoGenVersion
= None
2914 self
._LibraryFlag
= None
2915 self
._CustomMakefile
= None
2918 self
._BuildDir
= None
2919 self
._OutputDir
= None
2920 self
._FfsOutputDir
= None
2921 self
._DebugDir
= None
2922 self
._MakeFileDir
= None
2924 self
._IncludePathList
= None
2925 self
._IncludePathLength
= 0
2926 self
._AutoGenFileList
= None
2927 self
._UnicodeFileList
= None
2928 self
._VfrFileList
= None
2929 self
._IdfFileList
= None
2930 self
._SourceFileList
= None
2931 self
._ObjectFileList
= None
2932 self
._BinaryFileList
= None
2934 self
._DependentPackageList
= None
2935 self
._DependentLibraryList
= None
2936 self
._LibraryAutoGenList
= None
2937 self
._DerivedPackageList
= None
2938 self
._ModulePcdList
= None
2939 self
._LibraryPcdList
= None
2940 self
._PcdComments
= sdict()
2941 self
._GuidList
= None
2942 self
._GuidsUsedByPcd
= None
2943 self
._GuidComments
= sdict()
2944 self
._ProtocolList
= None
2945 self
._ProtocolComments
= sdict()
2946 self
._PpiList
= None
2947 self
._PpiComments
= sdict()
2948 self
._DepexList
= None
2949 self
._DepexExpressionList
= None
2950 self
._BuildOption
= None
2951 self
._BuildOptionIncPathList
= None
2952 self
._BuildTargets
= None
2953 self
._IntroBuildTargetList
= None
2954 self
._FinalBuildTargetList
= None
2955 self
._FileTypes
= None
2956 self
._BuildRules
= None
2958 self
._TimeStampPath
= None
2960 self
.AutoGenDepSet
= set()
2963 ## The Modules referenced to this Library
2964 # Only Library has this attribute
2965 self
._ReferenceModules
= []
2967 ## Store the FixedAtBuild Pcds
2969 self
._FixedAtBuildPcds
= []
2974 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
2976 # Get FixedAtBuild Pcds of this Module
2977 def _GetFixedAtBuildPcds(self
):
2978 if self
._FixedAtBuildPcds
:
2979 return self
._FixedAtBuildPcds
2980 for Pcd
in self
.ModulePcdList
:
2981 if Pcd
.Type
!= "FixedAtBuild":
2983 if Pcd
not in self
._FixedAtBuildPcds
:
2984 self
._FixedAtBuildPcds
.append(Pcd
)
2986 return self
._FixedAtBuildPcds
2988 def _GetUniqueBaseName(self
):
2989 BaseName
= self
.Name
2990 for Module
in self
.PlatformInfo
.ModuleAutoGenList
:
2991 if Module
.MetaFile
== self
.MetaFile
:
2993 if Module
.Name
== self
.Name
:
2994 if uuid
.UUID(Module
.Guid
) == uuid
.UUID(self
.Guid
):
2995 EdkLogger
.error("build", FILE_DUPLICATED
, 'Modules have same BaseName and FILE_GUID:\n'
2996 ' %s\n %s' % (Module
.MetaFile
, self
.MetaFile
))
2997 BaseName
= '%s_%s' % (self
.Name
, self
.Guid
)
3000 # Macros could be used in build_rule.txt (also Makefile)
3001 def _GetMacros(self
):
3002 if self
._Macro
== None:
3003 self
._Macro
= sdict()
3004 self
._Macro
["WORKSPACE" ] = self
.WorkspaceDir
3005 self
._Macro
["MODULE_NAME" ] = self
.Name
3006 self
._Macro
["MODULE_NAME_GUID" ] = self
._GetUniqueBaseName
()
3007 self
._Macro
["MODULE_GUID" ] = self
.Guid
3008 self
._Macro
["MODULE_VERSION" ] = self
.Version
3009 self
._Macro
["MODULE_TYPE" ] = self
.ModuleType
3010 self
._Macro
["MODULE_FILE" ] = str(self
.MetaFile
)
3011 self
._Macro
["MODULE_FILE_BASE_NAME" ] = self
.MetaFile
.BaseName
3012 self
._Macro
["MODULE_RELATIVE_DIR" ] = self
.SourceDir
3013 self
._Macro
["MODULE_DIR" ] = self
.SourceDir
3015 self
._Macro
["BASE_NAME" ] = self
.Name
3017 self
._Macro
["ARCH" ] = self
.Arch
3018 self
._Macro
["TOOLCHAIN" ] = self
.ToolChain
3019 self
._Macro
["TOOLCHAIN_TAG" ] = self
.ToolChain
3020 self
._Macro
["TOOL_CHAIN_TAG" ] = self
.ToolChain
3021 self
._Macro
["TARGET" ] = self
.BuildTarget
3023 self
._Macro
["BUILD_DIR" ] = self
.PlatformInfo
.BuildDir
3024 self
._Macro
["BIN_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
3025 self
._Macro
["LIB_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
3026 self
._Macro
["MODULE_BUILD_DIR" ] = self
.BuildDir
3027 self
._Macro
["OUTPUT_DIR" ] = self
.OutputDir
3028 self
._Macro
["DEBUG_DIR" ] = self
.DebugDir
3029 self
._Macro
["DEST_DIR_OUTPUT" ] = self
.OutputDir
3030 self
._Macro
["DEST_DIR_DEBUG" ] = self
.DebugDir
3031 self
._Macro
["PLATFORM_NAME" ] = self
.PlatformInfo
.Name
3032 self
._Macro
["PLATFORM_GUID" ] = self
.PlatformInfo
.Guid
3033 self
._Macro
["PLATFORM_VERSION" ] = self
.PlatformInfo
.Version
3034 self
._Macro
["PLATFORM_RELATIVE_DIR" ] = self
.PlatformInfo
.SourceDir
3035 self
._Macro
["PLATFORM_DIR" ] = mws
.join(self
.WorkspaceDir
, self
.PlatformInfo
.SourceDir
)
3036 self
._Macro
["PLATFORM_OUTPUT_DIR" ] = self
.PlatformInfo
.OutputDir
3037 self
._Macro
["FFS_OUTPUT_DIR" ] = self
.FfsOutputDir
3040 ## Return the module build data object
3041 def _GetModule(self
):
3042 if self
._Module
== None:
3043 self
._Module
= self
.Workspace
.BuildDatabase
[self
.MetaFile
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
3046 ## Return the module name
3047 def _GetBaseName(self
):
3048 return self
.Module
.BaseName
3050 ## Return the module DxsFile if exist
3051 def _GetDxsFile(self
):
3052 return self
.Module
.DxsFile
3054 ## Return the module SourceOverridePath
3055 def _GetSourceOverridePath(self
):
3056 return self
.Module
.SourceOverridePath
3058 ## Return the module meta-file GUID
3061 # To build same module more than once, the module path with FILE_GUID overridden has
3062 # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the realy path
3063 # in DSC. The overridden GUID can be retrieved from file name
3065 if os
.path
.basename(self
.MetaFile
.File
) != os
.path
.basename(self
.MetaFile
.Path
):
3067 # Length of GUID is 36
3069 return os
.path
.basename(self
.MetaFile
.Path
)[:36]
3070 return self
.Module
.Guid
3072 ## Return the module version
3073 def _GetVersion(self
):
3074 return self
.Module
.Version
3076 ## Return the module type
3077 def _GetModuleType(self
):
3078 return self
.Module
.ModuleType
3080 ## Return the component type (for Edk.x style of module)
3081 def _GetComponentType(self
):
3082 return self
.Module
.ComponentType
3084 ## Return the build type
3085 def _GetBuildType(self
):
3086 return self
.Module
.BuildType
3088 ## Return the PCD_IS_DRIVER setting
3089 def _GetPcdIsDriver(self
):
3090 return self
.Module
.PcdIsDriver
3092 ## Return the autogen version, i.e. module meta-file version
3093 def _GetAutoGenVersion(self
):
3094 return self
.Module
.AutoGenVersion
3096 ## Check if the module is library or not
3097 def _IsLibrary(self
):
3098 if self
._LibraryFlag
== None:
3099 if self
.Module
.LibraryClass
!= None and self
.Module
.LibraryClass
!= []:
3100 self
._LibraryFlag
= True
3102 self
._LibraryFlag
= False
3103 return self
._LibraryFlag
3105 ## Check if the module is binary module or not
3106 def _IsBinaryModule(self
):
3107 return self
.Module
.IsBinaryModule
3109 ## Return the directory to store intermediate files of the module
3110 def _GetBuildDir(self
):
3111 if self
._BuildDir
== None:
3112 self
._BuildDir
= path
.join(
3113 self
.PlatformInfo
.BuildDir
,
3116 self
.MetaFile
.BaseName
3118 CreateDirectory(self
._BuildDir
)
3119 return self
._BuildDir
3121 ## Return the directory to store the intermediate object files of the mdoule
3122 def _GetOutputDir(self
):
3123 if self
._OutputDir
== None:
3124 self
._OutputDir
= path
.join(self
.BuildDir
, "OUTPUT")
3125 CreateDirectory(self
._OutputDir
)
3126 return self
._OutputDir
3128 ## Return the directory to store ffs file
3129 def _GetFfsOutputDir(self
):
3130 if self
._FfsOutputDir
== None:
3131 if GlobalData
.gFdfParser
!= None:
3132 self
._FfsOutputDir
= path
.join(self
.PlatformInfo
.BuildDir
, "FV", "Ffs", self
.Guid
+ self
.Name
)
3134 self
._FfsOutputDir
= ''
3135 return self
._FfsOutputDir
3137 ## Return the directory to store auto-gened source files of the mdoule
3138 def _GetDebugDir(self
):
3139 if self
._DebugDir
== None:
3140 self
._DebugDir
= path
.join(self
.BuildDir
, "DEBUG")
3141 CreateDirectory(self
._DebugDir
)
3142 return self
._DebugDir
3144 ## Return the path of custom file
3145 def _GetCustomMakefile(self
):
3146 if self
._CustomMakefile
== None:
3147 self
._CustomMakefile
= {}
3148 for Type
in self
.Module
.CustomMakefile
:
3149 if Type
in gMakeTypeMap
:
3150 MakeType
= gMakeTypeMap
[Type
]
3153 if self
.SourceOverrideDir
!= None:
3154 File
= os
.path
.join(self
.SourceOverrideDir
, self
.Module
.CustomMakefile
[Type
])
3155 if not os
.path
.exists(File
):
3156 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
3158 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
3159 self
._CustomMakefile
[MakeType
] = File
3160 return self
._CustomMakefile
3162 ## Return the directory of the makefile
3164 # @retval string The directory string of module's makefile
3166 def _GetMakeFileDir(self
):
3167 return self
.BuildDir
3169 ## Return build command string
3171 # @retval string Build command string
3173 def _GetBuildCommand(self
):
3174 return self
.PlatformInfo
.BuildCommand
3176 ## Get object list of all packages the module and its dependent libraries belong to
3178 # @retval list The list of package object
3180 def _GetDerivedPackageList(self
):
3182 for M
in [self
.Module
] + self
.DependentLibraryList
:
3183 for Package
in M
.Packages
:
3184 if Package
in PackageList
:
3186 PackageList
.append(Package
)
3189 ## Get the depex string
3191 # @return : a string contain all depex expresion.
3192 def _GetDepexExpresionString(self
):
3195 ## DPX_SOURCE IN Define section.
3196 if self
.Module
.DxsFile
:
3198 for M
in [self
.Module
] + self
.DependentLibraryList
:
3199 Filename
= M
.MetaFile
.Path
3200 InfObj
= InfSectionParser
.InfSectionParser(Filename
)
3201 DepexExpresionList
= InfObj
.GetDepexExpresionList()
3202 for DepexExpresion
in DepexExpresionList
:
3203 for key
in DepexExpresion
.keys():
3204 Arch
, ModuleType
= key
3205 DepexExpr
= [x
for x
in DepexExpresion
[key
] if not str(x
).startswith('#')]
3206 # the type of build module is USER_DEFINED.
3207 # All different DEPEX section tags would be copied into the As Built INF file
3208 # and there would be separate DEPEX section tags
3209 if self
.ModuleType
.upper() == SUP_MODULE_USER_DEFINED
:
3210 if (Arch
.upper() == self
.Arch
.upper()) and (ModuleType
.upper() != TAB_ARCH_COMMON
):
3211 DepexList
.append({(Arch
, ModuleType
): DepexExpr
})
3213 if Arch
.upper() == TAB_ARCH_COMMON
or \
3214 (Arch
.upper() == self
.Arch
.upper() and \
3215 ModuleType
.upper() in [TAB_ARCH_COMMON
, self
.ModuleType
.upper()]):
3216 DepexList
.append({(Arch
, ModuleType
): DepexExpr
})
3218 #the type of build module is USER_DEFINED.
3219 if self
.ModuleType
.upper() == SUP_MODULE_USER_DEFINED
:
3220 for Depex
in DepexList
:
3221 for key
in Depex
.keys():
3222 DepexStr
+= '[Depex.%s.%s]\n' % key
3223 DepexStr
+= '\n'.join(['# '+ val
for val
in Depex
[key
]])
3226 return '[Depex.%s]\n' % self
.Arch
3229 #the type of build module not is USER_DEFINED.
3231 for Depex
in DepexList
:
3236 for D
in Depex
.values():
3237 DepexStr
+= ' '.join([val
for val
in D
])
3238 Index
= DepexStr
.find('END')
3239 if Index
> -1 and Index
== len(DepexStr
) - 3:
3240 DepexStr
= DepexStr
[:-3]
3241 DepexStr
= DepexStr
.strip()
3244 DepexStr
= DepexStr
.lstrip('(').rstrip(')').strip()
3246 return '[Depex.%s]\n' % self
.Arch
3247 return '[Depex.%s]\n# ' % self
.Arch
+ DepexStr
3249 ## Merge dependency expression
3251 # @retval list The token list of the dependency expression after parsed
3253 def _GetDepexTokenList(self
):
3254 if self
._DepexList
== None:
3255 self
._DepexList
= {}
3256 if self
.DxsFile
or self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
3257 return self
._DepexList
3259 self
._DepexList
[self
.ModuleType
] = []
3261 for ModuleType
in self
._DepexList
:
3262 DepexList
= self
._DepexList
[ModuleType
]
3264 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
3266 for M
in [self
.Module
] + self
.DependentLibraryList
:
3268 for D
in M
.Depex
[self
.Arch
, ModuleType
]:
3270 DepexList
.append('AND')
3271 DepexList
.append('(')
3273 if DepexList
[-1] == 'END': # no need of a END at this time
3275 DepexList
.append(')')
3278 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexList
))
3279 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
3281 if len(DepexList
) > 0:
3282 EdkLogger
.verbose('')
3283 return self
._DepexList
3285 ## Merge dependency expression
3287 # @retval list The token list of the dependency expression after parsed
3289 def _GetDepexExpressionTokenList(self
):
3290 if self
._DepexExpressionList
== None:
3291 self
._DepexExpressionList
= {}
3292 if self
.DxsFile
or self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
3293 return self
._DepexExpressionList
3295 self
._DepexExpressionList
[self
.ModuleType
] = ''
3297 for ModuleType
in self
._DepexExpressionList
:
3298 DepexExpressionList
= self
._DepexExpressionList
[ModuleType
]
3300 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
3302 for M
in [self
.Module
] + self
.DependentLibraryList
:
3304 for D
in M
.DepexExpression
[self
.Arch
, ModuleType
]:
3305 if DepexExpressionList
!= '':
3306 DepexExpressionList
+= ' AND '
3307 DepexExpressionList
+= '('
3308 DepexExpressionList
+= D
3309 DepexExpressionList
= DepexExpressionList
.rstrip('END').strip()
3310 DepexExpressionList
+= ')'
3313 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexExpressionList
))
3314 if 'BEFORE' in DepexExpressionList
or 'AFTER' in DepexExpressionList
:
3316 if len(DepexExpressionList
) > 0:
3317 EdkLogger
.verbose('')
3318 self
._DepexExpressionList
[ModuleType
] = DepexExpressionList
3319 return self
._DepexExpressionList
3321 # Get the tiano core user extension, it is contain dependent library.
3322 # @retval: a list contain tiano core userextension.
3324 def _GetTianoCoreUserExtensionList(self
):
3325 TianoCoreUserExtentionList
= []
3326 for M
in [self
.Module
] + self
.DependentLibraryList
:
3327 Filename
= M
.MetaFile
.Path
3328 InfObj
= InfSectionParser
.InfSectionParser(Filename
)
3329 TianoCoreUserExtenList
= InfObj
.GetUserExtensionTianoCore()
3330 for TianoCoreUserExtent
in TianoCoreUserExtenList
:
3331 for Section
in TianoCoreUserExtent
.keys():
3332 ItemList
= Section
.split(TAB_SPLIT
)
3334 if len(ItemList
) == 4:
3336 if Arch
.upper() == TAB_ARCH_COMMON
or Arch
.upper() == self
.Arch
.upper():
3338 TianoCoreList
.extend([TAB_SECTION_START
+ Section
+ TAB_SECTION_END
])
3339 TianoCoreList
.extend(TianoCoreUserExtent
[Section
][:])
3340 TianoCoreList
.append('\n')
3341 TianoCoreUserExtentionList
.append(TianoCoreList
)
3343 return TianoCoreUserExtentionList
3345 ## Return the list of specification version required for the module
3347 # @retval list The list of specification defined in module file
3349 def _GetSpecification(self
):
3350 return self
.Module
.Specification
3352 ## Tool option for the module build
3354 # @param PlatformInfo The object of PlatformBuildInfo
3355 # @retval dict The dict containing valid options
3357 def _GetModuleBuildOption(self
):
3358 if self
._BuildOption
== None:
3359 self
._BuildOption
, self
.BuildRuleOrder
= self
.PlatformInfo
.ApplyBuildOption(self
.Module
)
3360 if self
.BuildRuleOrder
:
3361 self
.BuildRuleOrder
= ['.%s' % Ext
for Ext
in self
.BuildRuleOrder
.split()]
3362 return self
._BuildOption
3364 ## Get include path list from tool option for the module build
3366 # @retval list The include path list
3368 def _GetBuildOptionIncPathList(self
):
3369 if self
._BuildOptionIncPathList
== None:
3371 # Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT
3372 # is the former use /I , the Latter used -I to specify include directories
3374 if self
.PlatformInfo
.ToolChainFamily
in ('MSFT'):
3375 gBuildOptIncludePattern
= re
.compile(r
"(?:.*?)/I[ \t]*([^ ]*)", re
.MULTILINE | re
.DOTALL
)
3376 elif self
.PlatformInfo
.ToolChainFamily
in ('INTEL', 'GCC', 'RVCT'):
3377 gBuildOptIncludePattern
= re
.compile(r
"(?:.*?)-I[ \t]*([^ ]*)", re
.MULTILINE | re
.DOTALL
)
3380 # New ToolChainFamily, don't known whether there is option to specify include directories
3382 self
._BuildOptionIncPathList
= []
3383 return self
._BuildOptionIncPathList
3385 BuildOptionIncPathList
= []
3386 for Tool
in ('CC', 'PP', 'VFRPP', 'ASLPP', 'ASLCC', 'APP', 'ASM'):
3389 FlagOption
= self
.BuildOption
[Tool
][Attr
]
3393 if self
.PlatformInfo
.ToolChainFamily
!= 'RVCT':
3394 IncPathList
= [NormPath(Path
, self
.Macros
) for Path
in gBuildOptIncludePattern
.findall(FlagOption
)]
3397 # RVCT may specify a list of directory seperated by commas
3400 for Path
in gBuildOptIncludePattern
.findall(FlagOption
):
3401 PathList
= GetSplitList(Path
, TAB_COMMA_SPLIT
)
3402 IncPathList
+= [NormPath(PathEntry
, self
.Macros
) for PathEntry
in PathList
]
3405 # EDK II modules must not reference header files outside of the packages they depend on or
3406 # within the module's directory tree. Report error if violation.
3408 if self
.AutoGenVersion
>= 0x00010005 and len(IncPathList
) > 0:
3409 for Path
in IncPathList
:
3410 if (Path
not in self
.IncludePathList
) and (CommonPath([Path
, self
.MetaFile
.Dir
]) != self
.MetaFile
.Dir
):
3411 ErrMsg
= "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path
, Tool
, FlagOption
)
3412 EdkLogger
.error("build",
3415 File
=str(self
.MetaFile
))
3418 BuildOptionIncPathList
+= IncPathList
3420 self
._BuildOptionIncPathList
= BuildOptionIncPathList
3422 return self
._BuildOptionIncPathList
3424 ## Return a list of files which can be built from source
3426 # What kind of files can be built is determined by build rules in
3427 # $(CONF_DIRECTORY)/build_rule.txt and toolchain family.
3429 def _GetSourceFileList(self
):
3430 if self
._SourceFileList
== None:
3431 self
._SourceFileList
= []
3432 for F
in self
.Module
.Sources
:
3434 if F
.TagName
not in ("", "*", self
.ToolChain
):
3435 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "The toolchain [%s] for processing file [%s] is found, "
3436 "but [%s] is needed" % (F
.TagName
, str(F
), self
.ToolChain
))
3438 # match tool chain family or build rule family
3439 if F
.ToolChainFamily
not in ("", "*", self
.ToolChainFamily
, self
.BuildRuleFamily
):
3442 "The file [%s] must be built by tools of [%s], " \
3443 "but current toolchain family is [%s], buildrule family is [%s]" \
3444 % (str(F
), F
.ToolChainFamily
, self
.ToolChainFamily
, self
.BuildRuleFamily
))
3447 # add the file path into search path list for file including
3448 if F
.Dir
not in self
.IncludePathList
and self
.AutoGenVersion
>= 0x00010005:
3449 self
.IncludePathList
.insert(0, F
.Dir
)
3450 self
._SourceFileList
.append(F
)
3452 self
._MatchBuildRuleOrder
(self
._SourceFileList
)
3454 for F
in self
._SourceFileList
:
3455 self
._ApplyBuildRule
(F
, TAB_UNKNOWN_FILE
)
3456 return self
._SourceFileList
3458 def _MatchBuildRuleOrder(self
, FileList
):
3460 self
._GetModuleBuildOption
()
3461 for SingleFile
in FileList
:
3462 if self
.BuildRuleOrder
and SingleFile
.Ext
in self
.BuildRuleOrder
and SingleFile
.Ext
in self
.BuildRules
:
3463 key
= SingleFile
.Path
.split(SingleFile
.Ext
)[0]
3464 if key
in Order_Dict
:
3465 Order_Dict
[key
].append(SingleFile
.Ext
)
3467 Order_Dict
[key
] = [SingleFile
.Ext
]
3470 for F
in Order_Dict
:
3471 if len(Order_Dict
[F
]) > 1:
3472 Order_Dict
[F
].sort(key
=lambda i
: self
.BuildRuleOrder
.index(i
))
3473 for Ext
in Order_Dict
[F
][1:]:
3474 RemoveList
.append(F
+ Ext
)
3476 for item
in RemoveList
:
3477 FileList
.remove(item
)
3481 ## Return the list of unicode files
3482 def _GetUnicodeFileList(self
):
3483 if self
._UnicodeFileList
== None:
3484 if TAB_UNICODE_FILE
in self
.FileTypes
:
3485 self
._UnicodeFileList
= self
.FileTypes
[TAB_UNICODE_FILE
]
3487 self
._UnicodeFileList
= []
3488 return self
._UnicodeFileList
3490 ## Return the list of vfr files
3491 def _GetVfrFileList(self
):
3492 if self
._VfrFileList
== None:
3493 if TAB_VFR_FILE
in self
.FileTypes
:
3494 self
._VfrFileList
= self
.FileTypes
[TAB_VFR_FILE
]
3496 self
._VfrFileList
= []
3497 return self
._VfrFileList
3499 ## Return the list of Image Definition files
3500 def _GetIdfFileList(self
):
3501 if self
._IdfFileList
== None:
3502 if TAB_IMAGE_FILE
in self
.FileTypes
:
3503 self
._IdfFileList
= self
.FileTypes
[TAB_IMAGE_FILE
]
3505 self
._IdfFileList
= []
3506 return self
._IdfFileList
3508 ## Return a list of files which can be built from binary
3510 # "Build" binary files are just to copy them to build directory.
3512 # @retval list The list of files which can be built later
3514 def _GetBinaryFiles(self
):
3515 if self
._BinaryFileList
== None:
3516 self
._BinaryFileList
= []
3517 for F
in self
.Module
.Binaries
:
3518 if F
.Target
not in ['COMMON', '*'] and F
.Target
!= self
.BuildTarget
:
3520 self
._BinaryFileList
.append(F
)
3521 self
._ApplyBuildRule
(F
, F
.Type
)
3522 return self
._BinaryFileList
3524 def _GetBuildRules(self
):
3525 if self
._BuildRules
== None:
3527 BuildRuleDatabase
= self
.PlatformInfo
.BuildRule
3528 for Type
in BuildRuleDatabase
.FileTypeList
:
3529 #first try getting build rule by BuildRuleFamily
3530 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.BuildRuleFamily
]
3532 # build type is always module type, but ...
3533 if self
.ModuleType
!= self
.BuildType
:
3534 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.BuildRuleFamily
]
3535 #second try getting build rule by ToolChainFamily
3537 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.ToolChainFamily
]
3539 # build type is always module type, but ...
3540 if self
.ModuleType
!= self
.BuildType
:
3541 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.ToolChainFamily
]
3544 RuleObject
= RuleObject
.Instantiate(self
.Macros
)
3545 BuildRules
[Type
] = RuleObject
3546 for Ext
in RuleObject
.SourceFileExtList
:
3547 BuildRules
[Ext
] = RuleObject
3548 self
._BuildRules
= BuildRules
3549 return self
._BuildRules
3551 def _ApplyBuildRule(self
, File
, FileType
):
3552 if self
._BuildTargets
== None:
3553 self
._IntroBuildTargetList
= set()
3554 self
._FinalBuildTargetList
= set()
3555 self
._BuildTargets
= {}
3556 self
._FileTypes
= {}
3558 SubDirectory
= os
.path
.join(self
.OutputDir
, File
.SubDir
)
3559 if not os
.path
.exists(SubDirectory
):
3560 CreateDirectory(SubDirectory
)
3566 # Make sure to get build rule order value
3568 self
._GetModuleBuildOption
()
3570 while Index
< len(SourceList
):
3571 Source
= SourceList
[Index
]
3575 CreateDirectory(Source
.Dir
)
3577 if File
.IsBinary
and File
== Source
and self
._BinaryFileList
!= None and File
in self
._BinaryFileList
:
3578 # Skip all files that are not binary libraries
3579 if not self
.IsLibrary
:
3581 RuleObject
= self
.BuildRules
[TAB_DEFAULT_BINARY_FILE
]
3582 elif FileType
in self
.BuildRules
:
3583 RuleObject
= self
.BuildRules
[FileType
]
3584 elif Source
.Ext
in self
.BuildRules
:
3585 RuleObject
= self
.BuildRules
[Source
.Ext
]
3587 # stop at no more rules
3589 self
._FinalBuildTargetList
.add(LastTarget
)
3592 FileType
= RuleObject
.SourceFileType
3593 if FileType
not in self
._FileTypes
:
3594 self
._FileTypes
[FileType
] = set()
3595 self
._FileTypes
[FileType
].add(Source
)
3597 # stop at STATIC_LIBRARY for library
3598 if self
.IsLibrary
and FileType
== TAB_STATIC_LIBRARY
:
3600 self
._FinalBuildTargetList
.add(LastTarget
)
3603 Target
= RuleObject
.Apply(Source
, self
.BuildRuleOrder
)
3606 self
._FinalBuildTargetList
.add(LastTarget
)
3608 elif not Target
.Outputs
:
3609 # Only do build for target with outputs
3610 self
._FinalBuildTargetList
.add(Target
)
3612 if FileType
not in self
._BuildTargets
:
3613 self
._BuildTargets
[FileType
] = set()
3614 self
._BuildTargets
[FileType
].add(Target
)
3616 if not Source
.IsBinary
and Source
== File
:
3617 self
._IntroBuildTargetList
.add(Target
)
3619 # to avoid cyclic rule
3620 if FileType
in RuleChain
:
3623 RuleChain
.append(FileType
)
3624 SourceList
.extend(Target
.Outputs
)
3626 FileType
= TAB_UNKNOWN_FILE
3628 def _GetTargets(self
):
3629 if self
._BuildTargets
== None:
3630 self
._IntroBuildTargetList
= set()
3631 self
._FinalBuildTargetList
= set()
3632 self
._BuildTargets
= {}
3633 self
._FileTypes
= {}
3635 #TRICK: call _GetSourceFileList to apply build rule for source files
3636 if self
.SourceFileList
:
3639 #TRICK: call _GetBinaryFileList to apply build rule for binary files
3640 if self
.BinaryFileList
:
3643 return self
._BuildTargets
3645 def _GetIntroTargetList(self
):
3647 return self
._IntroBuildTargetList
3649 def _GetFinalTargetList(self
):
3651 return self
._FinalBuildTargetList
3653 def _GetFileTypes(self
):
3655 return self
._FileTypes
3657 ## Get the list of package object the module depends on
3659 # @retval list The package object list
3661 def _GetDependentPackageList(self
):
3662 return self
.Module
.Packages
3664 ## Return the list of auto-generated code file
3666 # @retval list The list of auto-generated file
3668 def _GetAutoGenFileList(self
):
3669 UniStringAutoGenC
= True
3670 IdfStringAutoGenC
= True
3671 UniStringBinBuffer
= StringIO()
3672 IdfGenBinBuffer
= StringIO()
3673 if self
.BuildType
== 'UEFI_HII':
3674 UniStringAutoGenC
= False
3675 IdfStringAutoGenC
= False
3676 if self
._AutoGenFileList
== None:
3677 self
._AutoGenFileList
= {}
3678 AutoGenC
= TemplateString()
3679 AutoGenH
= TemplateString()
3680 StringH
= TemplateString()
3681 StringIdf
= TemplateString()
3682 GenC
.CreateCode(self
, AutoGenC
, AutoGenH
, StringH
, UniStringAutoGenC
, UniStringBinBuffer
, StringIdf
, IdfStringAutoGenC
, IdfGenBinBuffer
)
3684 # AutoGen.c is generated if there are library classes in inf, or there are object files
3686 if str(AutoGenC
) != "" and (len(self
.Module
.LibraryClasses
) > 0
3687 or TAB_OBJECT_FILE
in self
.FileTypes
):
3688 AutoFile
= PathClass(gAutoGenCodeFileName
, self
.DebugDir
)
3689 self
._AutoGenFileList
[AutoFile
] = str(AutoGenC
)
3690 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3691 if str(AutoGenH
) != "":
3692 AutoFile
= PathClass(gAutoGenHeaderFileName
, self
.DebugDir
)
3693 self
._AutoGenFileList
[AutoFile
] = str(AutoGenH
)
3694 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3695 if str(StringH
) != "":
3696 AutoFile
= PathClass(gAutoGenStringFileName
% {"module_name":self
.Name
}, self
.DebugDir
)
3697 self
._AutoGenFileList
[AutoFile
] = str(StringH
)
3698 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3699 if UniStringBinBuffer
!= None and UniStringBinBuffer
.getvalue() != "":
3700 AutoFile
= PathClass(gAutoGenStringFormFileName
% {"module_name":self
.Name
}, self
.OutputDir
)
3701 self
._AutoGenFileList
[AutoFile
] = UniStringBinBuffer
.getvalue()
3702 AutoFile
.IsBinary
= True
3703 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3704 if UniStringBinBuffer
!= None:
3705 UniStringBinBuffer
.close()
3706 if str(StringIdf
) != "":
3707 AutoFile
= PathClass(gAutoGenImageDefFileName
% {"module_name":self
.Name
}, self
.DebugDir
)
3708 self
._AutoGenFileList
[AutoFile
] = str(StringIdf
)
3709 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3710 if IdfGenBinBuffer
!= None and IdfGenBinBuffer
.getvalue() != "":
3711 AutoFile
= PathClass(gAutoGenIdfFileName
% {"module_name":self
.Name
}, self
.OutputDir
)
3712 self
._AutoGenFileList
[AutoFile
] = IdfGenBinBuffer
.getvalue()
3713 AutoFile
.IsBinary
= True
3714 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3715 if IdfGenBinBuffer
!= None:
3716 IdfGenBinBuffer
.close()
3717 return self
._AutoGenFileList
3719 ## Return the list of library modules explicitly or implicityly used by this module
3720 def _GetLibraryList(self
):
3721 if self
._DependentLibraryList
== None:
3722 # only merge library classes and PCD for non-library module
3724 self
._DependentLibraryList
= []
3726 if self
.AutoGenVersion
< 0x00010005:
3727 self
._DependentLibraryList
= self
.PlatformInfo
.ResolveLibraryReference(self
.Module
)
3729 self
._DependentLibraryList
= self
.PlatformInfo
.ApplyLibraryInstance(self
.Module
)
3730 return self
._DependentLibraryList
3733 def UpdateComments(Recver
, Src
):
3735 if Key
not in Recver
:
3737 Recver
[Key
].extend(Src
[Key
])
3738 ## Get the list of PCDs from current module
3740 # @retval list The list of PCD
3742 def _GetModulePcdList(self
):
3743 if self
._ModulePcdList
== None:
3744 # apply PCD settings from platform
3745 self
._ModulePcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, self
.Module
.Pcds
)
3746 self
.UpdateComments(self
._PcdComments
, self
.Module
.PcdComments
)
3747 return self
._ModulePcdList
3749 ## Get the list of PCDs from dependent libraries
3751 # @retval list The list of PCD
3753 def _GetLibraryPcdList(self
):
3754 if self
._LibraryPcdList
== None:
3756 if not self
.IsLibrary
:
3757 # get PCDs from dependent libraries
3758 for Library
in self
.DependentLibraryList
:
3759 self
.UpdateComments(self
._PcdComments
, Library
.PcdComments
)
3760 for Key
in Library
.Pcds
:
3761 # skip duplicated PCDs
3762 if Key
in self
.Module
.Pcds
or Key
in Pcds
:
3764 Pcds
[Key
] = copy
.copy(Library
.Pcds
[Key
])
3765 # apply PCD settings from platform
3766 self
._LibraryPcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, Pcds
)
3768 self
._LibraryPcdList
= []
3769 return self
._LibraryPcdList
3771 ## Get the GUID value mapping
3773 # @retval dict The mapping between GUID cname and its value
3775 def _GetGuidList(self
):
3776 if self
._GuidList
== None:
3777 self
._GuidList
= sdict()
3778 self
._GuidList
.update(self
.Module
.Guids
)
3779 for Library
in self
.DependentLibraryList
:
3780 self
._GuidList
.update(Library
.Guids
)
3781 self
.UpdateComments(self
._GuidComments
, Library
.GuidComments
)
3782 self
.UpdateComments(self
._GuidComments
, self
.Module
.GuidComments
)
3783 return self
._GuidList
3785 def GetGuidsUsedByPcd(self
):
3786 if self
._GuidsUsedByPcd
== None:
3787 self
._GuidsUsedByPcd
= sdict()
3788 self
._GuidsUsedByPcd
.update(self
.Module
.GetGuidsUsedByPcd())
3789 for Library
in self
.DependentLibraryList
:
3790 self
._GuidsUsedByPcd
.update(Library
.GetGuidsUsedByPcd())
3791 return self
._GuidsUsedByPcd
3792 ## Get the protocol value mapping
3794 # @retval dict The mapping between protocol cname and its value
3796 def _GetProtocolList(self
):
3797 if self
._ProtocolList
== None:
3798 self
._ProtocolList
= sdict()
3799 self
._ProtocolList
.update(self
.Module
.Protocols
)
3800 for Library
in self
.DependentLibraryList
:
3801 self
._ProtocolList
.update(Library
.Protocols
)
3802 self
.UpdateComments(self
._ProtocolComments
, Library
.ProtocolComments
)
3803 self
.UpdateComments(self
._ProtocolComments
, self
.Module
.ProtocolComments
)
3804 return self
._ProtocolList
3806 ## Get the PPI value mapping
3808 # @retval dict The mapping between PPI cname and its value
3810 def _GetPpiList(self
):
3811 if self
._PpiList
== None:
3812 self
._PpiList
= sdict()
3813 self
._PpiList
.update(self
.Module
.Ppis
)
3814 for Library
in self
.DependentLibraryList
:
3815 self
._PpiList
.update(Library
.Ppis
)
3816 self
.UpdateComments(self
._PpiComments
, Library
.PpiComments
)
3817 self
.UpdateComments(self
._PpiComments
, self
.Module
.PpiComments
)
3818 return self
._PpiList
3820 ## Get the list of include search path
3822 # @retval list The list path
3824 def _GetIncludePathList(self
):
3825 if self
._IncludePathList
== None:
3826 self
._IncludePathList
= []
3827 if self
.AutoGenVersion
< 0x00010005:
3828 for Inc
in self
.Module
.Includes
:
3829 if Inc
not in self
._IncludePathList
:
3830 self
._IncludePathList
.append(Inc
)
3832 Inc
= path
.join(Inc
, self
.Arch
.capitalize())
3833 if os
.path
.exists(Inc
) and Inc
not in self
._IncludePathList
:
3834 self
._IncludePathList
.append(Inc
)
3835 # Edk module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
3836 self
._IncludePathList
.append(self
.DebugDir
)
3838 self
._IncludePathList
.append(self
.MetaFile
.Dir
)
3839 self
._IncludePathList
.append(self
.DebugDir
)
3841 for Package
in self
.Module
.Packages
:
3842 PackageDir
= mws
.join(self
.WorkspaceDir
, Package
.MetaFile
.Dir
)
3843 if PackageDir
not in self
._IncludePathList
:
3844 self
._IncludePathList
.append(PackageDir
)
3845 IncludesList
= Package
.Includes
3846 if Package
._PrivateIncludes
:
3847 if not self
.MetaFile
.Path
.startswith(PackageDir
):
3848 IncludesList
= list(set(Package
.Includes
).difference(set(Package
._PrivateIncludes
)))
3849 for Inc
in IncludesList
:
3850 if Inc
not in self
._IncludePathList
:
3851 self
._IncludePathList
.append(str(Inc
))
3852 return self
._IncludePathList
3854 def _GetIncludePathLength(self
):
3855 self
._IncludePathLength
= 0
3856 if self
._IncludePathList
:
3857 for inc
in self
._IncludePathList
:
3858 self
._IncludePathLength
+= len(' ' + inc
)
3859 return self
._IncludePathLength
3861 ## Get HII EX PCDs which maybe used by VFR
3863 # efivarstore used by VFR may relate with HII EX PCDs
3864 # Get the variable name and GUID from efivarstore and HII EX PCD
3865 # List the HII EX PCDs in As Built INF if both name and GUID match.
3867 # @retval list HII EX PCDs
3869 def _GetPcdsMaybeUsedByVfr(self
):
3870 if not self
.SourceFileList
:
3874 for SrcFile
in self
.SourceFileList
:
3875 if SrcFile
.Ext
.lower() != '.vfr':
3877 Vfri
= os
.path
.join(self
.OutputDir
, SrcFile
.BaseName
+ '.i')
3878 if not os
.path
.exists(Vfri
):
3880 VfriFile
= open(Vfri
, 'r')
3881 Content
= VfriFile
.read()
3883 Pos
= Content
.find('efivarstore')
3886 # Make sure 'efivarstore' is the start of efivarstore statement
3887 # In case of the value of 'name' (name = efivarstore) is equal to 'efivarstore'
3890 while Index
>= 0 and Content
[Index
] in ' \t\r\n':
3892 if Index
>= 0 and Content
[Index
] != ';':
3893 Pos
= Content
.find('efivarstore', Pos
+ len('efivarstore'))
3896 # 'efivarstore' must be followed by name and guid
3898 Name
= gEfiVarStoreNamePattern
.search(Content
, Pos
)
3901 Guid
= gEfiVarStoreGuidPattern
.search(Content
, Pos
)
3904 NameArray
= ConvertStringToByteArray('L"' + Name
.group(1) + '"')
3905 NameGuids
.append((NameArray
, GuidStructureStringToGuidString(Guid
.group(1))))
3906 Pos
= Content
.find('efivarstore', Name
.end())
3910 for Pcd
in self
.PlatformInfo
.Platform
.Pcds
.values():
3911 if Pcd
.Type
!= TAB_PCDS_DYNAMIC_EX_HII
:
3913 for SkuName
in Pcd
.SkuInfoList
:
3914 SkuInfo
= Pcd
.SkuInfoList
[SkuName
]
3915 Name
= ConvertStringToByteArray(SkuInfo
.VariableName
)
3916 Value
= GuidValue(SkuInfo
.VariableGuid
, self
.PlatformInfo
.PackageList
, self
.MetaFile
.Path
)
3919 Guid
= GuidStructureStringToGuidString(Value
)
3920 if (Name
, Guid
) in NameGuids
and Pcd
not in HiiExPcds
:
3921 HiiExPcds
.append(Pcd
)
3926 def _GenOffsetBin(self
):
3928 for SourceFile
in self
.Module
.Sources
:
3929 if SourceFile
.Type
.upper() == ".VFR" :
3931 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
3933 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
3934 if SourceFile
.Type
.upper() == ".UNI" :
3936 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
3938 VfrUniBaseName
["UniOffsetName"] = (self
.Name
+ "Strings")
3940 if len(VfrUniBaseName
) == 0:
3942 MapFileName
= os
.path
.join(self
.OutputDir
, self
.Name
+ ".map")
3943 EfiFileName
= os
.path
.join(self
.OutputDir
, self
.Name
+ ".efi")
3944 VfrUniOffsetList
= GetVariableOffset(MapFileName
, EfiFileName
, VfrUniBaseName
.values())
3945 if not VfrUniOffsetList
:
3948 OutputName
= '%sOffset.bin' % self
.Name
3949 UniVfrOffsetFileName
= os
.path
.join( self
.OutputDir
, OutputName
)
3952 fInputfile
= open(UniVfrOffsetFileName
, "wb+", 0)
3954 EdkLogger
.error("build", FILE_OPEN_FAILURE
, "File open failed for %s" % UniVfrOffsetFileName
,None)
3956 # Use a instance of StringIO to cache data
3957 fStringIO
= StringIO('')
3959 for Item
in VfrUniOffsetList
:
3960 if (Item
[0].find("Strings") != -1):
3962 # UNI offset in image.
3964 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
3966 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
3967 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
3968 fStringIO
.write(''.join(UniGuid
))
3969 UniValue
= pack ('Q', int (Item
[1], 16))
3970 fStringIO
.write (UniValue
)
3973 # VFR binary offset in image.
3975 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
3977 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
3978 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
3979 fStringIO
.write(''.join(VfrGuid
))
3981 VfrValue
= pack ('Q', int (Item
[1], 16))
3982 fStringIO
.write (VfrValue
)
3984 # write data into file.
3987 fInputfile
.write (fStringIO
.getvalue())
3989 EdkLogger
.error("build", FILE_WRITE_FAILURE
, "Write data to file %s failed, please check whether the "
3990 "file been locked or using by other applications." %UniVfrOffsetFileName
,None)
3996 ## Create AsBuilt INF file the module
3998 def CreateAsBuiltInf(self
, IsOnlyCopy
= False):
3999 self
.OutputFile
= []
4001 if GlobalData
.gBinCacheDest
:
4002 self
.CopyModuleToCache()
4005 if self
.IsAsBuiltInfCreated
:
4008 # Skip the following code for EDK I inf
4009 if self
.AutoGenVersion
< 0x00010005:
4012 # Skip the following code for libraries
4016 # Skip the following code for modules with no source files
4017 if self
.SourceFileList
== None or self
.SourceFileList
== []:
4020 # Skip the following code for modules without any binary files
4021 if self
.BinaryFileList
<> None and self
.BinaryFileList
<> []:
4024 ### TODO: How to handles mixed source and binary modules
4026 # Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries
4027 # Also find all packages that the DynamicEx PCDs depend on
4032 PcdTokenSpaceList
= []
4033 for Pcd
in self
.ModulePcdList
+ self
.LibraryPcdList
:
4034 if Pcd
.Type
== TAB_PCDS_PATCHABLE_IN_MODULE
:
4035 PatchablePcds
+= [Pcd
]
4036 PcdCheckList
.append((Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, 'PatchableInModule'))
4037 elif Pcd
.Type
in GenC
.gDynamicExPcd
:
4040 PcdCheckList
.append((Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, 'DynamicEx'))
4041 PcdCheckList
.append((Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, 'Dynamic'))
4042 PcdTokenSpaceList
.append(Pcd
.TokenSpaceGuidCName
)
4044 GuidList
.update(self
.GuidList
)
4045 for TokenSpace
in self
.GetGuidsUsedByPcd():
4046 # If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list
4047 # The GUIDs in GUIDs section should really be the GUIDs in source INF or referred by Ex an patch PCDs
4048 if TokenSpace
not in PcdTokenSpaceList
and TokenSpace
in GuidList
:
4049 GuidList
.pop(TokenSpace
)
4050 CheckList
= (GuidList
, self
.PpiList
, self
.ProtocolList
, PcdCheckList
)
4051 for Package
in self
.DerivedPackageList
:
4052 if Package
in Packages
:
4054 BeChecked
= (Package
.Guids
, Package
.Ppis
, Package
.Protocols
, Package
.Pcds
)
4056 for Index
in range(len(BeChecked
)):
4057 for Item
in CheckList
[Index
]:
4058 if Item
in BeChecked
[Index
]:
4059 Packages
+= [Package
]
4064 VfrPcds
= self
._GetPcdsMaybeUsedByVfr
()
4065 for Pkg
in self
.PlatformInfo
.PackageList
:
4068 for VfrPcd
in VfrPcds
:
4069 if ((VfrPcd
.TokenCName
, VfrPcd
.TokenSpaceGuidCName
, 'DynamicEx') in Pkg
.Pcds
or
4070 (VfrPcd
.TokenCName
, VfrPcd
.TokenSpaceGuidCName
, 'Dynamic') in Pkg
.Pcds
):
4074 ModuleType
= self
.ModuleType
4075 if ModuleType
== 'UEFI_DRIVER' and self
.DepexGenerated
:
4076 ModuleType
= 'DXE_DRIVER'
4079 if self
.PcdIsDriver
!= '':
4080 DriverType
= self
.PcdIsDriver
4083 MDefs
= self
.Module
.Defines
4086 'module_name' : self
.Name
,
4087 'module_guid' : Guid
,
4088 'module_module_type' : ModuleType
,
4089 'module_version_string' : [MDefs
['VERSION_STRING']] if 'VERSION_STRING' in MDefs
else [],
4090 'pcd_is_driver_string' : [],
4091 'module_uefi_specification_version' : [],
4092 'module_pi_specification_version' : [],
4093 'module_entry_point' : self
.Module
.ModuleEntryPointList
,
4094 'module_unload_image' : self
.Module
.ModuleUnloadImageList
,
4095 'module_constructor' : self
.Module
.ConstructorList
,
4096 'module_destructor' : self
.Module
.DestructorList
,
4097 'module_shadow' : [MDefs
['SHADOW']] if 'SHADOW' in MDefs
else [],
4098 'module_pci_vendor_id' : [MDefs
['PCI_VENDOR_ID']] if 'PCI_VENDOR_ID' in MDefs
else [],
4099 'module_pci_device_id' : [MDefs
['PCI_DEVICE_ID']] if 'PCI_DEVICE_ID' in MDefs
else [],
4100 'module_pci_class_code' : [MDefs
['PCI_CLASS_CODE']] if 'PCI_CLASS_CODE' in MDefs
else [],
4101 'module_pci_revision' : [MDefs
['PCI_REVISION']] if 'PCI_REVISION' in MDefs
else [],
4102 'module_build_number' : [MDefs
['BUILD_NUMBER']] if 'BUILD_NUMBER' in MDefs
else [],
4103 'module_spec' : [MDefs
['SPEC']] if 'SPEC' in MDefs
else [],
4104 'module_uefi_hii_resource_section' : [MDefs
['UEFI_HII_RESOURCE_SECTION']] if 'UEFI_HII_RESOURCE_SECTION' in MDefs
else [],
4105 'module_uni_file' : [MDefs
['MODULE_UNI_FILE']] if 'MODULE_UNI_FILE' in MDefs
else [],
4106 'module_arch' : self
.Arch
,
4107 'package_item' : ['%s' % (Package
.MetaFile
.File
.replace('\\', '/')) for Package
in Packages
],
4109 'patchablepcd_item' : [],
4111 'protocol_item' : [],
4115 'libraryclasses_item' : []
4118 if 'MODULE_UNI_FILE' in MDefs
:
4119 UNIFile
= os
.path
.join(self
.MetaFile
.Dir
, MDefs
['MODULE_UNI_FILE'])
4120 if os
.path
.isfile(UNIFile
):
4121 shutil
.copy2(UNIFile
, self
.OutputDir
)
4123 if self
.AutoGenVersion
> int(gInfSpecVersion
, 0):
4124 AsBuiltInfDict
['module_inf_version'] = '0x%08x' % self
.AutoGenVersion
4126 AsBuiltInfDict
['module_inf_version'] = gInfSpecVersion
4129 AsBuiltInfDict
['pcd_is_driver_string'] += [DriverType
]
4131 if 'UEFI_SPECIFICATION_VERSION' in self
.Specification
:
4132 AsBuiltInfDict
['module_uefi_specification_version'] += [self
.Specification
['UEFI_SPECIFICATION_VERSION']]
4133 if 'PI_SPECIFICATION_VERSION' in self
.Specification
:
4134 AsBuiltInfDict
['module_pi_specification_version'] += [self
.Specification
['PI_SPECIFICATION_VERSION']]
4136 OutputDir
= self
.OutputDir
.replace('\\', '/').strip('/')
4137 DebugDir
= self
.DebugDir
.replace('\\', '/').strip('/')
4138 for Item
in self
.CodaTargetList
:
4139 File
= Item
.Target
.Path
.replace('\\', '/').strip('/').replace(DebugDir
, '').strip('/')
4140 if File
not in self
.OutputFile
:
4141 self
.OutputFile
.append(File
)
4142 if os
.path
.isabs(File
):
4143 File
= File
.replace('\\', '/').strip('/').replace(OutputDir
, '').strip('/')
4144 if Item
.Target
.Ext
.lower() == '.aml':
4145 AsBuiltInfDict
['binary_item'] += ['ASL|' + File
]
4146 elif Item
.Target
.Ext
.lower() == '.acpi':
4147 AsBuiltInfDict
['binary_item'] += ['ACPI|' + File
]
4148 elif Item
.Target
.Ext
.lower() == '.efi':
4149 AsBuiltInfDict
['binary_item'] += ['PE32|' + self
.Name
+ '.efi']
4151 AsBuiltInfDict
['binary_item'] += ['BIN|' + File
]
4152 if self
.DepexGenerated
:
4153 if self
.Name
+ '.depex' not in self
.OutputFile
:
4154 self
.OutputFile
.append(self
.Name
+ '.depex')
4155 if self
.ModuleType
in ['PEIM']:
4156 AsBuiltInfDict
['binary_item'] += ['PEI_DEPEX|' + self
.Name
+ '.depex']
4157 if self
.ModuleType
in ['DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'UEFI_DRIVER']:
4158 AsBuiltInfDict
['binary_item'] += ['DXE_DEPEX|' + self
.Name
+ '.depex']
4159 if self
.ModuleType
in ['DXE_SMM_DRIVER']:
4160 AsBuiltInfDict
['binary_item'] += ['SMM_DEPEX|' + self
.Name
+ '.depex']
4162 Bin
= self
._GenOffsetBin
()
4164 AsBuiltInfDict
['binary_item'] += ['BIN|%s' % Bin
]
4165 if Bin
not in self
.OutputFile
:
4166 self
.OutputFile
.append(Bin
)
4168 for Root
, Dirs
, Files
in os
.walk(OutputDir
):
4170 if File
.lower().endswith('.pdb'):
4171 AsBuiltInfDict
['binary_item'] += ['DISPOSABLE|' + File
]
4172 if File
not in self
.OutputFile
:
4173 self
.OutputFile
.append(File
)
4174 HeaderComments
= self
.Module
.HeaderComments
4176 for Index
in range(len(HeaderComments
)):
4177 if HeaderComments
[Index
].find('@BinaryHeader') != -1:
4178 HeaderComments
[Index
] = HeaderComments
[Index
].replace('@BinaryHeader', '@file')
4181 AsBuiltInfDict
['header_comments'] = '\n'.join(HeaderComments
[StartPos
:]).replace(':#', '://')
4182 AsBuiltInfDict
['tail_comments'] = '\n'.join(self
.Module
.TailComments
)
4185 (self
.ProtocolList
, self
._ProtocolComments
, 'protocol_item'),
4186 (self
.PpiList
, self
._PpiComments
, 'ppi_item'),
4187 (GuidList
, self
._GuidComments
, 'guid_item')
4189 for Item
in GenList
:
4190 for CName
in Item
[0]:
4192 if CName
in Item
[1]:
4193 Comments
= '\n '.join(Item
[1][CName
])
4196 Entry
= Comments
+ '\n ' + CName
4197 AsBuiltInfDict
[Item
[2]].append(Entry
)
4198 PatchList
= parsePcdInfoFromMapFile(
4199 os
.path
.join(self
.OutputDir
, self
.Name
+ '.map'),
4200 os
.path
.join(self
.OutputDir
, self
.Name
+ '.efi')
4203 for Pcd
in PatchablePcds
:
4204 TokenCName
= Pcd
.TokenCName
4205 for PcdItem
in GlobalData
.MixedPcd
:
4206 if (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
) in GlobalData
.MixedPcd
[PcdItem
]:
4207 TokenCName
= PcdItem
[0]
4209 for PatchPcd
in PatchList
:
4210 if TokenCName
== PatchPcd
[0]:
4215 if Pcd
.DatumType
== 'BOOLEAN':
4216 BoolValue
= Pcd
.DefaultValue
.upper()
4217 if BoolValue
== 'TRUE':
4218 Pcd
.DefaultValue
= '1'
4219 elif BoolValue
== 'FALSE':
4220 Pcd
.DefaultValue
= '0'
4222 if Pcd
.DatumType
in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:
4223 HexFormat
= '0x%02x'
4224 if Pcd
.DatumType
== 'UINT16':
4225 HexFormat
= '0x%04x'
4226 elif Pcd
.DatumType
== 'UINT32':
4227 HexFormat
= '0x%08x'
4228 elif Pcd
.DatumType
== 'UINT64':
4229 HexFormat
= '0x%016x'
4230 PcdValue
= HexFormat
% int(Pcd
.DefaultValue
, 0)
4232 if Pcd
.MaxDatumSize
== None or Pcd
.MaxDatumSize
== '':
4233 EdkLogger
.error("build", AUTOGEN_ERROR
,
4234 "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd
.TokenSpaceGuidCName
, TokenCName
)
4236 ArraySize
= int(Pcd
.MaxDatumSize
, 0)
4237 PcdValue
= Pcd
.DefaultValue
4238 if PcdValue
[0] != '{':
4240 if PcdValue
[0] == 'L':
4242 PcdValue
= PcdValue
.lstrip('L')
4243 PcdValue
= eval(PcdValue
)
4245 for Index
in range(0, len(PcdValue
)):
4247 CharVal
= ord(PcdValue
[Index
])
4248 NewValue
= NewValue
+ '0x%02x' % (CharVal
& 0x00FF) + ', ' \
4249 + '0x%02x' % (CharVal
>> 8) + ', '
4251 NewValue
= NewValue
+ '0x%02x' % (ord(PcdValue
[Index
]) % 0x100) + ', '
4254 Padding
= Padding
* 2
4255 ArraySize
= ArraySize
/ 2
4256 if ArraySize
< (len(PcdValue
) + 1):
4257 EdkLogger
.error("build", AUTOGEN_ERROR
,
4258 "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd
.TokenSpaceGuidCName
, TokenCName
)
4260 if ArraySize
> len(PcdValue
) + 1:
4261 NewValue
= NewValue
+ Padding
* (ArraySize
- len(PcdValue
) - 1)
4262 PcdValue
= NewValue
+ Padding
.strip().rstrip(',') + '}'
4263 elif len(PcdValue
.split(',')) <= ArraySize
:
4264 PcdValue
= PcdValue
.rstrip('}') + ', 0x00' * (ArraySize
- len(PcdValue
.split(',')))
4267 EdkLogger
.error("build", AUTOGEN_ERROR
,
4268 "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd
.TokenSpaceGuidCName
, TokenCName
)
4270 PcdItem
= '%s.%s|%s|0x%X' % \
4271 (Pcd
.TokenSpaceGuidCName
, TokenCName
, PcdValue
, PatchPcd
[1])
4273 if (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
) in self
._PcdComments
:
4274 PcdComments
= '\n '.join(self
._PcdComments
[Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
])
4276 PcdItem
= PcdComments
+ '\n ' + PcdItem
4277 AsBuiltInfDict
['patchablepcd_item'].append(PcdItem
)
4280 for Pcd
in Pcds
+ VfrPcds
:
4285 TokenCName
= Pcd
.TokenCName
4286 for PcdItem
in GlobalData
.MixedPcd
:
4287 if (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
) in GlobalData
.MixedPcd
[PcdItem
]:
4288 TokenCName
= PcdItem
[0]
4290 if Pcd
.Type
== TAB_PCDS_DYNAMIC_EX_HII
:
4291 for SkuName
in Pcd
.SkuInfoList
:
4292 SkuInfo
= Pcd
.SkuInfoList
[SkuName
]
4293 SkuId
= SkuInfo
.SkuId
4294 HiiInfo
= '## %s|%s|%s' % (SkuInfo
.VariableName
, SkuInfo
.VariableGuid
, SkuInfo
.VariableOffset
)
4298 # Don't generate duplicated HII PCD
4300 if (SkuId
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
) in HiiPcds
:
4303 HiiPcds
.append((SkuId
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
4304 if (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
) in self
._PcdComments
:
4305 PcdCommentList
= self
._PcdComments
[Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
][:]
4309 for Index
, Comment
in enumerate(PcdCommentList
):
4310 for Usage
in UsageList
:
4311 if Comment
.find(Usage
) != -1:
4315 if UsageIndex
!= -1:
4316 PcdCommentList
[UsageIndex
] = '## %s %s %s' % (UsageStr
, HiiInfo
, PcdCommentList
[UsageIndex
].replace(UsageStr
, ''))
4318 PcdCommentList
.append('## UNDEFINED ' + HiiInfo
)
4319 PcdComments
= '\n '.join(PcdCommentList
)
4320 PcdEntry
= Pcd
.TokenSpaceGuidCName
+ '.' + TokenCName
4322 PcdEntry
= PcdComments
+ '\n ' + PcdEntry
4323 AsBuiltInfDict
['pcd_item'] += [PcdEntry
]
4324 for Item
in self
.BuildOption
:
4325 if 'FLAGS' in self
.BuildOption
[Item
]:
4326 AsBuiltInfDict
['flags_item'] += ['%s:%s_%s_%s_%s_FLAGS = %s' % (self
.ToolChainFamily
, self
.BuildTarget
, self
.ToolChain
, self
.Arch
, Item
, self
.BuildOption
[Item
]['FLAGS'].strip())]
4328 # Generated LibraryClasses section in comments.
4329 for Library
in self
.LibraryAutoGenList
:
4330 AsBuiltInfDict
['libraryclasses_item'] += [Library
.MetaFile
.File
.replace('\\', '/')]
4332 # Generated UserExtensions TianoCore section.
4333 # All tianocore user extensions are copied.
4335 for TianoCore
in self
._GetTianoCoreUserExtensionList
():
4336 UserExtStr
+= '\n'.join(TianoCore
)
4337 ExtensionFile
= os
.path
.join(self
.MetaFile
.Dir
, TianoCore
[1])
4338 if os
.path
.isfile(ExtensionFile
):
4339 shutil
.copy2(ExtensionFile
, self
.OutputDir
)
4340 AsBuiltInfDict
['userextension_tianocore_item'] = UserExtStr
4342 # Generated depex expression section in comments.
4343 AsBuiltInfDict
['depexsection_item'] = ''
4344 DepexExpresion
= self
._GetDepexExpresionString
()
4346 AsBuiltInfDict
['depexsection_item'] = DepexExpresion
4348 AsBuiltInf
= TemplateString()
4349 AsBuiltInf
.Append(gAsBuiltInfHeaderString
.Replace(AsBuiltInfDict
))
4351 SaveFileOnChange(os
.path
.join(self
.OutputDir
, self
.Name
+ '.inf'), str(AsBuiltInf
), False)
4353 self
.IsAsBuiltInfCreated
= True
4354 if GlobalData
.gBinCacheDest
:
4355 self
.CopyModuleToCache()
4357 def CopyModuleToCache(self
):
4358 FileDir
= path
.join(GlobalData
.gBinCacheDest
, self
.Arch
, self
.SourceDir
, self
.MetaFile
.BaseName
)
4359 CreateDirectory (FileDir
)
4360 HashFile
= path
.join(self
.BuildDir
, self
.Name
+ '.hash')
4361 ModuleFile
= path
.join(self
.OutputDir
, self
.Name
+ '.inf')
4362 if os
.path
.exists(HashFile
):
4363 shutil
.copy2(HashFile
, FileDir
)
4364 if os
.path
.exists(ModuleFile
):
4365 shutil
.copy2(ModuleFile
, FileDir
)
4366 if not self
.OutputFile
:
4367 Ma
= self
.Workspace
.BuildDatabase
[PathClass(ModuleFile
), self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
4368 self
.OutputFile
= Ma
.Binaries
4370 for File
in self
.OutputFile
:
4372 if not os
.path
.isabs(File
):
4373 File
= os
.path
.join(self
.OutputDir
, File
)
4374 if os
.path
.exists(File
):
4375 shutil
.copy2(File
, FileDir
)
4377 def AttemptModuleCacheCopy(self
):
4378 if self
.IsBinaryModule
:
4380 FileDir
= path
.join(GlobalData
.gBinCacheSource
, self
.Arch
, self
.SourceDir
, self
.MetaFile
.BaseName
)
4381 HashFile
= path
.join(FileDir
, self
.Name
+ '.hash')
4382 if os
.path
.exists(HashFile
):
4383 f
= open(HashFile
, 'r')
4384 CacheHash
= f
.read()
4386 if GlobalData
.gModuleHash
[self
.Arch
][self
.Name
]:
4387 if CacheHash
== GlobalData
.gModuleHash
[self
.Arch
][self
.Name
]:
4388 for root
, dir, files
in os
.walk(FileDir
):
4390 if self
.Name
+ '.hash' in f
:
4391 shutil
.copy2(HashFile
, self
.BuildDir
)
4393 File
= path
.join(root
, f
)
4394 shutil
.copy2(File
, self
.OutputDir
)
4395 if self
.Name
== "PcdPeim" or self
.Name
== "PcdDxe":
4396 CreatePcdDatabaseCode(self
, TemplateString(), TemplateString())
4400 ## Create makefile for the module and its dependent libraries
4402 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of
4403 # dependent libraries will be created
4405 def CreateMakeFile(self
, CreateLibraryMakeFile
=True, GenFfsList
= []):
4406 # Ignore generating makefile when it is a binary module
4407 if self
.IsBinaryModule
:
4410 if self
.IsMakeFileCreated
:
4412 self
.GenFfsList
= GenFfsList
4413 if not self
.IsLibrary
and CreateLibraryMakeFile
:
4414 for LibraryAutoGen
in self
.LibraryAutoGenList
:
4415 LibraryAutoGen
.CreateMakeFile()
4420 if len(self
.CustomMakefile
) == 0:
4421 Makefile
= GenMake
.ModuleMakefile(self
)
4423 Makefile
= GenMake
.CustomMakefile(self
)
4424 if Makefile
.Generate():
4425 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for module %s [%s]" %
4426 (self
.Name
, self
.Arch
))
4428 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for module %s [%s]" %
4429 (self
.Name
, self
.Arch
))
4431 self
.CreateTimeStamp(Makefile
)
4432 self
.IsMakeFileCreated
= True
4434 def CopyBinaryFiles(self
):
4435 for File
in self
.Module
.Binaries
:
4437 DstPath
= os
.path
.join(self
.OutputDir
, os
.path
.basename(SrcPath
))
4438 CopyLongFilePath(SrcPath
, DstPath
)
4439 ## Create autogen code for the module and its dependent libraries
4441 # @param CreateLibraryCodeFile Flag indicating if or not the code of
4442 # dependent libraries will be created
4444 def CreateCodeFile(self
, CreateLibraryCodeFile
=True):
4445 if self
.IsCodeFileCreated
:
4448 # Need to generate PcdDatabase even PcdDriver is binarymodule
4449 if self
.IsBinaryModule
and self
.PcdIsDriver
!= '':
4450 CreatePcdDatabaseCode(self
, TemplateString(), TemplateString())
4452 if self
.IsBinaryModule
:
4454 self
.CopyBinaryFiles()
4457 if not self
.IsLibrary
and CreateLibraryCodeFile
:
4458 for LibraryAutoGen
in self
.LibraryAutoGenList
:
4459 LibraryAutoGen
.CreateCodeFile()
4465 IgoredAutoGenList
= []
4467 for File
in self
.AutoGenFileList
:
4468 if GenC
.Generate(File
.Path
, self
.AutoGenFileList
[File
], File
.IsBinary
):
4469 #Ignore Edk AutoGen.c
4470 if self
.AutoGenVersion
< 0x00010005 and File
.Name
== 'AutoGen.c':
4473 AutoGenList
.append(str(File
))
4475 IgoredAutoGenList
.append(str(File
))
4477 # Skip the following code for EDK I inf
4478 if self
.AutoGenVersion
< 0x00010005:
4481 for ModuleType
in self
.DepexList
:
4482 # Ignore empty [depex] section or [depex] section for "USER_DEFINED" module
4483 if len(self
.DepexList
[ModuleType
]) == 0 or ModuleType
== "USER_DEFINED":
4486 Dpx
= GenDepex
.DependencyExpression(self
.DepexList
[ModuleType
], ModuleType
, True)
4487 DpxFile
= gAutoGenDepexFileName
% {"module_name" : self
.Name
}
4489 if len(Dpx
.PostfixNotation
) <> 0:
4490 self
.DepexGenerated
= True
4492 if Dpx
.Generate(path
.join(self
.OutputDir
, DpxFile
)):
4493 AutoGenList
.append(str(DpxFile
))
4495 IgoredAutoGenList
.append(str(DpxFile
))
4497 if IgoredAutoGenList
== []:
4498 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] files for module %s [%s]" %
4499 (" ".join(AutoGenList
), self
.Name
, self
.Arch
))
4500 elif AutoGenList
== []:
4501 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of [%s] files for module %s [%s]" %
4502 (" ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
4504 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] (skipped %s) files for module %s [%s]" %
4505 (" ".join(AutoGenList
), " ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
4507 self
.IsCodeFileCreated
= True
4510 ## Summarize the ModuleAutoGen objects of all libraries used by this module
4511 def _GetLibraryAutoGenList(self
):
4512 if self
._LibraryAutoGenList
== None:
4513 self
._LibraryAutoGenList
= []
4514 for Library
in self
.DependentLibraryList
:
4521 self
.PlatformInfo
.MetaFile
4523 if La
not in self
._LibraryAutoGenList
:
4524 self
._LibraryAutoGenList
.append(La
)
4525 for Lib
in La
.CodaTargetList
:
4526 self
._ApplyBuildRule
(Lib
.Target
, TAB_UNKNOWN_FILE
)
4527 return self
._LibraryAutoGenList
4529 def GenModuleHash(self
):
4530 if self
.Arch
not in GlobalData
.gModuleHash
:
4531 GlobalData
.gModuleHash
[self
.Arch
] = {}
4533 # Add Platform level hash
4534 m
.update(GlobalData
.gPlatformHash
)
4535 # Add Package level hash
4536 if self
.DependentPackageList
:
4537 for Pkg
in self
.DependentPackageList
:
4538 if Pkg
.PackageName
in GlobalData
.gPackageHash
[self
.Arch
]:
4539 m
.update(GlobalData
.gPackageHash
[self
.Arch
][Pkg
.PackageName
])
4542 if self
.LibraryAutoGenList
:
4543 for Lib
in self
.LibraryAutoGenList
:
4544 if Lib
.Name
not in GlobalData
.gModuleHash
[self
.Arch
]:
4546 m
.update(GlobalData
.gModuleHash
[self
.Arch
][Lib
.Name
])
4549 f
= open(str(self
.MetaFile
), 'r')
4553 # Add Module's source files
4554 if self
.SourceFileList
:
4555 for File
in self
.SourceFileList
:
4556 f
= open(str(File
), 'r')
4561 ModuleHashFile
= path
.join(self
.BuildDir
, self
.Name
+ ".hash")
4562 if self
.Name
not in GlobalData
.gModuleHash
[self
.Arch
]:
4563 GlobalData
.gModuleHash
[self
.Arch
][self
.Name
] = m
.hexdigest()
4564 if GlobalData
.gBinCacheSource
:
4565 CacheValid
= self
.AttemptModuleCacheCopy()
4568 return SaveFileOnChange(ModuleHashFile
, m
.hexdigest(), True)
4570 ## Decide whether we can skip the ModuleAutoGen process
4571 def CanSkipbyHash(self
):
4572 if GlobalData
.gUseHashCache
:
4573 return not self
.GenModuleHash()
4575 ## Decide whether we can skip the ModuleAutoGen process
4576 # If any source file is newer than the module than we cannot skip
4579 if not os
.path
.exists(self
.GetTimeStampPath()):
4581 #last creation time of the module
4582 DstTimeStamp
= os
.stat(self
.GetTimeStampPath())[8]
4584 SrcTimeStamp
= self
.Workspace
._SrcTimeStamp
4585 if SrcTimeStamp
> DstTimeStamp
:
4588 with
open(self
.GetTimeStampPath(),'r') as f
:
4590 source
= source
.rstrip('\n')
4591 if not os
.path
.exists(source
):
4593 if source
not in ModuleAutoGen
.TimeDict
:
4594 ModuleAutoGen
.TimeDict
[source
] = os
.stat(source
)[8]
4595 if ModuleAutoGen
.TimeDict
[source
] > DstTimeStamp
:
4599 def GetTimeStampPath(self
):
4600 if self
._TimeStampPath
== None:
4601 self
._TimeStampPath
= os
.path
.join(self
.MakeFileDir
, 'AutoGenTimeStamp')
4602 return self
._TimeStampPath
4603 def CreateTimeStamp(self
, Makefile
):
4607 FileSet
.add (self
.MetaFile
.Path
)
4609 for SourceFile
in self
.Module
.Sources
:
4610 FileSet
.add (SourceFile
.Path
)
4612 for Lib
in self
.DependentLibraryList
:
4613 FileSet
.add (Lib
.MetaFile
.Path
)
4615 for f
in self
.AutoGenDepSet
:
4616 FileSet
.add (f
.Path
)
4618 if os
.path
.exists (self
.GetTimeStampPath()):
4619 os
.remove (self
.GetTimeStampPath())
4620 with
open(self
.GetTimeStampPath(), 'w+') as file:
4624 Module
= property(_GetModule
)
4625 Name
= property(_GetBaseName
)
4626 Guid
= property(_GetGuid
)
4627 Version
= property(_GetVersion
)
4628 ModuleType
= property(_GetModuleType
)
4629 ComponentType
= property(_GetComponentType
)
4630 BuildType
= property(_GetBuildType
)
4631 PcdIsDriver
= property(_GetPcdIsDriver
)
4632 AutoGenVersion
= property(_GetAutoGenVersion
)
4633 Macros
= property(_GetMacros
)
4634 Specification
= property(_GetSpecification
)
4636 IsLibrary
= property(_IsLibrary
)
4637 IsBinaryModule
= property(_IsBinaryModule
)
4638 BuildDir
= property(_GetBuildDir
)
4639 OutputDir
= property(_GetOutputDir
)
4640 FfsOutputDir
= property(_GetFfsOutputDir
)
4641 DebugDir
= property(_GetDebugDir
)
4642 MakeFileDir
= property(_GetMakeFileDir
)
4643 CustomMakefile
= property(_GetCustomMakefile
)
4645 IncludePathList
= property(_GetIncludePathList
)
4646 IncludePathLength
= property(_GetIncludePathLength
)
4647 AutoGenFileList
= property(_GetAutoGenFileList
)
4648 UnicodeFileList
= property(_GetUnicodeFileList
)
4649 VfrFileList
= property(_GetVfrFileList
)
4650 SourceFileList
= property(_GetSourceFileList
)
4651 BinaryFileList
= property(_GetBinaryFiles
) # FileType : [File List]
4652 Targets
= property(_GetTargets
)
4653 IntroTargetList
= property(_GetIntroTargetList
)
4654 CodaTargetList
= property(_GetFinalTargetList
)
4655 FileTypes
= property(_GetFileTypes
)
4656 BuildRules
= property(_GetBuildRules
)
4657 IdfFileList
= property(_GetIdfFileList
)
4659 DependentPackageList
= property(_GetDependentPackageList
)
4660 DependentLibraryList
= property(_GetLibraryList
)
4661 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
4662 DerivedPackageList
= property(_GetDerivedPackageList
)
4664 ModulePcdList
= property(_GetModulePcdList
)
4665 LibraryPcdList
= property(_GetLibraryPcdList
)
4666 GuidList
= property(_GetGuidList
)
4667 ProtocolList
= property(_GetProtocolList
)
4668 PpiList
= property(_GetPpiList
)
4669 DepexList
= property(_GetDepexTokenList
)
4670 DxsFile
= property(_GetDxsFile
)
4671 DepexExpressionList
= property(_GetDepexExpressionTokenList
)
4672 BuildOption
= property(_GetModuleBuildOption
)
4673 BuildOptionIncPathList
= property(_GetBuildOptionIncPathList
)
4674 BuildCommand
= property(_GetBuildCommand
)
4676 FixedAtBuildPcds
= property(_GetFixedAtBuildPcds
)
4678 # This acts like the main() function for the script, unless it is 'import'ed into another script.
4679 if __name__
== '__main__':