2 # Generate AutoGen.h, AutoGen.c and *.depex files
4 # Copyright (c) 2007 - 2017, 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 ## Regular expression for splitting Dependency Expression string into tokens
48 gDepexTokenPattern
= re
.compile("(\(|\)|\w+| \S+\.inf)")
51 # Match name = variable
53 gEfiVarStoreNamePattern
= re
.compile("\s*name\s*=\s*(\w+)")
55 # The format of guid in efivarstore statement likes following and must be correct:
56 # guid = {0xA04A27f4, 0xDF00, 0x4D42, {0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D}}
58 gEfiVarStoreGuidPattern
= re
.compile("\s*guid\s*=\s*({.*?{.*?}\s*})")
60 ## Mapping Makefile type
61 gMakeTypeMap
= {"MSFT":"nmake", "GCC":"gmake"}
64 ## Build rule configuration file
65 gDefaultBuildRuleFile
= 'build_rule.txt'
67 ## Tools definition configuration file
68 gDefaultToolsDefFile
= 'tools_def.txt'
70 ## Build rule default version
71 AutoGenReqBuildRuleVerNum
= "0.1"
73 ## default file name for AutoGen
74 gAutoGenCodeFileName
= "AutoGen.c"
75 gAutoGenHeaderFileName
= "AutoGen.h"
76 gAutoGenStringFileName
= "%(module_name)sStrDefs.h"
77 gAutoGenStringFormFileName
= "%(module_name)sStrDefs.hpk"
78 gAutoGenDepexFileName
= "%(module_name)s.depex"
79 gAutoGenImageDefFileName
= "%(module_name)sImgDefs.h"
80 gAutoGenIdfFileName
= "%(module_name)sIdf.hpk"
81 gInfSpecVersion
= "0x00010017"
84 # Template string to generic AsBuilt INF
86 gAsBuiltInfHeaderString
= TemplateString("""${header_comments}
92 INF_VERSION = ${module_inf_version}
93 BASE_NAME = ${module_name}
94 FILE_GUID = ${module_guid}
95 MODULE_TYPE = ${module_module_type}${BEGIN}
96 VERSION_STRING = ${module_version_string}${END}${BEGIN}
97 PCD_IS_DRIVER = ${pcd_is_driver_string}${END}${BEGIN}
98 UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN}
99 PI_SPECIFICATION_VERSION = ${module_pi_specification_version}${END}${BEGIN}
100 ENTRY_POINT = ${module_entry_point}${END}${BEGIN}
101 UNLOAD_IMAGE = ${module_unload_image}${END}${BEGIN}
102 CONSTRUCTOR = ${module_constructor}${END}${BEGIN}
103 DESTRUCTOR = ${module_destructor}${END}${BEGIN}
104 SHADOW = ${module_shadow}${END}${BEGIN}
105 PCI_VENDOR_ID = ${module_pci_vendor_id}${END}${BEGIN}
106 PCI_DEVICE_ID = ${module_pci_device_id}${END}${BEGIN}
107 PCI_CLASS_CODE = ${module_pci_class_code}${END}${BEGIN}
108 PCI_REVISION = ${module_pci_revision}${END}${BEGIN}
109 BUILD_NUMBER = ${module_build_number}${END}${BEGIN}
110 SPEC = ${module_spec}${END}${BEGIN}
111 UEFI_HII_RESOURCE_SECTION = ${module_uefi_hii_resource_section}${END}${BEGIN}
112 MODULE_UNI_FILE = ${module_uni_file}${END}
114 [Packages.${module_arch}]${BEGIN}
115 ${package_item}${END}
117 [Binaries.${module_arch}]${BEGIN}
120 [PatchPcd.${module_arch}]${BEGIN}
124 [Protocols.${module_arch}]${BEGIN}
128 [Ppis.${module_arch}]${BEGIN}
132 [Guids.${module_arch}]${BEGIN}
136 [PcdEx.${module_arch}]${BEGIN}
140 [LibraryClasses.${module_arch}]
141 ## @LIB_INSTANCES${BEGIN}
142 # ${libraryclasses_item}${END}
148 [BuildOptions.${module_arch}]
150 ## ${flags_item}${END}
153 ## Base class for AutoGen
155 # This class just implements the cache mechanism of AutoGen objects.
157 class AutoGen(object):
158 # database to maintain the objects of xxxAutoGen
159 _CACHE_
= {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}
163 # @param Class class object of real AutoGen class
164 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
165 # @param Workspace Workspace directory or WorkspaceAutoGen object
166 # @param MetaFile The path of meta file
167 # @param Target Build target
168 # @param Toolchain Tool chain name
169 # @param Arch Target arch
170 # @param *args The specific class related parameters
171 # @param **kwargs The specific class related dict parameters
173 def __new__(Class
, Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
174 # check if the object has been created
175 Key
= (Target
, Toolchain
)
176 if Key
not in Class
._CACHE
_ or Arch
not in Class
._CACHE
_[Key
] \
177 or MetaFile
not in Class
._CACHE
_[Key
][Arch
]:
178 AutoGenObject
= super(AutoGen
, Class
).__new
__(Class
)
179 # call real constructor
180 if not AutoGenObject
._Init
(Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
182 if Key
not in Class
._CACHE
_:
183 Class
._CACHE
_[Key
] = {}
184 if Arch
not in Class
._CACHE
_[Key
]:
185 Class
._CACHE
_[Key
][Arch
] = {}
186 Class
._CACHE
_[Key
][Arch
][MetaFile
] = AutoGenObject
188 AutoGenObject
= Class
._CACHE
_[Key
][Arch
][MetaFile
]
194 # The file path of platform file will be used to represent hash value of this object
196 # @retval int Hash value of the file path of platform file
199 return hash(self
.MetaFile
)
203 # The file path of platform file will be used to represent this object
205 # @retval string String of platform file path
208 return str(self
.MetaFile
)
211 def __eq__(self
, Other
):
212 return Other
and self
.MetaFile
== Other
214 ## Workspace AutoGen class
216 # This class is used mainly to control the whole platform build for different
217 # architecture. This class will generate top level makefile.
219 class WorkspaceAutoGen(AutoGen
):
220 ## Real constructor of WorkspaceAutoGen
222 # This method behaves the same as __init__ except that it needs explicit invoke
223 # (in super class's __new__ method)
225 # @param WorkspaceDir Root directory of workspace
226 # @param ActivePlatform Meta-file of active platform
227 # @param Target Build target
228 # @param Toolchain Tool chain name
229 # @param ArchList List of architecture of current build
230 # @param MetaFileDb Database containing meta-files
231 # @param BuildConfig Configuration of build
232 # @param ToolDefinition Tool chain definitions
233 # @param FlashDefinitionFile File of flash definition
234 # @param Fds FD list to be generated
235 # @param Fvs FV list to be generated
236 # @param Caps Capsule list to be generated
237 # @param SkuId SKU id from command line
239 def _Init(self
, WorkspaceDir
, ActivePlatform
, Target
, Toolchain
, ArchList
, MetaFileDb
,
240 BuildConfig
, ToolDefinition
, FlashDefinitionFile
='', Fds
=None, Fvs
=None, Caps
=None, SkuId
='', UniFlag
=None,
241 Progress
=None, BuildModule
=None):
248 self
.BuildDatabase
= MetaFileDb
249 self
.MetaFile
= ActivePlatform
250 self
.WorkspaceDir
= WorkspaceDir
251 self
.Platform
= self
.BuildDatabase
[self
.MetaFile
, 'COMMON', Target
, Toolchain
]
252 GlobalData
.gActivePlatform
= self
.Platform
253 self
.BuildTarget
= Target
254 self
.ToolChain
= Toolchain
255 self
.ArchList
= ArchList
257 self
.UniFlag
= UniFlag
259 self
.TargetTxt
= BuildConfig
260 self
.ToolDef
= ToolDefinition
261 self
.FdfFile
= FlashDefinitionFile
262 self
.FdTargetList
= Fds
263 self
.FvTargetList
= Fvs
264 self
.CapTargetList
= Caps
265 self
.AutoGenObjectList
= []
267 # there's many relative directory operations, so ...
268 os
.chdir(self
.WorkspaceDir
)
273 if not self
.ArchList
:
274 ArchList
= set(self
.Platform
.SupArchList
)
276 ArchList
= set(self
.ArchList
) & set(self
.Platform
.SupArchList
)
278 EdkLogger
.error("build", PARAMETER_INVALID
,
279 ExtraData
= "Invalid ARCH specified. [Valid ARCH: %s]" % (" ".join(self
.Platform
.SupArchList
)))
280 elif self
.ArchList
and len(ArchList
) != len(self
.ArchList
):
281 SkippedArchList
= set(self
.ArchList
).symmetric_difference(set(self
.Platform
.SupArchList
))
282 EdkLogger
.verbose("\nArch [%s] is ignored because the platform supports [%s] only!"
283 % (" ".join(SkippedArchList
), " ".join(self
.Platform
.SupArchList
)))
284 self
.ArchList
= tuple(ArchList
)
286 # Validate build target
287 if self
.BuildTarget
not in self
.Platform
.BuildTargets
:
288 EdkLogger
.error("build", PARAMETER_INVALID
,
289 ExtraData
="Build target [%s] is not supported by the platform. [Valid target: %s]"
290 % (self
.BuildTarget
, " ".join(self
.Platform
.BuildTargets
)))
293 # parse FDF file to get PCDs in it, if any
295 self
.FdfFile
= self
.Platform
.FlashDefinition
299 EdkLogger
.info('%-16s = %s' % ("Architecture(s)", ' '.join(self
.ArchList
)))
300 EdkLogger
.info('%-16s = %s' % ("Build target", self
.BuildTarget
))
301 EdkLogger
.info('%-16s = %s' % ("Toolchain", self
.ToolChain
))
303 EdkLogger
.info('\n%-24s = %s' % ("Active Platform", self
.Platform
))
305 EdkLogger
.info('%-24s = %s' % ("Active Module", BuildModule
))
308 EdkLogger
.info('%-24s = %s' % ("Flash Image Definition", self
.FdfFile
))
310 EdkLogger
.verbose("\nFLASH_DEFINITION = %s" % self
.FdfFile
)
313 Progress
.Start("\nProcessing meta-data")
317 # Mark now build in AutoGen Phase
319 GlobalData
.gAutoGenPhase
= True
320 Fdf
= FdfParser(self
.FdfFile
.Path
)
322 GlobalData
.gFdfParser
= Fdf
323 GlobalData
.gAutoGenPhase
= False
324 PcdSet
= Fdf
.Profile
.PcdDict
325 if Fdf
.CurrentFdName
and Fdf
.CurrentFdName
in Fdf
.Profile
.FdDict
:
326 FdDict
= Fdf
.Profile
.FdDict
[Fdf
.CurrentFdName
]
327 for FdRegion
in FdDict
.RegionList
:
328 if str(FdRegion
.RegionType
) is 'FILE' and self
.Platform
.VpdToolGuid
in str(FdRegion
.RegionDataList
):
329 if int(FdRegion
.Offset
) % 8 != 0:
330 EdkLogger
.error("build", FORMAT_INVALID
, 'The VPD Base Address %s must be 8-byte aligned.' % (FdRegion
.Offset
))
331 ModuleList
= Fdf
.Profile
.InfList
332 self
.FdfProfile
= Fdf
.Profile
333 for fvname
in self
.FvTargetList
:
334 if fvname
.upper() not in self
.FdfProfile
.FvDict
:
335 EdkLogger
.error("build", OPTION_VALUE_INVALID
,
336 "No such an FV in FDF file: %s" % fvname
)
338 # In DSC file may use FILE_GUID to override the module, then in the Platform.Modules use FILE_GUIDmodule.inf as key,
339 # but the path (self.MetaFile.Path) is the real path
340 for key
in self
.FdfProfile
.InfDict
:
344 for Arch
in self
.ArchList
:
345 Platform_cache
[Arch
] = self
.BuildDatabase
[self
.MetaFile
, Arch
, Target
, Toolchain
]
346 MetaFile_cache
[Arch
] = []
347 for Pkey
in Platform_cache
[Arch
].Modules
.keys():
348 MetaFile_cache
[Arch
].append(Platform_cache
[Arch
].Modules
[Pkey
].MetaFile
)
349 for Inf
in self
.FdfProfile
.InfDict
[key
]:
350 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
)
351 for Arch
in self
.ArchList
:
352 if ModuleFile
in MetaFile_cache
[Arch
]:
355 ModuleData
= self
.BuildDatabase
[ModuleFile
, Arch
, Target
, Toolchain
]
356 if not ModuleData
.IsBinaryModule
:
357 EdkLogger
.error('build', PARSER_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile
)
360 for Arch
in self
.ArchList
:
362 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
, Target
, Toolchain
]
364 for Pkey
in Platform
.Modules
.keys():
365 MetaFileList
.append(Platform
.Modules
[Pkey
].MetaFile
)
366 for Inf
in self
.FdfProfile
.InfDict
[key
]:
367 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
)
368 if ModuleFile
in MetaFileList
:
370 ModuleData
= self
.BuildDatabase
[ModuleFile
, Arch
, Target
, Toolchain
]
371 if not ModuleData
.IsBinaryModule
:
372 EdkLogger
.error('build', PARSER_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile
)
377 self
.FdfProfile
= None
378 if self
.FdTargetList
:
379 EdkLogger
.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self
.FdTargetList
))
380 self
.FdTargetList
= []
381 if self
.FvTargetList
:
382 EdkLogger
.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self
.FvTargetList
))
383 self
.FvTargetList
= []
384 if self
.CapTargetList
:
385 EdkLogger
.info("No flash definition file found. Capsule [%s] will be ignored." % " ".join(self
.CapTargetList
))
386 self
.CapTargetList
= []
388 # apply SKU and inject PCDs from Flash Definition file
389 for Arch
in self
.ArchList
:
390 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
, Target
, Toolchain
]
394 PGen
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
395 if GlobalData
.BuildOptionPcd
:
396 for i
, pcd
in enumerate(GlobalData
.BuildOptionPcd
):
397 if type(pcd
) is tuple:
399 (pcdname
, pcdvalue
) = pcd
.split('=')
401 EdkLogger
.error('build', AUTOGEN_ERROR
, "No Value specified for the PCD %s." % (pcdname
))
403 (TokenSpaceGuidCName
, TokenCName
) = pcdname
.split('.')
407 TokenSpaceGuidCName
= ''
408 HasTokenSpace
= False
409 TokenSpaceGuidCNameList
= []
413 for package
in PGen
.PackageList
:
414 for key
in package
.Pcds
:
415 PcdItem
= package
.Pcds
[key
]
417 if (PcdItem
.TokenCName
, PcdItem
.TokenSpaceGuidCName
) == (TokenCName
, TokenSpaceGuidCName
):
418 PcdDatumType
= PcdItem
.DatumType
419 NewValue
= self
._BuildOptionPcdValueFormat
(TokenSpaceGuidCName
, TokenCName
, PcdDatumType
, pcdvalue
)
422 if PcdItem
.TokenCName
== TokenCName
:
423 if not PcdItem
.TokenSpaceGuidCName
in TokenSpaceGuidCNameList
:
424 if len (TokenSpaceGuidCNameList
) < 1:
425 TokenSpaceGuidCNameList
.append(PcdItem
.TokenSpaceGuidCName
)
426 PcdDatumType
= PcdItem
.DatumType
427 TokenSpaceGuidCName
= PcdItem
.TokenSpaceGuidCName
428 NewValue
= self
._BuildOptionPcdValueFormat
(TokenSpaceGuidCName
, TokenCName
, PcdDatumType
, pcdvalue
)
434 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName
, PcdItem
.TokenSpaceGuidCName
, TokenSpaceGuidCNameList
[0])
437 GlobalData
.BuildOptionPcd
[i
] = (TokenSpaceGuidCName
, TokenCName
, NewValue
)
441 EdkLogger
.error('build', AUTOGEN_ERROR
, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName
, TokenCName
))
443 EdkLogger
.error('build', AUTOGEN_ERROR
, "The Pcd %s is not found in the DEC file." % (TokenCName
))
445 for BuildData
in PGen
.BuildDatabase
._CACHE
_.values():
446 if BuildData
.Arch
!= Arch
:
448 if BuildData
.MetaFile
.Ext
== '.dec':
450 for key
in BuildData
.Pcds
:
451 PcdItem
= BuildData
.Pcds
[key
]
452 if (TokenSpaceGuidCName
, TokenCName
) == (PcdItem
.TokenSpaceGuidCName
, PcdItem
.TokenCName
):
453 PcdItem
.DefaultValue
= NewValue
455 if (TokenCName
, TokenSpaceGuidCName
) in PcdSet
:
456 PcdSet
[(TokenCName
, TokenSpaceGuidCName
)] = NewValue
458 SourcePcdDict
= {'DynamicEx':[], 'PatchableInModule':[],'Dynamic':[],'FixedAtBuild':[]}
459 BinaryPcdDict
= {'DynamicEx':[], 'PatchableInModule':[]}
460 SourcePcdDict_Keys
= SourcePcdDict
.keys()
461 BinaryPcdDict_Keys
= BinaryPcdDict
.keys()
463 # generate the SourcePcdDict and BinaryPcdDict
464 for BuildData
in PGen
.BuildDatabase
._CACHE
_.values():
465 if BuildData
.Arch
!= Arch
:
467 if BuildData
.MetaFile
.Ext
== '.inf':
468 for key
in BuildData
.Pcds
:
469 if BuildData
.Pcds
[key
].Pending
:
470 if key
in Platform
.Pcds
:
471 PcdInPlatform
= Platform
.Pcds
[key
]
472 if PcdInPlatform
.Type
not in [None, '']:
473 BuildData
.Pcds
[key
].Type
= PcdInPlatform
.Type
475 if BuildData
.MetaFile
in Platform
.Modules
:
476 PlatformModule
= Platform
.Modules
[str(BuildData
.MetaFile
)]
477 if key
in PlatformModule
.Pcds
:
478 PcdInPlatform
= PlatformModule
.Pcds
[key
]
479 if PcdInPlatform
.Type
not in [None, '']:
480 BuildData
.Pcds
[key
].Type
= PcdInPlatform
.Type
482 if 'DynamicEx' in BuildData
.Pcds
[key
].Type
:
483 if BuildData
.IsBinaryModule
:
484 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in BinaryPcdDict
['DynamicEx']:
485 BinaryPcdDict
['DynamicEx'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
487 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in SourcePcdDict
['DynamicEx']:
488 SourcePcdDict
['DynamicEx'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
490 elif 'PatchableInModule' in BuildData
.Pcds
[key
].Type
:
491 if BuildData
.MetaFile
.Ext
== '.inf':
492 if BuildData
.IsBinaryModule
:
493 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in BinaryPcdDict
['PatchableInModule']:
494 BinaryPcdDict
['PatchableInModule'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
496 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in SourcePcdDict
['PatchableInModule']:
497 SourcePcdDict
['PatchableInModule'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
499 elif 'Dynamic' in BuildData
.Pcds
[key
].Type
:
500 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in SourcePcdDict
['Dynamic']:
501 SourcePcdDict
['Dynamic'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
502 elif 'FixedAtBuild' in BuildData
.Pcds
[key
].Type
:
503 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) not in SourcePcdDict
['FixedAtBuild']:
504 SourcePcdDict
['FixedAtBuild'].append((BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
))
509 # intersection the BinaryPCD for Mixed PCD
511 for i
in BinaryPcdDict_Keys
:
512 for j
in BinaryPcdDict_Keys
:
514 IntersectionList
= list(set(BinaryPcdDict
[i
]).intersection(set(BinaryPcdDict
[j
])))
515 for item
in IntersectionList
:
516 NewPcd1
= (item
[0] + '_' + i
, item
[1])
517 NewPcd2
= (item
[0] + '_' + j
, item
[1])
518 if item
not in GlobalData
.MixedPcd
:
519 GlobalData
.MixedPcd
[item
] = [NewPcd1
, NewPcd2
]
521 if NewPcd1
not in GlobalData
.MixedPcd
[item
]:
522 GlobalData
.MixedPcd
[item
].append(NewPcd1
)
523 if NewPcd2
not in GlobalData
.MixedPcd
[item
]:
524 GlobalData
.MixedPcd
[item
].append(NewPcd2
)
529 # intersection the SourcePCD and BinaryPCD for Mixed PCD
531 for i
in SourcePcdDict_Keys
:
532 for j
in BinaryPcdDict_Keys
:
534 IntersectionList
= list(set(SourcePcdDict
[i
]).intersection(set(BinaryPcdDict
[j
])))
535 for item
in IntersectionList
:
536 NewPcd1
= (item
[0] + '_' + i
, item
[1])
537 NewPcd2
= (item
[0] + '_' + j
, item
[1])
538 if item
not in GlobalData
.MixedPcd
:
539 GlobalData
.MixedPcd
[item
] = [NewPcd1
, NewPcd2
]
541 if NewPcd1
not in GlobalData
.MixedPcd
[item
]:
542 GlobalData
.MixedPcd
[item
].append(NewPcd1
)
543 if NewPcd2
not in GlobalData
.MixedPcd
[item
]:
544 GlobalData
.MixedPcd
[item
].append(NewPcd2
)
548 for BuildData
in PGen
.BuildDatabase
._CACHE
_.values():
549 if BuildData
.Arch
!= Arch
:
551 for key
in BuildData
.Pcds
:
552 for SinglePcd
in GlobalData
.MixedPcd
:
553 if (BuildData
.Pcds
[key
].TokenCName
, BuildData
.Pcds
[key
].TokenSpaceGuidCName
) == SinglePcd
:
554 for item
in GlobalData
.MixedPcd
[SinglePcd
]:
555 Pcd_Type
= item
[0].split('_')[-1]
556 if (Pcd_Type
== BuildData
.Pcds
[key
].Type
) or (Pcd_Type
== TAB_PCDS_DYNAMIC_EX
and BuildData
.Pcds
[key
].Type
in GenC
.gDynamicExPcd
) or \
557 (Pcd_Type
== TAB_PCDS_DYNAMIC
and BuildData
.Pcds
[key
].Type
in GenC
.gDynamicPcd
):
558 Value
= BuildData
.Pcds
[key
]
559 Value
.TokenCName
= BuildData
.Pcds
[key
].TokenCName
+ '_' + Pcd_Type
561 newkey
= (Value
.TokenCName
, key
[1])
563 newkey
= (Value
.TokenCName
, key
[1], key
[2])
564 del BuildData
.Pcds
[key
]
565 BuildData
.Pcds
[newkey
] = Value
573 # handle the mixed pcd in FDF file
575 if key
in GlobalData
.MixedPcd
:
578 for item
in GlobalData
.MixedPcd
[key
]:
581 #Collect package set information from INF of FDF
583 for Inf
in ModuleList
:
584 ModuleFile
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, Arch
)
585 if ModuleFile
in Platform
.Modules
:
587 ModuleData
= self
.BuildDatabase
[ModuleFile
, Arch
, Target
, Toolchain
]
588 PkgSet
.update(ModuleData
.Packages
)
589 Pkgs
= list(PkgSet
) + list(PGen
.PackageList
)
592 DecPcds
[Pcd
[0], Pcd
[1]] = Pkg
.Pcds
[Pcd
]
593 DecPcdsKey
.add((Pcd
[0], Pcd
[1], Pcd
[2]))
595 Platform
.SkuName
= self
.SkuId
596 for Name
, Guid
in PcdSet
:
597 if (Name
, Guid
) not in DecPcds
:
601 "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid
, Name
),
602 File
= self
.FdfProfile
.PcdFileLineDict
[Name
, Guid
][0],
603 Line
= self
.FdfProfile
.PcdFileLineDict
[Name
, Guid
][1]
606 # Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message.
607 if (Name
, Guid
, TAB_PCDS_FIXED_AT_BUILD
) in DecPcdsKey \
608 or (Name
, Guid
, TAB_PCDS_PATCHABLE_IN_MODULE
) in DecPcdsKey \
609 or (Name
, Guid
, TAB_PCDS_FEATURE_FLAG
) in DecPcdsKey
:
610 Platform
.AddPcd(Name
, Guid
, PcdSet
[Name
, Guid
])
612 elif (Name
, Guid
, TAB_PCDS_DYNAMIC
) in DecPcdsKey
or (Name
, Guid
, TAB_PCDS_DYNAMIC_EX
) in DecPcdsKey
:
616 "Using Dynamic or DynamicEx type of PCD [%s.%s] in FDF file is not allowed." % (Guid
, Name
),
617 File
= self
.FdfProfile
.PcdFileLineDict
[Name
, Guid
][0],
618 Line
= self
.FdfProfile
.PcdFileLineDict
[Name
, Guid
][1]
621 Pa
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
623 # Explicitly collect platform's dynamic PCDs
625 Pa
.CollectPlatformDynamicPcds()
626 Pa
.CollectFixedAtBuildPcds()
627 self
.AutoGenObjectList
.append(Pa
)
630 # Check PCDs token value conflict in each DEC file.
632 self
._CheckAllPcdsTokenValueConflict
()
635 # Check PCD type and definition between DSC and DEC
637 self
._CheckPcdDefineAndType
()
640 # self._CheckDuplicateInFV(Fdf)
642 self
._BuildDir
= None
644 self
._MakeFileDir
= None
645 self
._BuildCommand
= None
648 # Create BuildOptions Macro & PCD metafile.
650 content
= 'gCommandLineDefines: '
651 content
+= str(GlobalData
.gCommandLineDefines
)
652 content
+= os
.linesep
653 content
+= 'BuildOptionPcd: '
654 content
+= str(GlobalData
.BuildOptionPcd
)
655 SaveFileOnChange(os
.path
.join(self
.BuildDir
, 'BuildOptions'), content
, False)
658 # Get set of workspace metafiles
660 AllWorkSpaceMetaFiles
= self
._GetMetaFiles
(Target
, Toolchain
, Arch
)
663 # Retrieve latest modified time of all metafiles
666 for f
in AllWorkSpaceMetaFiles
:
667 if os
.stat(f
)[8] > SrcTimeStamp
:
668 SrcTimeStamp
= os
.stat(f
)[8]
669 self
._SrcTimeStamp
= SrcTimeStamp
672 # Write metafile list to build directory
674 AutoGenFilePath
= os
.path
.join(self
.BuildDir
, 'AutoGen')
675 if os
.path
.exists (AutoGenFilePath
):
676 os
.remove(AutoGenFilePath
)
677 if not os
.path
.exists(self
.BuildDir
):
678 os
.makedirs(self
.BuildDir
)
679 with
open(os
.path
.join(self
.BuildDir
, 'AutoGen'), 'w+') as file:
680 for f
in AllWorkSpaceMetaFiles
:
684 def _BuildOptionPcdValueFormat(self
, TokenSpaceGuidCName
, TokenCName
, PcdDatumType
, Value
):
685 if PcdDatumType
== 'VOID*':
686 if Value
.startswith('L'):
688 EdkLogger
.error('build', OPTION_VALUE_INVALID
, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
689 Value
= Value
[0] + '"' + Value
[1:] + '"'
690 elif Value
.startswith('B'):
692 EdkLogger
.error('build', OPTION_VALUE_INVALID
, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
696 EdkLogger
.error('build', OPTION_VALUE_INVALID
, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
697 Value
= '"' + Value
+ '"'
699 IsValid
, Cause
= CheckPcdDatum(PcdDatumType
, Value
)
701 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, ExtraData
="%s.%s" % (TokenSpaceGuidCName
, TokenCName
))
702 if PcdDatumType
== 'BOOLEAN':
703 Value
= Value
.upper()
704 if Value
== 'TRUE' or Value
== '1':
706 elif Value
== 'FALSE' or Value
== '0':
710 def _GetMetaFiles(self
, Target
, Toolchain
, Arch
):
711 AllWorkSpaceMetaFiles
= set()
716 AllWorkSpaceMetaFiles
.add (self
.FdfFile
.Path
)
718 FdfFiles
= GlobalData
.gFdfParser
.GetAllIncludedFile()
720 AllWorkSpaceMetaFiles
.add (f
.FileName
)
724 AllWorkSpaceMetaFiles
.add(self
.MetaFile
.Path
)
727 # add build_rule.txt & tools_def.txt
729 AllWorkSpaceMetaFiles
.add(os
.path
.join(GlobalData
.gConfDirectory
, gDefaultBuildRuleFile
))
730 AllWorkSpaceMetaFiles
.add(os
.path
.join(GlobalData
.gConfDirectory
, gDefaultToolsDefFile
))
732 # add BuildOption metafile
734 AllWorkSpaceMetaFiles
.add(os
.path
.join(self
.BuildDir
, 'BuildOptions'))
736 for Arch
in self
.ArchList
:
737 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
, Target
, Toolchain
]
738 PGen
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
743 for Package
in PGen
.PackageList
:
744 AllWorkSpaceMetaFiles
.add(Package
.MetaFile
.Path
)
749 for filePath
in Platform
._RawData
.IncludedFiles
:
750 AllWorkSpaceMetaFiles
.add(filePath
.Path
)
752 return AllWorkSpaceMetaFiles
754 ## _CheckDuplicateInFV() method
756 # Check whether there is duplicate modules/files exist in FV section.
757 # The check base on the file GUID;
759 def _CheckDuplicateInFV(self
, Fdf
):
760 for Fv
in Fdf
.Profile
.FvDict
:
762 for FfsFile
in Fdf
.Profile
.FvDict
[Fv
].FfsList
:
763 if FfsFile
.InfFileName
and FfsFile
.NameGuid
== None:
768 for Pa
in self
.AutoGenObjectList
:
771 for Module
in Pa
.ModuleAutoGenList
:
772 if path
.normpath(Module
.MetaFile
.File
) == path
.normpath(FfsFile
.InfFileName
):
774 if not Module
.Guid
.upper() in _GuidDict
.keys():
775 _GuidDict
[Module
.Guid
.upper()] = FfsFile
778 EdkLogger
.error("build",
780 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile
.CurrentLineNum
,
781 FfsFile
.CurrentLineContent
,
782 _GuidDict
[Module
.Guid
.upper()].CurrentLineNum
,
783 _GuidDict
[Module
.Guid
.upper()].CurrentLineContent
,
784 Module
.Guid
.upper()),
785 ExtraData
=self
.FdfFile
)
787 # Some INF files not have entity in DSC file.
790 if FfsFile
.InfFileName
.find('$') == -1:
791 InfPath
= NormPath(FfsFile
.InfFileName
)
792 if not os
.path
.exists(InfPath
):
793 EdkLogger
.error('build', GENFDS_ERROR
, "Non-existant Module %s !" % (FfsFile
.InfFileName
))
795 PathClassObj
= PathClass(FfsFile
.InfFileName
, self
.WorkspaceDir
)
797 # Here we just need to get FILE_GUID from INF file, use 'COMMON' as ARCH attribute. and use
798 # BuildObject from one of AutoGenObjectList is enough.
800 InfObj
= self
.AutoGenObjectList
[0].BuildDatabase
.WorkspaceDb
.BuildObject
[PathClassObj
, 'COMMON', self
.BuildTarget
, self
.ToolChain
]
801 if not InfObj
.Guid
.upper() in _GuidDict
.keys():
802 _GuidDict
[InfObj
.Guid
.upper()] = FfsFile
804 EdkLogger
.error("build",
806 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile
.CurrentLineNum
,
807 FfsFile
.CurrentLineContent
,
808 _GuidDict
[InfObj
.Guid
.upper()].CurrentLineNum
,
809 _GuidDict
[InfObj
.Guid
.upper()].CurrentLineContent
,
810 InfObj
.Guid
.upper()),
811 ExtraData
=self
.FdfFile
)
814 if FfsFile
.NameGuid
!= None:
815 _CheckPCDAsGuidPattern
= re
.compile("^PCD\(.+\..+\)$")
818 # If the NameGuid reference a PCD name.
819 # The style must match: PCD(xxxx.yyy)
821 if _CheckPCDAsGuidPattern
.match(FfsFile
.NameGuid
):
823 # Replace the PCD value.
825 _PcdName
= FfsFile
.NameGuid
.lstrip("PCD(").rstrip(")")
827 for Pa
in self
.AutoGenObjectList
:
829 for PcdItem
in Pa
.AllPcdList
:
830 if (PcdItem
.TokenSpaceGuidCName
+ "." + PcdItem
.TokenCName
) == _PcdName
:
832 # First convert from CFormatGuid to GUID string
834 _PcdGuidString
= GuidStructureStringToGuidString(PcdItem
.DefaultValue
)
836 if not _PcdGuidString
:
838 # Then try Byte array.
840 _PcdGuidString
= GuidStructureByteArrayToGuidString(PcdItem
.DefaultValue
)
842 if not _PcdGuidString
:
844 # Not Byte array or CFormat GUID, raise error.
846 EdkLogger
.error("build",
848 "The format of PCD value is incorrect. PCD: %s , Value: %s\n" % (_PcdName
, PcdItem
.DefaultValue
),
849 ExtraData
=self
.FdfFile
)
851 if not _PcdGuidString
.upper() in _GuidDict
.keys():
852 _GuidDict
[_PcdGuidString
.upper()] = FfsFile
856 EdkLogger
.error("build",
858 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile
.CurrentLineNum
,
859 FfsFile
.CurrentLineContent
,
860 _GuidDict
[_PcdGuidString
.upper()].CurrentLineNum
,
861 _GuidDict
[_PcdGuidString
.upper()].CurrentLineContent
,
862 FfsFile
.NameGuid
.upper()),
863 ExtraData
=self
.FdfFile
)
865 if not FfsFile
.NameGuid
.upper() in _GuidDict
.keys():
866 _GuidDict
[FfsFile
.NameGuid
.upper()] = FfsFile
869 # Two raw file GUID conflict.
871 EdkLogger
.error("build",
873 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile
.CurrentLineNum
,
874 FfsFile
.CurrentLineContent
,
875 _GuidDict
[FfsFile
.NameGuid
.upper()].CurrentLineNum
,
876 _GuidDict
[FfsFile
.NameGuid
.upper()].CurrentLineContent
,
877 FfsFile
.NameGuid
.upper()),
878 ExtraData
=self
.FdfFile
)
881 def _CheckPcdDefineAndType(self
):
883 "FixedAtBuild", "PatchableInModule", "FeatureFlag",
884 "Dynamic", #"DynamicHii", "DynamicVpd",
885 "DynamicEx", # "DynamicExHii", "DynamicExVpd"
888 # This dict store PCDs which are not used by any modules with specified arches
890 for Pa
in self
.AutoGenObjectList
:
891 # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid
892 for Pcd
in Pa
.Platform
.Pcds
:
893 PcdType
= Pa
.Platform
.Pcds
[Pcd
].Type
895 # If no PCD type, this PCD comes from FDF
899 # Try to remove Hii and Vpd suffix
900 if PcdType
.startswith("DynamicEx"):
901 PcdType
= "DynamicEx"
902 elif PcdType
.startswith("Dynamic"):
905 for Package
in Pa
.PackageList
:
906 # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType
907 if (Pcd
[0], Pcd
[1], PcdType
) in Package
.Pcds
:
909 for Type
in PcdTypeList
:
910 if (Pcd
[0], Pcd
[1], Type
) in Package
.Pcds
:
914 "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \
915 % (Pa
.Platform
.Pcds
[Pcd
].Type
, Pcd
[1], Pcd
[0], Type
),
920 UnusedPcd
.setdefault(Pcd
, []).append(Pa
.Arch
)
922 for Pcd
in UnusedPcd
:
925 "The PCD was not specified by any INF module in the platform for the given architecture.\n"
926 "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"
927 % (Pcd
[1], Pcd
[0], os
.path
.basename(str(self
.MetaFile
)), str(UnusedPcd
[Pcd
])),
932 return "%s [%s]" % (self
.MetaFile
, ", ".join(self
.ArchList
))
934 ## Return the directory to store FV files
936 if self
._FvDir
== None:
937 self
._FvDir
= path
.join(self
.BuildDir
, 'FV')
940 ## Return the directory to store all intermediate and final files built
941 def _GetBuildDir(self
):
942 return self
.AutoGenObjectList
[0].BuildDir
944 ## Return the build output directory platform specifies
945 def _GetOutputDir(self
):
946 return self
.Platform
.OutputDirectory
948 ## Return platform name
950 return self
.Platform
.PlatformName
952 ## Return meta-file GUID
954 return self
.Platform
.Guid
956 ## Return platform version
957 def _GetVersion(self
):
958 return self
.Platform
.Version
960 ## Return paths of tools
961 def _GetToolDefinition(self
):
962 return self
.AutoGenObjectList
[0].ToolDefinition
964 ## Return directory of platform makefile
966 # @retval string Makefile directory
968 def _GetMakeFileDir(self
):
969 if self
._MakeFileDir
== None:
970 self
._MakeFileDir
= self
.BuildDir
971 return self
._MakeFileDir
973 ## Return build command string
975 # @retval string Build command string
977 def _GetBuildCommand(self
):
978 if self
._BuildCommand
== None:
979 # BuildCommand should be all the same. So just get one from platform AutoGen
980 self
._BuildCommand
= self
.AutoGenObjectList
[0].BuildCommand
981 return self
._BuildCommand
983 ## Check the PCDs token value conflict in each DEC file.
985 # Will cause build break and raise error message while two PCDs conflict.
989 def _CheckAllPcdsTokenValueConflict(self
):
990 for Pa
in self
.AutoGenObjectList
:
991 for Package
in Pa
.PackageList
:
992 PcdList
= Package
.Pcds
.values()
993 PcdList
.sort(lambda x
, y
: cmp(int(x
.TokenValue
, 0), int(y
.TokenValue
, 0)))
995 while (Count
< len(PcdList
) - 1) :
996 Item
= PcdList
[Count
]
997 ItemNext
= PcdList
[Count
+ 1]
999 # Make sure in the same token space the TokenValue should be unique
1001 if (int(Item
.TokenValue
, 0) == int(ItemNext
.TokenValue
, 0)):
1002 SameTokenValuePcdList
= []
1003 SameTokenValuePcdList
.append(Item
)
1004 SameTokenValuePcdList
.append(ItemNext
)
1005 RemainPcdListLength
= len(PcdList
) - Count
- 2
1006 for ValueSameCount
in range(RemainPcdListLength
):
1007 if int(PcdList
[len(PcdList
) - RemainPcdListLength
+ ValueSameCount
].TokenValue
, 0) == int(Item
.TokenValue
, 0):
1008 SameTokenValuePcdList
.append(PcdList
[len(PcdList
) - RemainPcdListLength
+ ValueSameCount
])
1012 # Sort same token value PCD list with TokenGuid and TokenCName
1014 SameTokenValuePcdList
.sort(lambda x
, y
: cmp("%s.%s" % (x
.TokenSpaceGuidCName
, x
.TokenCName
), "%s.%s" % (y
.TokenSpaceGuidCName
, y
.TokenCName
)))
1015 SameTokenValuePcdListCount
= 0
1016 while (SameTokenValuePcdListCount
< len(SameTokenValuePcdList
) - 1):
1018 TemListItem
= SameTokenValuePcdList
[SameTokenValuePcdListCount
]
1019 TemListItemNext
= SameTokenValuePcdList
[SameTokenValuePcdListCount
+ 1]
1021 if (TemListItem
.TokenSpaceGuidCName
== TemListItemNext
.TokenSpaceGuidCName
) and (TemListItem
.TokenCName
!= TemListItemNext
.TokenCName
):
1022 for PcdItem
in GlobalData
.MixedPcd
:
1023 if (TemListItem
.TokenCName
, TemListItem
.TokenSpaceGuidCName
) in GlobalData
.MixedPcd
[PcdItem
] or \
1024 (TemListItemNext
.TokenCName
, TemListItemNext
.TokenSpaceGuidCName
) in GlobalData
.MixedPcd
[PcdItem
]:
1030 "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\
1031 % (TemListItem
.TokenValue
, TemListItem
.TokenSpaceGuidCName
, TemListItem
.TokenCName
, TemListItemNext
.TokenSpaceGuidCName
, TemListItemNext
.TokenCName
, Package
),
1034 SameTokenValuePcdListCount
+= 1
1035 Count
+= SameTokenValuePcdListCount
1038 PcdList
= Package
.Pcds
.values()
1039 PcdList
.sort(lambda x
, y
: cmp("%s.%s" % (x
.TokenSpaceGuidCName
, x
.TokenCName
), "%s.%s" % (y
.TokenSpaceGuidCName
, y
.TokenCName
)))
1041 while (Count
< len(PcdList
) - 1) :
1042 Item
= PcdList
[Count
]
1043 ItemNext
= PcdList
[Count
+ 1]
1045 # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.
1047 if (Item
.TokenSpaceGuidCName
== ItemNext
.TokenSpaceGuidCName
) and (Item
.TokenCName
== ItemNext
.TokenCName
) and (int(Item
.TokenValue
, 0) != int(ItemNext
.TokenValue
, 0)):
1051 "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\
1052 % (Item
.TokenValue
, Item
.TokenSpaceGuidCName
, Item
.TokenCName
, Package
),
1056 ## Generate fds command
1057 def _GenFdsCommand(self
):
1058 return (GenMake
.TopLevelMakefile(self
)._TEMPLATE
_.Replace(GenMake
.TopLevelMakefile(self
)._TemplateDict
)).strip()
1060 ## Create makefile for the platform and modules in it
1062 # @param CreateDepsMakeFile Flag indicating if the makefile for
1063 # modules will be created as well
1065 def CreateMakeFile(self
, CreateDepsMakeFile
=False):
1066 if CreateDepsMakeFile
:
1067 for Pa
in self
.AutoGenObjectList
:
1068 Pa
.CreateMakeFile(CreateDepsMakeFile
)
1070 ## Create autogen code for platform and modules
1072 # Since there's no autogen code for platform, this method will do nothing
1073 # if CreateModuleCodeFile is set to False.
1075 # @param CreateDepsCodeFile Flag indicating if creating module's
1076 # autogen code file or not
1078 def CreateCodeFile(self
, CreateDepsCodeFile
=False):
1079 if not CreateDepsCodeFile
:
1081 for Pa
in self
.AutoGenObjectList
:
1082 Pa
.CreateCodeFile(CreateDepsCodeFile
)
1084 ## Create AsBuilt INF file the platform
1086 def CreateAsBuiltInf(self
):
1089 Name
= property(_GetName
)
1090 Guid
= property(_GetGuid
)
1091 Version
= property(_GetVersion
)
1092 OutputDir
= property(_GetOutputDir
)
1094 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
1096 BuildDir
= property(_GetBuildDir
)
1097 FvDir
= property(_GetFvDir
)
1098 MakeFileDir
= property(_GetMakeFileDir
)
1099 BuildCommand
= property(_GetBuildCommand
)
1100 GenFdsCommand
= property(_GenFdsCommand
)
1102 ## AutoGen class for platform
1104 # PlatformAutoGen class will process the original information in platform
1105 # file in order to generate makefile for platform.
1107 class PlatformAutoGen(AutoGen
):
1109 # Used to store all PCDs for both PEI and DXE phase, in order to generate
1110 # correct PCD database
1113 _NonDynaPcdList_
= []
1117 # The priority list while override build option
1119 PrioList
= {"0x11111" : 16, # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)
1120 "0x01111" : 15, # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
1121 "0x10111" : 14, # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE
1122 "0x00111" : 13, # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE
1123 "0x11011" : 12, # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
1124 "0x01011" : 11, # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
1125 "0x10011" : 10, # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE
1126 "0x00011" : 9, # ******_*********_****_COMMANDTYPE_ATTRIBUTE
1127 "0x11101" : 8, # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE
1128 "0x01101" : 7, # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE
1129 "0x10101" : 6, # TARGET_*********_ARCH_***********_ATTRIBUTE
1130 "0x00101" : 5, # ******_*********_ARCH_***********_ATTRIBUTE
1131 "0x11001" : 4, # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE
1132 "0x01001" : 3, # ******_TOOLCHAIN_****_***********_ATTRIBUTE
1133 "0x10001" : 2, # TARGET_*********_****_***********_ATTRIBUTE
1134 "0x00001" : 1} # ******_*********_****_***********_ATTRIBUTE (Lowest)
1136 ## The real constructor of PlatformAutoGen
1138 # This method is not supposed to be called by users of PlatformAutoGen. It's
1139 # only used by factory method __new__() to do real initialization work for an
1140 # object of PlatformAutoGen
1142 # @param Workspace WorkspaceAutoGen object
1143 # @param PlatformFile Platform file (DSC file)
1144 # @param Target Build target (DEBUG, RELEASE)
1145 # @param Toolchain Name of tool chain
1146 # @param Arch arch of the platform supports
1148 def _Init(self
, Workspace
, PlatformFile
, Target
, Toolchain
, Arch
):
1149 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen platform [%s] [%s]" % (PlatformFile
, Arch
))
1150 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (PlatformFile
, Arch
, Toolchain
, Target
)
1152 self
.MetaFile
= PlatformFile
1153 self
.Workspace
= Workspace
1154 self
.WorkspaceDir
= Workspace
.WorkspaceDir
1155 self
.ToolChain
= Toolchain
1156 self
.BuildTarget
= Target
1158 self
.SourceDir
= PlatformFile
.SubDir
1159 self
.SourceOverrideDir
= None
1160 self
.FdTargetList
= self
.Workspace
.FdTargetList
1161 self
.FvTargetList
= self
.Workspace
.FvTargetList
1162 self
.AllPcdList
= []
1163 # get the original module/package/platform objects
1164 self
.BuildDatabase
= Workspace
.BuildDatabase
1166 # flag indicating if the makefile/C-code file has been created or not
1167 self
.IsMakeFileCreated
= False
1168 self
.IsCodeFileCreated
= False
1170 self
._Platform
= None
1173 self
._Version
= None
1175 self
._BuildRule
= None
1176 self
._SourceDir
= None
1177 self
._BuildDir
= None
1178 self
._OutputDir
= None
1180 self
._MakeFileDir
= None
1181 self
._FdfFile
= None
1183 self
._PcdTokenNumber
= None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
1184 self
._DynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1185 self
._NonDynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1186 self
._NonDynamicPcdDict
= {}
1188 self
._ToolDefinitions
= None
1189 self
._ToolDefFile
= None # toolcode : tool path
1190 self
._ToolChainFamily
= None
1191 self
._BuildRuleFamily
= None
1192 self
._BuildOption
= None # toolcode : option
1193 self
._EdkBuildOption
= None # edktoolcode : option
1194 self
._EdkIIBuildOption
= None # edkiitoolcode : option
1195 self
._PackageList
= None
1196 self
._ModuleAutoGenList
= None
1197 self
._LibraryAutoGenList
= None
1198 self
._BuildCommand
= None
1199 self
._AsBuildInfList
= []
1200 self
._AsBuildModuleList
= []
1201 if GlobalData
.gFdfParser
!= None:
1202 self
._AsBuildInfList
= GlobalData
.gFdfParser
.Profile
.InfList
1203 for Inf
in self
._AsBuildInfList
:
1204 InfClass
= PathClass(NormPath(Inf
), GlobalData
.gWorkspace
, self
.Arch
)
1205 M
= self
.BuildDatabase
[InfClass
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
1206 if not M
.IsSupportedArch
:
1208 self
._AsBuildModuleList
.append(InfClass
)
1209 # get library/modules for build
1210 self
.LibraryBuildDirectoryList
= []
1211 self
.ModuleBuildDirectoryList
= []
1215 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
1217 ## Create autogen code for platform and modules
1219 # Since there's no autogen code for platform, this method will do nothing
1220 # if CreateModuleCodeFile is set to False.
1222 # @param CreateModuleCodeFile Flag indicating if creating module's
1223 # autogen code file or not
1225 def CreateCodeFile(self
, CreateModuleCodeFile
=False):
1226 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
1227 if self
.IsCodeFileCreated
or not CreateModuleCodeFile
:
1230 for Ma
in self
.ModuleAutoGenList
:
1231 Ma
.CreateCodeFile(True)
1233 # don't do this twice
1234 self
.IsCodeFileCreated
= True
1236 ## Generate Fds Command
1237 def _GenFdsCommand(self
):
1238 return self
.Workspace
.GenFdsCommand
1240 ## Create makefile for the platform and mdoules in it
1242 # @param CreateModuleMakeFile Flag indicating if the makefile for
1243 # modules will be created as well
1245 def CreateMakeFile(self
, CreateModuleMakeFile
=False):
1246 if CreateModuleMakeFile
:
1247 for ModuleFile
in self
.Platform
.Modules
:
1248 Ma
= ModuleAutoGen(self
.Workspace
, ModuleFile
, self
.BuildTarget
,
1249 self
.ToolChain
, self
.Arch
, self
.MetaFile
)
1250 Ma
.CreateMakeFile(True)
1251 #Ma.CreateAsBuiltInf()
1253 # no need to create makefile for the platform more than once
1254 if self
.IsMakeFileCreated
:
1257 # create library/module build dirs for platform
1258 Makefile
= GenMake
.PlatformMakefile(self
)
1259 self
.LibraryBuildDirectoryList
= Makefile
.GetLibraryBuildDirectoryList()
1260 self
.ModuleBuildDirectoryList
= Makefile
.GetModuleBuildDirectoryList()
1262 self
.IsMakeFileCreated
= True
1264 ## Deal with Shared FixedAtBuild Pcds
1266 def CollectFixedAtBuildPcds(self
):
1267 for LibAuto
in self
.LibraryAutoGenList
:
1268 FixedAtBuildPcds
= {}
1269 ShareFixedAtBuildPcdsSameValue
= {}
1270 for Module
in LibAuto
._ReferenceModules
:
1271 for Pcd
in Module
.FixedAtBuildPcds
+ LibAuto
.FixedAtBuildPcds
:
1272 key
= ".".join((Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
))
1273 if key
not in FixedAtBuildPcds
:
1274 ShareFixedAtBuildPcdsSameValue
[key
] = True
1275 FixedAtBuildPcds
[key
] = Pcd
.DefaultValue
1277 if FixedAtBuildPcds
[key
] != Pcd
.DefaultValue
:
1278 ShareFixedAtBuildPcdsSameValue
[key
] = False
1279 for Pcd
in LibAuto
.FixedAtBuildPcds
:
1280 key
= ".".join((Pcd
.TokenSpaceGuidCName
,Pcd
.TokenCName
))
1281 if (Pcd
.TokenCName
,Pcd
.TokenSpaceGuidCName
) not in self
.NonDynamicPcdDict
:
1284 DscPcd
= self
.NonDynamicPcdDict
[(Pcd
.TokenCName
,Pcd
.TokenSpaceGuidCName
)]
1285 if DscPcd
.Type
!= "FixedAtBuild":
1287 if key
in ShareFixedAtBuildPcdsSameValue
and ShareFixedAtBuildPcdsSameValue
[key
]:
1288 LibAuto
.ConstPcd
[key
] = Pcd
.DefaultValue
1290 ## Collect dynamic PCDs
1292 # Gather dynamic PCDs list from each module and their settings from platform
1293 # This interface should be invoked explicitly when platform action is created.
1295 def CollectPlatformDynamicPcds(self
):
1296 # Override the platform Pcd's value by build option
1297 if GlobalData
.BuildOptionPcd
:
1298 for key
in self
.Platform
.Pcds
:
1299 PlatformPcd
= self
.Platform
.Pcds
[key
]
1300 for PcdItem
in GlobalData
.BuildOptionPcd
:
1301 if (PlatformPcd
.TokenSpaceGuidCName
, PlatformPcd
.TokenCName
) == (PcdItem
[0], PcdItem
[1]):
1302 PlatformPcd
.DefaultValue
= PcdItem
[2]
1303 if PlatformPcd
.SkuInfoList
:
1304 Sku
= PlatformPcd
.SkuInfoList
[PlatformPcd
.SkuInfoList
.keys()[0]]
1305 Sku
.DefaultValue
= PcdItem
[2]
1308 for key
in self
.Platform
.Pcds
:
1309 for SinglePcd
in GlobalData
.MixedPcd
:
1310 if (self
.Platform
.Pcds
[key
].TokenCName
, self
.Platform
.Pcds
[key
].TokenSpaceGuidCName
) == SinglePcd
:
1311 for item
in GlobalData
.MixedPcd
[SinglePcd
]:
1312 Pcd_Type
= item
[0].split('_')[-1]
1313 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 \
1314 (Pcd_Type
== TAB_PCDS_DYNAMIC
and self
.Platform
.Pcds
[key
].Type
in GenC
.gDynamicPcd
):
1315 Value
= self
.Platform
.Pcds
[key
]
1316 Value
.TokenCName
= self
.Platform
.Pcds
[key
].TokenCName
+ '_' + Pcd_Type
1318 newkey
= (Value
.TokenCName
, key
[1])
1320 newkey
= (Value
.TokenCName
, key
[1], key
[2])
1321 del self
.Platform
.Pcds
[key
]
1322 self
.Platform
.Pcds
[newkey
] = Value
1330 # for gathering error information
1331 NoDatumTypePcdList
= set()
1333 self
._GuidValue
= {}
1335 for InfName
in self
._AsBuildInfList
:
1336 InfName
= mws
.join(self
.WorkspaceDir
, InfName
)
1337 FdfModuleList
.append(os
.path
.normpath(InfName
))
1338 for F
in self
.Platform
.Modules
.keys():
1339 M
= ModuleAutoGen(self
.Workspace
, F
, self
.BuildTarget
, self
.ToolChain
, self
.Arch
, self
.MetaFile
)
1340 #GuidValue.update(M.Guids)
1342 self
.Platform
.Modules
[F
].M
= M
1344 for PcdFromModule
in M
.ModulePcdList
+ M
.LibraryPcdList
:
1345 # make sure that the "VOID*" kind of datum has MaxDatumSize set
1346 if PcdFromModule
.DatumType
== "VOID*" and PcdFromModule
.MaxDatumSize
in [None, '']:
1347 NoDatumTypePcdList
.add("%s.%s [%s]" % (PcdFromModule
.TokenSpaceGuidCName
, PcdFromModule
.TokenCName
, F
))
1349 # Check the PCD from Binary INF or Source INF
1350 if M
.IsBinaryModule
== True:
1351 PcdFromModule
.IsFromBinaryInf
= True
1353 # Check the PCD from DSC or not
1354 if (PcdFromModule
.TokenCName
, PcdFromModule
.TokenSpaceGuidCName
) in self
.Platform
.Pcds
.keys():
1355 PcdFromModule
.IsFromDsc
= True
1357 PcdFromModule
.IsFromDsc
= False
1358 if PcdFromModule
.Type
in GenC
.gDynamicPcd
or PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
1359 if F
.Path
not in FdfModuleList
:
1360 # If one of the Source built modules listed in the DSC is not listed
1361 # in FDF modules, and the INF lists a PCD can only use the PcdsDynamic
1362 # access method (it is only listed in the DEC file that declares the
1363 # PCD as PcdsDynamic), then build tool will report warning message
1364 # notify the PI that they are attempting to build a module that must
1365 # be included in a flash image in order to be functional. These Dynamic
1366 # PCD will not be added into the Database unless it is used by other
1367 # modules that are included in the FDF file.
1368 if PcdFromModule
.Type
in GenC
.gDynamicPcd
and \
1369 PcdFromModule
.IsFromBinaryInf
== False:
1370 # Print warning message to let the developer make a determine.
1371 if PcdFromModule
not in PcdNotInDb
:
1372 PcdNotInDb
.append(PcdFromModule
)
1374 # If one of the Source built modules listed in the DSC is not listed in
1375 # FDF modules, and the INF lists a PCD can only use the PcdsDynamicEx
1376 # access method (it is only listed in the DEC file that declares the
1377 # PCD as PcdsDynamicEx), then DO NOT break the build; DO NOT add the
1378 # PCD to the Platform's PCD Database.
1379 if PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
1380 if PcdFromModule
not in PcdNotInDb
:
1381 PcdNotInDb
.append(PcdFromModule
)
1384 # If a dynamic PCD used by a PEM module/PEI module & DXE module,
1385 # it should be stored in Pcd PEI database, If a dynamic only
1386 # used by DXE module, it should be stored in DXE PCD database.
1387 # The default Phase is DXE
1389 if M
.ModuleType
in ["PEIM", "PEI_CORE"]:
1390 PcdFromModule
.Phase
= "PEI"
1391 if PcdFromModule
not in self
._DynaPcdList
_:
1392 self
._DynaPcdList
_.append(PcdFromModule
)
1393 elif PcdFromModule
.Phase
== 'PEI':
1394 # overwrite any the same PCD existing, if Phase is PEI
1395 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
1396 self
._DynaPcdList
_[Index
] = PcdFromModule
1397 elif PcdFromModule
not in self
._NonDynaPcdList
_:
1398 self
._NonDynaPcdList
_.append(PcdFromModule
)
1399 elif PcdFromModule
in self
._NonDynaPcdList
_ and PcdFromModule
.IsFromBinaryInf
== True:
1400 Index
= self
._NonDynaPcdList
_.index(PcdFromModule
)
1401 if self
._NonDynaPcdList
_[Index
].IsFromBinaryInf
== False:
1402 #The PCD from Binary INF will override the same one from source INF
1403 self
._NonDynaPcdList
_.remove (self
._NonDynaPcdList
_[Index
])
1404 PcdFromModule
.Pending
= False
1405 self
._NonDynaPcdList
_.append (PcdFromModule
)
1406 # Parse the DynamicEx PCD from the AsBuild INF module list of FDF.
1408 for ModuleInf
in self
.Platform
.Modules
.keys():
1409 DscModuleList
.append (os
.path
.normpath(ModuleInf
.Path
))
1410 # add the PCD from modules that listed in FDF but not in DSC to Database
1411 for InfName
in FdfModuleList
:
1412 if InfName
not in DscModuleList
:
1413 InfClass
= PathClass(InfName
)
1414 M
= self
.BuildDatabase
[InfClass
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
1415 # If a module INF in FDF but not in current arch's DSC module list, it must be module (either binary or source)
1416 # for different Arch. PCDs in source module for different Arch is already added before, so skip the source module here.
1417 # For binary module, if in current arch, we need to list the PCDs into database.
1418 if not M
.IsSupportedArch
:
1420 # Override the module PCD setting by platform setting
1421 ModulePcdList
= self
.ApplyPcdSetting(M
, M
.Pcds
)
1422 for PcdFromModule
in ModulePcdList
:
1423 PcdFromModule
.IsFromBinaryInf
= True
1424 PcdFromModule
.IsFromDsc
= False
1425 # Only allow the DynamicEx and Patchable PCD in AsBuild INF
1426 if PcdFromModule
.Type
not in GenC
.gDynamicExPcd
and PcdFromModule
.Type
not in TAB_PCDS_PATCHABLE_IN_MODULE
:
1427 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
1429 ExtraData
="\n\tExisted %s PCD %s in:\n\t\t%s\n"
1430 % (PcdFromModule
.Type
, PcdFromModule
.TokenCName
, InfName
))
1431 # make sure that the "VOID*" kind of datum has MaxDatumSize set
1432 if PcdFromModule
.DatumType
== "VOID*" and PcdFromModule
.MaxDatumSize
in [None, '']:
1433 NoDatumTypePcdList
.add("%s.%s [%s]" % (PcdFromModule
.TokenSpaceGuidCName
, PcdFromModule
.TokenCName
, InfName
))
1434 if M
.ModuleType
in ["PEIM", "PEI_CORE"]:
1435 PcdFromModule
.Phase
= "PEI"
1436 if PcdFromModule
not in self
._DynaPcdList
_ and PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
1437 self
._DynaPcdList
_.append(PcdFromModule
)
1438 elif PcdFromModule
not in self
._NonDynaPcdList
_ and PcdFromModule
.Type
in TAB_PCDS_PATCHABLE_IN_MODULE
:
1439 self
._NonDynaPcdList
_.append(PcdFromModule
)
1440 if PcdFromModule
in self
._DynaPcdList
_ and PcdFromModule
.Phase
== 'PEI' and PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
1441 # Overwrite the phase of any the same PCD existing, if Phase is PEI.
1442 # It is to solve the case that a dynamic PCD used by a PEM module/PEI
1443 # module & DXE module at a same time.
1444 # Overwrite the type of the PCDs in source INF by the type of AsBuild
1445 # INF file as DynamicEx.
1446 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
1447 self
._DynaPcdList
_[Index
].Phase
= PcdFromModule
.Phase
1448 self
._DynaPcdList
_[Index
].Type
= PcdFromModule
.Type
1449 for PcdFromModule
in self
._NonDynaPcdList
_:
1450 # If a PCD is not listed in the DSC file, but binary INF files used by
1451 # this platform all (that use this PCD) list the PCD in a [PatchPcds]
1452 # section, AND all source INF files used by this platform the build
1453 # that use the PCD list the PCD in either a [Pcds] or [PatchPcds]
1454 # section, then the tools must NOT add the PCD to the Platform's PCD
1455 # Database; the build must assign the access method for this PCD as
1456 # PcdsPatchableInModule.
1457 if PcdFromModule
not in self
._DynaPcdList
_:
1459 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
1460 if PcdFromModule
.IsFromDsc
== False and \
1461 PcdFromModule
.Type
in TAB_PCDS_PATCHABLE_IN_MODULE
and \
1462 PcdFromModule
.IsFromBinaryInf
== True and \
1463 self
._DynaPcdList
_[Index
].IsFromBinaryInf
== False:
1464 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
1465 self
._DynaPcdList
_.remove (self
._DynaPcdList
_[Index
])
1467 # print out error information and break the build, if error found
1468 if len(NoDatumTypePcdList
) > 0:
1469 NoDatumTypePcdListString
= "\n\t\t".join(NoDatumTypePcdList
)
1470 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
1472 ExtraData
="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
1473 % NoDatumTypePcdListString
)
1474 self
._NonDynamicPcdList
= self
._NonDynaPcdList
_
1475 self
._DynamicPcdList
= self
._DynaPcdList
_
1477 # Sort dynamic PCD list to:
1478 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should
1479 # try to be put header of dynamicd List
1480 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD
1482 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
1484 UnicodePcdArray
= []
1488 VpdFile
= VpdInfoFile
.VpdInfoFile()
1489 NeedProcessVpdMapFile
= False
1491 for pcd
in self
.Platform
.Pcds
.keys():
1492 if pcd
not in self
._PlatformPcds
.keys():
1493 self
._PlatformPcds
[pcd
] = self
.Platform
.Pcds
[pcd
]
1495 if (self
.Workspace
.ArchList
[-1] == self
.Arch
):
1496 for Pcd
in self
._DynamicPcdList
:
1497 # just pick the a value to determine whether is unicode string type
1498 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
1499 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
1501 PcdValue
= Sku
.DefaultValue
1502 if Pcd
.DatumType
== 'VOID*' and PcdValue
.startswith("L"):
1503 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
1504 UnicodePcdArray
.append(Pcd
)
1505 elif len(Sku
.VariableName
) > 0:
1506 # if found HII type PCD then insert to right of UnicodeIndex
1507 HiiPcdArray
.append(Pcd
)
1509 OtherPcdArray
.append(Pcd
)
1510 if Pcd
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
]:
1511 VpdPcdDict
[(Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
)] = Pcd
1513 PlatformPcds
= self
._PlatformPcds
.keys()
1516 # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.
1518 for PcdKey
in PlatformPcds
:
1519 Pcd
= self
._PlatformPcds
[PcdKey
]
1520 if Pcd
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
] and \
1521 PcdKey
in VpdPcdDict
:
1522 Pcd
= VpdPcdDict
[PcdKey
]
1523 for (SkuName
,Sku
) in Pcd
.SkuInfoList
.items():
1524 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
1525 PcdValue
= Sku
.DefaultValue
1527 PcdValue
= Pcd
.DefaultValue
1528 if Sku
.VpdOffset
!= '*':
1529 if PcdValue
.startswith("{"):
1531 elif PcdValue
.startswith("L"):
1536 VpdOffset
= int(Sku
.VpdOffset
)
1539 VpdOffset
= int(Sku
.VpdOffset
, 16)
1541 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid offset value %s for PCD %s.%s." % (Sku
.VpdOffset
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
1542 if VpdOffset
% Alignment
!= 0:
1543 if PcdValue
.startswith("{"):
1544 EdkLogger
.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
), File
=self
.MetaFile
)
1546 EdkLogger
.error("build", FORMAT_INVALID
, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Alignment
))
1547 VpdFile
.Add(Pcd
, Sku
.VpdOffset
)
1548 # if the offset of a VPD is *, then it need to be fixed up by third party tool.
1549 if not NeedProcessVpdMapFile
and Sku
.VpdOffset
== "*":
1550 NeedProcessVpdMapFile
= True
1551 if self
.Platform
.VpdToolGuid
== None or self
.Platform
.VpdToolGuid
== '':
1552 EdkLogger
.error("Build", FILE_NOT_FOUND
, \
1553 "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.")
1557 # Fix the PCDs define in VPD PCD section that never referenced by module.
1558 # An example is PCD for signature usage.
1560 for DscPcd
in PlatformPcds
:
1561 DscPcdEntry
= self
._PlatformPcds
[DscPcd
]
1562 if DscPcdEntry
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
]:
1563 if not (self
.Platform
.VpdToolGuid
== None or self
.Platform
.VpdToolGuid
== ''):
1565 for VpdPcd
in VpdFile
._VpdArray
.keys():
1566 # This PCD has been referenced by module
1567 if (VpdPcd
.TokenSpaceGuidCName
== DscPcdEntry
.TokenSpaceGuidCName
) and \
1568 (VpdPcd
.TokenCName
== DscPcdEntry
.TokenCName
):
1571 # Not found, it should be signature
1573 # just pick the a value to determine whether is unicode string type
1574 for (SkuName
,Sku
) in DscPcdEntry
.SkuInfoList
.items():
1575 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
1577 # Need to iterate DEC pcd information to get the value & datumtype
1578 for eachDec
in self
.PackageList
:
1579 for DecPcd
in eachDec
.Pcds
:
1580 DecPcdEntry
= eachDec
.Pcds
[DecPcd
]
1581 if (DecPcdEntry
.TokenSpaceGuidCName
== DscPcdEntry
.TokenSpaceGuidCName
) and \
1582 (DecPcdEntry
.TokenCName
== DscPcdEntry
.TokenCName
):
1583 # Print warning message to let the developer make a determine.
1584 EdkLogger
.warn("build", "Unreferenced vpd pcd used!",
1585 File
=self
.MetaFile
, \
1586 ExtraData
= "PCD: %s.%s used in the DSC file %s is unreferenced." \
1587 %(DscPcdEntry
.TokenSpaceGuidCName
, DscPcdEntry
.TokenCName
, self
.Platform
.MetaFile
.Path
))
1589 DscPcdEntry
.DatumType
= DecPcdEntry
.DatumType
1590 DscPcdEntry
.DefaultValue
= DecPcdEntry
.DefaultValue
1591 DscPcdEntry
.TokenValue
= DecPcdEntry
.TokenValue
1592 DscPcdEntry
.TokenSpaceGuidValue
= eachDec
.Guids
[DecPcdEntry
.TokenSpaceGuidCName
]
1593 # Only fix the value while no value provided in DSC file.
1594 if (Sku
.DefaultValue
== "" or Sku
.DefaultValue
==None):
1595 DscPcdEntry
.SkuInfoList
[DscPcdEntry
.SkuInfoList
.keys()[0]].DefaultValue
= DecPcdEntry
.DefaultValue
1597 if DscPcdEntry
not in self
._DynamicPcdList
:
1598 self
._DynamicPcdList
.append(DscPcdEntry
)
1599 # Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]
1600 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
1601 PcdValue
= Sku
.DefaultValue
1603 PcdValue
= DscPcdEntry
.DefaultValue
1604 if Sku
.VpdOffset
!= '*':
1605 if PcdValue
.startswith("{"):
1607 elif PcdValue
.startswith("L"):
1612 VpdOffset
= int(Sku
.VpdOffset
)
1615 VpdOffset
= int(Sku
.VpdOffset
, 16)
1617 EdkLogger
.error("build", FORMAT_INVALID
, "Invalid offset value %s for PCD %s.%s." % (Sku
.VpdOffset
, DscPcdEntry
.TokenSpaceGuidCName
, DscPcdEntry
.TokenCName
))
1618 if VpdOffset
% Alignment
!= 0:
1619 if PcdValue
.startswith("{"):
1620 EdkLogger
.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(DscPcdEntry
.TokenSpaceGuidCName
, DscPcdEntry
.TokenCName
), File
=self
.MetaFile
)
1622 EdkLogger
.error("build", FORMAT_INVALID
, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (DscPcdEntry
.TokenSpaceGuidCName
, DscPcdEntry
.TokenCName
, Alignment
))
1623 VpdFile
.Add(DscPcdEntry
, Sku
.VpdOffset
)
1624 if not NeedProcessVpdMapFile
and Sku
.VpdOffset
== "*":
1625 NeedProcessVpdMapFile
= True
1626 if DscPcdEntry
.DatumType
== 'VOID*' and PcdValue
.startswith("L"):
1627 UnicodePcdArray
.append(DscPcdEntry
)
1628 elif len(Sku
.VariableName
) > 0:
1629 HiiPcdArray
.append(DscPcdEntry
)
1631 OtherPcdArray
.append(DscPcdEntry
)
1633 # if the offset of a VPD is *, then it need to be fixed up by third party tool.
1637 if (self
.Platform
.FlashDefinition
== None or self
.Platform
.FlashDefinition
== '') and \
1638 VpdFile
.GetCount() != 0:
1639 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1640 "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self
.Platform
.MetaFile
))
1642 if VpdFile
.GetCount() != 0:
1643 FvPath
= os
.path
.join(self
.BuildDir
, "FV")
1644 if not os
.path
.exists(FvPath
):
1648 EdkLogger
.error("build", FILE_WRITE_FAILURE
, "Fail to create FV folder under %s" % self
.BuildDir
)
1650 VpdFilePath
= os
.path
.join(FvPath
, "%s.txt" % self
.Platform
.VpdToolGuid
)
1652 if VpdFile
.Write(VpdFilePath
):
1653 # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.
1655 for ToolDef
in self
.ToolDefinition
.values():
1656 if ToolDef
.has_key("GUID") and ToolDef
["GUID"] == self
.Platform
.VpdToolGuid
:
1657 if not ToolDef
.has_key("PATH"):
1658 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self
.Platform
.VpdToolGuid
)
1659 BPDGToolName
= ToolDef
["PATH"]
1661 # Call third party GUID BPDG tool.
1662 if BPDGToolName
!= None:
1663 VpdInfoFile
.CallExtenalBPDGTool(BPDGToolName
, VpdFilePath
)
1665 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.")
1667 # Process VPD map file generated by third party BPDG tool
1668 if NeedProcessVpdMapFile
:
1669 VpdMapFilePath
= os
.path
.join(self
.BuildDir
, "FV", "%s.map" % self
.Platform
.VpdToolGuid
)
1670 if os
.path
.exists(VpdMapFilePath
):
1671 VpdFile
.Read(VpdMapFilePath
)
1674 for Pcd
in self
._DynamicPcdList
:
1675 # just pick the a value to determine whether is unicode string type
1677 for (SkuName
,Sku
) in Pcd
.SkuInfoList
.items():
1678 if Sku
.VpdOffset
== "*":
1679 Sku
.VpdOffset
= VpdFile
.GetOffset(Pcd
)[i
].strip()
1682 EdkLogger
.error("build", FILE_READ_FAILURE
, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath
)
1684 # Delete the DynamicPcdList At the last time enter into this function
1685 del self
._DynamicPcdList
[:]
1686 self
._DynamicPcdList
.extend(UnicodePcdArray
)
1687 self
._DynamicPcdList
.extend(HiiPcdArray
)
1688 self
._DynamicPcdList
.extend(OtherPcdArray
)
1689 self
.AllPcdList
= self
._NonDynamicPcdList
+ self
._DynamicPcdList
1691 ## Return the platform build data object
1692 def _GetPlatform(self
):
1693 if self
._Platform
== None:
1694 self
._Platform
= self
.BuildDatabase
[self
.MetaFile
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
1695 return self
._Platform
1697 ## Return platform name
1699 return self
.Platform
.PlatformName
1701 ## Return the meta file GUID
1703 return self
.Platform
.Guid
1705 ## Return the platform version
1706 def _GetVersion(self
):
1707 return self
.Platform
.Version
1709 ## Return the FDF file name
1710 def _GetFdfFile(self
):
1711 if self
._FdfFile
== None:
1712 if self
.Workspace
.FdfFile
!= "":
1713 self
._FdfFile
= mws
.join(self
.WorkspaceDir
, self
.Workspace
.FdfFile
)
1716 return self
._FdfFile
1718 ## Return the build output directory platform specifies
1719 def _GetOutputDir(self
):
1720 return self
.Platform
.OutputDirectory
1722 ## Return the directory to store all intermediate and final files built
1723 def _GetBuildDir(self
):
1724 if self
._BuildDir
== None:
1725 if os
.path
.isabs(self
.OutputDir
):
1726 self
._BuildDir
= path
.join(
1727 path
.abspath(self
.OutputDir
),
1728 self
.BuildTarget
+ "_" + self
.ToolChain
,
1731 self
._BuildDir
= path
.join(
1734 self
.BuildTarget
+ "_" + self
.ToolChain
,
1736 return self
._BuildDir
1738 ## Return directory of platform makefile
1740 # @retval string Makefile directory
1742 def _GetMakeFileDir(self
):
1743 if self
._MakeFileDir
== None:
1744 self
._MakeFileDir
= path
.join(self
.BuildDir
, self
.Arch
)
1745 return self
._MakeFileDir
1747 ## Return build command string
1749 # @retval string Build command string
1751 def _GetBuildCommand(self
):
1752 if self
._BuildCommand
== None:
1753 self
._BuildCommand
= []
1754 if "MAKE" in self
.ToolDefinition
and "PATH" in self
.ToolDefinition
["MAKE"]:
1755 self
._BuildCommand
+= SplitOption(self
.ToolDefinition
["MAKE"]["PATH"])
1756 if "FLAGS" in self
.ToolDefinition
["MAKE"]:
1757 NewOption
= self
.ToolDefinition
["MAKE"]["FLAGS"].strip()
1759 self
._BuildCommand
+= SplitOption(NewOption
)
1760 return self
._BuildCommand
1762 ## Get tool chain definition
1764 # Get each tool defition for given tool chain from tools_def.txt and platform
1766 def _GetToolDefinition(self
):
1767 if self
._ToolDefinitions
== None:
1768 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDictionary
1769 if TAB_TOD_DEFINES_COMMAND_TYPE
not in self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
:
1770 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No tools found in configuration",
1771 ExtraData
="[%s]" % self
.MetaFile
)
1772 self
._ToolDefinitions
= {}
1774 for Def
in ToolDefinition
:
1775 Target
, Tag
, Arch
, Tool
, Attr
= Def
.split("_")
1776 if Target
!= self
.BuildTarget
or Tag
!= self
.ToolChain
or Arch
!= self
.Arch
:
1779 Value
= ToolDefinition
[Def
]
1780 # don't record the DLL
1782 DllPathList
.add(Value
)
1785 if Tool
not in self
._ToolDefinitions
:
1786 self
._ToolDefinitions
[Tool
] = {}
1787 self
._ToolDefinitions
[Tool
][Attr
] = Value
1791 if GlobalData
.gOptions
.SilentMode
and "MAKE" in self
._ToolDefinitions
:
1792 if "FLAGS" not in self
._ToolDefinitions
["MAKE"]:
1793 self
._ToolDefinitions
["MAKE"]["FLAGS"] = ""
1794 self
._ToolDefinitions
["MAKE"]["FLAGS"] += " -s"
1796 for Tool
in self
._ToolDefinitions
:
1797 for Attr
in self
._ToolDefinitions
[Tool
]:
1798 Value
= self
._ToolDefinitions
[Tool
][Attr
]
1799 if Tool
in self
.BuildOption
and Attr
in self
.BuildOption
[Tool
]:
1800 # check if override is indicated
1801 if self
.BuildOption
[Tool
][Attr
].startswith('='):
1802 Value
= self
.BuildOption
[Tool
][Attr
][1:]
1805 Value
+= " " + self
.BuildOption
[Tool
][Attr
]
1807 Value
= self
.BuildOption
[Tool
][Attr
]
1810 # Don't put MAKE definition in the file
1814 ToolsDef
+= "%s = %s\n" % (Tool
, Value
)
1816 # Don't put MAKE definition in the file
1821 ToolsDef
+= "%s_%s = %s\n" % (Tool
, Attr
, Value
)
1824 SaveFileOnChange(self
.ToolDefinitionFile
, ToolsDef
)
1825 for DllPath
in DllPathList
:
1826 os
.environ
["PATH"] = DllPath
+ os
.pathsep
+ os
.environ
["PATH"]
1827 os
.environ
["MAKE_FLAGS"] = MakeFlags
1829 return self
._ToolDefinitions
1831 ## Return the paths of tools
1832 def _GetToolDefFile(self
):
1833 if self
._ToolDefFile
== None:
1834 self
._ToolDefFile
= os
.path
.join(self
.MakeFileDir
, "TOOLS_DEF." + self
.Arch
)
1835 return self
._ToolDefFile
1837 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
1838 def _GetToolChainFamily(self
):
1839 if self
._ToolChainFamily
== None:
1840 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
1841 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
1842 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
1843 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]:
1844 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
1846 self
._ToolChainFamily
= "MSFT"
1848 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]
1849 return self
._ToolChainFamily
1851 def _GetBuildRuleFamily(self
):
1852 if self
._BuildRuleFamily
== None:
1853 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
1854 if TAB_TOD_DEFINES_BUILDRULEFAMILY
not in ToolDefinition \
1855 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
1856 or not ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]:
1857 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
1859 self
._BuildRuleFamily
= "MSFT"
1861 self
._BuildRuleFamily
= ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]
1862 return self
._BuildRuleFamily
1864 ## Return the build options specific for all modules in this platform
1865 def _GetBuildOptions(self
):
1866 if self
._BuildOption
== None:
1867 self
._BuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
)
1868 return self
._BuildOption
1870 ## Return the build options specific for EDK modules in this platform
1871 def _GetEdkBuildOptions(self
):
1872 if self
._EdkBuildOption
== None:
1873 self
._EdkBuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
, EDK_NAME
)
1874 return self
._EdkBuildOption
1876 ## Return the build options specific for EDKII modules in this platform
1877 def _GetEdkIIBuildOptions(self
):
1878 if self
._EdkIIBuildOption
== None:
1879 self
._EdkIIBuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
, EDKII_NAME
)
1880 return self
._EdkIIBuildOption
1882 ## Parse build_rule.txt in Conf Directory.
1884 # @retval BuildRule object
1886 def _GetBuildRule(self
):
1887 if self
._BuildRule
== None:
1888 BuildRuleFile
= None
1889 if TAB_TAT_DEFINES_BUILD_RULE_CONF
in self
.Workspace
.TargetTxt
.TargetTxtDictionary
:
1890 BuildRuleFile
= self
.Workspace
.TargetTxt
.TargetTxtDictionary
[TAB_TAT_DEFINES_BUILD_RULE_CONF
]
1891 if BuildRuleFile
in [None, '']:
1892 BuildRuleFile
= gDefaultBuildRuleFile
1893 self
._BuildRule
= BuildRule(BuildRuleFile
)
1894 if self
._BuildRule
._FileVersion
== "":
1895 self
._BuildRule
._FileVersion
= AutoGenReqBuildRuleVerNum
1897 if self
._BuildRule
._FileVersion
< AutoGenReqBuildRuleVerNum
:
1898 # If Build Rule's version is less than the version number required by the tools, halting the build.
1899 EdkLogger
.error("build", AUTOGEN_ERROR
,
1900 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])"\
1901 % (self
._BuildRule
._FileVersion
, AutoGenReqBuildRuleVerNum
))
1903 return self
._BuildRule
1905 ## Summarize the packages used by modules in this platform
1906 def _GetPackageList(self
):
1907 if self
._PackageList
== None:
1908 self
._PackageList
= set()
1909 for La
in self
.LibraryAutoGenList
:
1910 self
._PackageList
.update(La
.DependentPackageList
)
1911 for Ma
in self
.ModuleAutoGenList
:
1912 self
._PackageList
.update(Ma
.DependentPackageList
)
1913 #Collect package set information from INF of FDF
1915 for ModuleFile
in self
._AsBuildModuleList
:
1916 if ModuleFile
in self
.Platform
.Modules
:
1918 ModuleData
= self
.BuildDatabase
[ModuleFile
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
1919 PkgSet
.update(ModuleData
.Packages
)
1920 self
._PackageList
= list(self
._PackageList
) + list (PkgSet
)
1921 return self
._PackageList
1923 def _GetNonDynamicPcdDict(self
):
1924 if self
._NonDynamicPcdDict
:
1925 return self
._NonDynamicPcdDict
1926 for Pcd
in self
.NonDynamicPcdList
:
1927 self
._NonDynamicPcdDict
[(Pcd
.TokenCName
,Pcd
.TokenSpaceGuidCName
)] = Pcd
1928 return self
._NonDynamicPcdDict
1930 ## Get list of non-dynamic PCDs
1931 def _GetNonDynamicPcdList(self
):
1932 if self
._NonDynamicPcdList
== None:
1933 self
.CollectPlatformDynamicPcds()
1934 return self
._NonDynamicPcdList
1936 ## Get list of dynamic PCDs
1937 def _GetDynamicPcdList(self
):
1938 if self
._DynamicPcdList
== None:
1939 self
.CollectPlatformDynamicPcds()
1940 return self
._DynamicPcdList
1942 ## Generate Token Number for all PCD
1943 def _GetPcdTokenNumbers(self
):
1944 if self
._PcdTokenNumber
== None:
1945 self
._PcdTokenNumber
= sdict()
1948 # Make the Dynamic and DynamicEx PCD use within different TokenNumber area.
1952 # TokenNumber 0 ~ 10
1954 # TokeNumber 11 ~ 20
1956 for Pcd
in self
.DynamicPcdList
:
1957 if Pcd
.Phase
== "PEI":
1958 if Pcd
.Type
in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
1959 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
1960 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1963 for Pcd
in self
.DynamicPcdList
:
1964 if Pcd
.Phase
== "PEI":
1965 if Pcd
.Type
in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
1966 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
1967 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1970 for Pcd
in self
.DynamicPcdList
:
1971 if Pcd
.Phase
== "DXE":
1972 if Pcd
.Type
in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
1973 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
1974 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1977 for Pcd
in self
.DynamicPcdList
:
1978 if Pcd
.Phase
== "DXE":
1979 if Pcd
.Type
in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
1980 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
1981 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1984 for Pcd
in self
.NonDynamicPcdList
:
1985 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1987 return self
._PcdTokenNumber
1989 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
1990 def _GetAutoGenObjectList(self
):
1991 self
._ModuleAutoGenList
= []
1992 self
._LibraryAutoGenList
= []
1993 for ModuleFile
in self
.Platform
.Modules
:
2002 if Ma
not in self
._ModuleAutoGenList
:
2003 self
._ModuleAutoGenList
.append(Ma
)
2004 for La
in Ma
.LibraryAutoGenList
:
2005 if La
not in self
._LibraryAutoGenList
:
2006 self
._LibraryAutoGenList
.append(La
)
2007 if Ma
not in La
._ReferenceModules
:
2008 La
._ReferenceModules
.append(Ma
)
2010 ## Summarize ModuleAutoGen objects of all modules to be built for this platform
2011 def _GetModuleAutoGenList(self
):
2012 if self
._ModuleAutoGenList
== None:
2013 self
._GetAutoGenObjectList
()
2014 return self
._ModuleAutoGenList
2016 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
2017 def _GetLibraryAutoGenList(self
):
2018 if self
._LibraryAutoGenList
== None:
2019 self
._GetAutoGenObjectList
()
2020 return self
._LibraryAutoGenList
2022 ## Test if a module is supported by the platform
2024 # An error will be raised directly if the module or its arch is not supported
2025 # by the platform or current configuration
2027 def ValidModule(self
, Module
):
2028 return Module
in self
.Platform
.Modules
or Module
in self
.Platform
.LibraryInstances \
2029 or Module
in self
._AsBuildModuleList
2031 ## Resolve the library classes in a module to library instances
2033 # This method will not only resolve library classes but also sort the library
2034 # instances according to the dependency-ship.
2036 # @param Module The module from which the library classes will be resolved
2038 # @retval library_list List of library instances sorted
2040 def ApplyLibraryInstance(self
, Module
):
2041 # Cover the case that the binary INF file is list in the FDF file but not DSC file, return empty list directly
2042 if str(Module
) not in self
.Platform
.Modules
:
2045 ModuleType
= Module
.ModuleType
2047 # for overridding library instances with module specific setting
2048 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
2050 # add forced library instances (specified under LibraryClasses sections)
2052 # If a module has a MODULE_TYPE of USER_DEFINED,
2053 # do not link in NULL library class instances from the global [LibraryClasses.*] sections.
2055 if Module
.ModuleType
!= SUP_MODULE_USER_DEFINED
:
2056 for LibraryClass
in self
.Platform
.LibraryClasses
.GetKeys():
2057 if LibraryClass
.startswith("NULL") and self
.Platform
.LibraryClasses
[LibraryClass
, Module
.ModuleType
]:
2058 Module
.LibraryClasses
[LibraryClass
] = self
.Platform
.LibraryClasses
[LibraryClass
, Module
.ModuleType
]
2060 # add forced library instances (specified in module overrides)
2061 for LibraryClass
in PlatformModule
.LibraryClasses
:
2062 if LibraryClass
.startswith("NULL"):
2063 Module
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
2066 LibraryConsumerList
= [Module
]
2068 ConsumedByList
= sdict()
2069 LibraryInstance
= sdict()
2071 EdkLogger
.verbose("")
2072 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
2073 while len(LibraryConsumerList
) > 0:
2074 M
= LibraryConsumerList
.pop()
2075 for LibraryClassName
in M
.LibraryClasses
:
2076 if LibraryClassName
not in LibraryInstance
:
2077 # override library instance for this module
2078 if LibraryClassName
in PlatformModule
.LibraryClasses
:
2079 LibraryPath
= PlatformModule
.LibraryClasses
[LibraryClassName
]
2081 LibraryPath
= self
.Platform
.LibraryClasses
[LibraryClassName
, ModuleType
]
2082 if LibraryPath
== None or LibraryPath
== "":
2083 LibraryPath
= M
.LibraryClasses
[LibraryClassName
]
2084 if LibraryPath
== None or LibraryPath
== "":
2085 EdkLogger
.error("build", RESOURCE_NOT_AVAILABLE
,
2086 "Instance of library class [%s] is not found" % LibraryClassName
,
2088 ExtraData
="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M
), self
.Arch
, str(Module
)))
2090 LibraryModule
= self
.BuildDatabase
[LibraryPath
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
2091 # for those forced library instance (NULL library), add a fake library class
2092 if LibraryClassName
.startswith("NULL"):
2093 LibraryModule
.LibraryClass
.append(LibraryClassObject(LibraryClassName
, [ModuleType
]))
2094 elif LibraryModule
.LibraryClass
== None \
2095 or len(LibraryModule
.LibraryClass
) == 0 \
2096 or (ModuleType
!= 'USER_DEFINED'
2097 and ModuleType
not in LibraryModule
.LibraryClass
[0].SupModList
):
2098 # only USER_DEFINED can link against any library instance despite of its SupModList
2099 EdkLogger
.error("build", OPTION_MISSING
,
2100 "Module type [%s] is not supported by library instance [%s]" \
2101 % (ModuleType
, LibraryPath
), File
=self
.MetaFile
,
2102 ExtraData
="consumed by [%s]" % str(Module
))
2104 LibraryInstance
[LibraryClassName
] = LibraryModule
2105 LibraryConsumerList
.append(LibraryModule
)
2106 EdkLogger
.verbose("\t" + str(LibraryClassName
) + " : " + str(LibraryModule
))
2108 LibraryModule
= LibraryInstance
[LibraryClassName
]
2110 if LibraryModule
== None:
2113 if LibraryModule
.ConstructorList
!= [] and LibraryModule
not in Constructor
:
2114 Constructor
.append(LibraryModule
)
2116 if LibraryModule
not in ConsumedByList
:
2117 ConsumedByList
[LibraryModule
] = []
2118 # don't add current module itself to consumer list
2120 if M
in ConsumedByList
[LibraryModule
]:
2122 ConsumedByList
[LibraryModule
].append(M
)
2124 # Initialize the sorted output list to the empty set
2126 SortedLibraryList
= []
2128 # Q <- Set of all nodes with no incoming edges
2130 LibraryList
= [] #LibraryInstance.values()
2132 for LibraryClassName
in LibraryInstance
:
2133 M
= LibraryInstance
[LibraryClassName
]
2134 LibraryList
.append(M
)
2135 if ConsumedByList
[M
] == []:
2139 # start the DAG algorithm
2143 while Q
== [] and EdgeRemoved
:
2145 # for each node Item with a Constructor
2146 for Item
in LibraryList
:
2147 if Item
not in Constructor
:
2149 # for each Node without a constructor with an edge e from Item to Node
2150 for Node
in ConsumedByList
[Item
]:
2151 if Node
in Constructor
:
2153 # remove edge e from the graph if Node has no constructor
2154 ConsumedByList
[Item
].remove(Node
)
2156 if ConsumedByList
[Item
] == []:
2157 # insert Item into Q
2162 # DAG is done if there's no more incoming edge for all nodes
2166 # remove node from Q
2169 SortedLibraryList
.append(Node
)
2171 # for each node Item with an edge e from Node to Item do
2172 for Item
in LibraryList
:
2173 if Node
not in ConsumedByList
[Item
]:
2175 # remove edge e from the graph
2176 ConsumedByList
[Item
].remove(Node
)
2178 if ConsumedByList
[Item
] != []:
2180 # insert Item into Q, if Item has no other incoming edges
2184 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
2186 for Item
in LibraryList
:
2187 if ConsumedByList
[Item
] != [] and Item
in Constructor
and len(Constructor
) > 1:
2188 ErrorMessage
= "\tconsumed by " + "\n\tconsumed by ".join([str(L
) for L
in ConsumedByList
[Item
]])
2189 EdkLogger
.error("build", BUILD_ERROR
, 'Library [%s] with constructors has a cycle' % str(Item
),
2190 ExtraData
=ErrorMessage
, File
=self
.MetaFile
)
2191 if Item
not in SortedLibraryList
:
2192 SortedLibraryList
.append(Item
)
2195 # Build the list of constructor and destructir names
2196 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
2198 SortedLibraryList
.reverse()
2199 return SortedLibraryList
2202 ## Override PCD setting (type, value, ...)
2204 # @param ToPcd The PCD to be overrided
2205 # @param FromPcd The PCD overrideing from
2207 def _OverridePcd(self
, ToPcd
, FromPcd
, Module
=""):
2209 # in case there's PCDs coming from FDF file, which have no type given.
2210 # at this point, ToPcd.Type has the type found from dependent
2213 TokenCName
= ToPcd
.TokenCName
2214 for PcdItem
in GlobalData
.MixedPcd
:
2215 if (ToPcd
.TokenCName
, ToPcd
.TokenSpaceGuidCName
) in GlobalData
.MixedPcd
[PcdItem
]:
2216 TokenCName
= PcdItem
[0]
2219 if GlobalData
.BuildOptionPcd
:
2220 for pcd
in GlobalData
.BuildOptionPcd
:
2221 if (FromPcd
.TokenSpaceGuidCName
, FromPcd
.TokenCName
) == (pcd
[0], pcd
[1]):
2222 FromPcd
.DefaultValue
= pcd
[2]
2224 if ToPcd
.Pending
and FromPcd
.Type
not in [None, '']:
2225 ToPcd
.Type
= FromPcd
.Type
2226 elif (ToPcd
.Type
not in [None, '']) and (FromPcd
.Type
not in [None, ''])\
2227 and (ToPcd
.Type
!= FromPcd
.Type
) and (ToPcd
.Type
in FromPcd
.Type
):
2228 if ToPcd
.Type
.strip() == "DynamicEx":
2229 ToPcd
.Type
= FromPcd
.Type
2230 elif ToPcd
.Type
not in [None, ''] and FromPcd
.Type
not in [None, ''] \
2231 and ToPcd
.Type
!= FromPcd
.Type
:
2232 EdkLogger
.error("build", OPTION_CONFLICT
, "Mismatched PCD type",
2233 ExtraData
="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
2234 % (ToPcd
.TokenSpaceGuidCName
, TokenCName
,
2235 ToPcd
.Type
, Module
, FromPcd
.Type
),
2238 if FromPcd
.MaxDatumSize
not in [None, '']:
2239 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
2240 if FromPcd
.DefaultValue
not in [None, '']:
2241 ToPcd
.DefaultValue
= FromPcd
.DefaultValue
2242 if FromPcd
.TokenValue
not in [None, '']:
2243 ToPcd
.TokenValue
= FromPcd
.TokenValue
2244 if FromPcd
.MaxDatumSize
not in [None, '']:
2245 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
2246 if FromPcd
.DatumType
not in [None, '']:
2247 ToPcd
.DatumType
= FromPcd
.DatumType
2248 if FromPcd
.SkuInfoList
not in [None, '', []]:
2249 ToPcd
.SkuInfoList
= FromPcd
.SkuInfoList
2251 # check the validation of datum
2252 IsValid
, Cause
= CheckPcdDatum(ToPcd
.DatumType
, ToPcd
.DefaultValue
)
2254 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, File
=self
.MetaFile
,
2255 ExtraData
="%s.%s" % (ToPcd
.TokenSpaceGuidCName
, TokenCName
))
2256 ToPcd
.validateranges
= FromPcd
.validateranges
2257 ToPcd
.validlists
= FromPcd
.validlists
2258 ToPcd
.expressions
= FromPcd
.expressions
2260 if ToPcd
.DatumType
== "VOID*" and ToPcd
.MaxDatumSize
in ['', None]:
2261 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "No MaxDatumSize specified for PCD %s.%s" \
2262 % (ToPcd
.TokenSpaceGuidCName
, TokenCName
))
2263 Value
= ToPcd
.DefaultValue
2264 if Value
in [None, '']:
2265 ToPcd
.MaxDatumSize
= '1'
2266 elif Value
[0] == 'L':
2267 ToPcd
.MaxDatumSize
= str((len(Value
) - 2) * 2)
2268 elif Value
[0] == '{':
2269 ToPcd
.MaxDatumSize
= str(len(Value
.split(',')))
2271 ToPcd
.MaxDatumSize
= str(len(Value
) - 1)
2273 # apply default SKU for dynamic PCDS if specified one is not available
2274 if (ToPcd
.Type
in PCD_DYNAMIC_TYPE_LIST
or ToPcd
.Type
in PCD_DYNAMIC_EX_TYPE_LIST
) \
2275 and ToPcd
.SkuInfoList
in [None, {}, '']:
2276 if self
.Platform
.SkuName
in self
.Platform
.SkuIds
:
2277 SkuName
= self
.Platform
.SkuName
2280 ToPcd
.SkuInfoList
= {
2281 SkuName
: SkuInfoClass(SkuName
, self
.Platform
.SkuIds
[SkuName
], '', '', '', '', '', ToPcd
.DefaultValue
)
2284 ## Apply PCD setting defined platform to a module
2286 # @param Module The module from which the PCD setting will be overrided
2288 # @retval PCD_list The list PCDs with settings from platform
2290 def ApplyPcdSetting(self
, Module
, Pcds
):
2291 # for each PCD in module
2292 for Name
, Guid
in Pcds
:
2293 PcdInModule
= Pcds
[Name
, Guid
]
2294 # find out the PCD setting in platform
2295 if (Name
, Guid
) in self
.Platform
.Pcds
:
2296 PcdInPlatform
= self
.Platform
.Pcds
[Name
, Guid
]
2298 PcdInPlatform
= None
2299 # then override the settings if any
2300 self
._OverridePcd
(PcdInModule
, PcdInPlatform
, Module
)
2301 # resolve the VariableGuid value
2302 for SkuId
in PcdInModule
.SkuInfoList
:
2303 Sku
= PcdInModule
.SkuInfoList
[SkuId
]
2304 if Sku
.VariableGuid
== '': continue
2305 Sku
.VariableGuidValue
= GuidValue(Sku
.VariableGuid
, self
.PackageList
, self
.MetaFile
.Path
)
2306 if Sku
.VariableGuidValue
== None:
2307 PackageList
= "\n\t".join([str(P
) for P
in self
.PackageList
])
2310 RESOURCE_NOT_AVAILABLE
,
2311 "Value of GUID [%s] is not found in" % Sku
.VariableGuid
,
2312 ExtraData
=PackageList
+ "\n\t(used with %s.%s from module %s)" \
2313 % (Guid
, Name
, str(Module
)),
2317 # override PCD settings with module specific setting
2318 if Module
in self
.Platform
.Modules
:
2319 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
2320 for Key
in PlatformModule
.Pcds
:
2322 self
._OverridePcd
(Pcds
[Key
], PlatformModule
.Pcds
[Key
], Module
)
2323 return Pcds
.values()
2325 ## Resolve library names to library modules
2327 # (for Edk.x modules)
2329 # @param Module The module from which the library names will be resolved
2331 # @retval library_list The list of library modules
2333 def ResolveLibraryReference(self
, Module
):
2334 EdkLogger
.verbose("")
2335 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
2336 LibraryConsumerList
= [Module
]
2338 # "CompilerStub" is a must for Edk modules
2339 if Module
.Libraries
:
2340 Module
.Libraries
.append("CompilerStub")
2342 while len(LibraryConsumerList
) > 0:
2343 M
= LibraryConsumerList
.pop()
2344 for LibraryName
in M
.Libraries
:
2345 Library
= self
.Platform
.LibraryClasses
[LibraryName
, ':dummy:']
2347 for Key
in self
.Platform
.LibraryClasses
.data
.keys():
2348 if LibraryName
.upper() == Key
.upper():
2349 Library
= self
.Platform
.LibraryClasses
[Key
, ':dummy:']
2352 EdkLogger
.warn("build", "Library [%s] is not found" % LibraryName
, File
=str(M
),
2353 ExtraData
="\t%s [%s]" % (str(Module
), self
.Arch
))
2356 if Library
not in LibraryList
:
2357 LibraryList
.append(Library
)
2358 LibraryConsumerList
.append(Library
)
2359 EdkLogger
.verbose("\t" + LibraryName
+ " : " + str(Library
) + ' ' + str(type(Library
)))
2362 ## Calculate the priority value of the build option
2364 # @param Key Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
2366 # @retval Value Priority value based on the priority list.
2368 def CalculatePriorityValue(self
, Key
):
2369 Target
, ToolChain
, Arch
, CommandType
, Attr
= Key
.split('_')
2370 PriorityValue
= 0x11111
2372 PriorityValue
&= 0x01111
2373 if ToolChain
== "*":
2374 PriorityValue
&= 0x10111
2376 PriorityValue
&= 0x11011
2377 if CommandType
== "*":
2378 PriorityValue
&= 0x11101
2380 PriorityValue
&= 0x11110
2382 return self
.PrioList
["0x%0.5x" % PriorityValue
]
2385 ## Expand * in build option key
2387 # @param Options Options to be expanded
2389 # @retval options Options expanded
2391 def _ExpandBuildOption(self
, Options
, ModuleStyle
=None):
2398 # Construct a list contain the build options which need override.
2402 # Key[0] -- tool family
2403 # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
2405 if (Key
[0] == self
.BuildRuleFamily
and
2406 (ModuleStyle
== None or len(Key
) < 3 or (len(Key
) > 2 and Key
[2] == ModuleStyle
))):
2407 Target
, ToolChain
, Arch
, CommandType
, Attr
= Key
[1].split('_')
2408 if Target
== self
.BuildTarget
or Target
== "*":
2409 if ToolChain
== self
.ToolChain
or ToolChain
== "*":
2410 if Arch
== self
.Arch
or Arch
== "*":
2411 if Options
[Key
].startswith("="):
2412 if OverrideList
.get(Key
[1]) != None:
2413 OverrideList
.pop(Key
[1])
2414 OverrideList
[Key
[1]] = Options
[Key
]
2417 # Use the highest priority value.
2419 if (len(OverrideList
) >= 2):
2420 KeyList
= OverrideList
.keys()
2421 for Index
in range(len(KeyList
)):
2422 NowKey
= KeyList
[Index
]
2423 Target1
, ToolChain1
, Arch1
, CommandType1
, Attr1
= NowKey
.split("_")
2424 for Index1
in range(len(KeyList
) - Index
- 1):
2425 NextKey
= KeyList
[Index1
+ Index
+ 1]
2427 # Compare two Key, if one is included by another, choose the higher priority one
2429 Target2
, ToolChain2
, Arch2
, CommandType2
, Attr2
= NextKey
.split("_")
2430 if Target1
== Target2
or Target1
== "*" or Target2
== "*":
2431 if ToolChain1
== ToolChain2
or ToolChain1
== "*" or ToolChain2
== "*":
2432 if Arch1
== Arch2
or Arch1
== "*" or Arch2
== "*":
2433 if CommandType1
== CommandType2
or CommandType1
== "*" or CommandType2
== "*":
2434 if Attr1
== Attr2
or Attr1
== "*" or Attr2
== "*":
2435 if self
.CalculatePriorityValue(NowKey
) > self
.CalculatePriorityValue(NextKey
):
2436 if Options
.get((self
.BuildRuleFamily
, NextKey
)) != None:
2437 Options
.pop((self
.BuildRuleFamily
, NextKey
))
2439 if Options
.get((self
.BuildRuleFamily
, NowKey
)) != None:
2440 Options
.pop((self
.BuildRuleFamily
, NowKey
))
2443 if ModuleStyle
!= None and len (Key
) > 2:
2444 # Check Module style is EDK or EDKII.
2445 # Only append build option for the matched style module.
2446 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
2448 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
2451 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
2452 # if tool chain family doesn't match, skip it
2453 if Tool
in self
.ToolDefinition
and Family
!= "":
2454 FamilyIsNull
= False
2455 if self
.ToolDefinition
[Tool
].get(TAB_TOD_DEFINES_BUILDRULEFAMILY
, "") != "":
2456 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_BUILDRULEFAMILY
]:
2458 elif Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
2461 # expand any wildcard
2462 if Target
== "*" or Target
== self
.BuildTarget
:
2463 if Tag
== "*" or Tag
== self
.ToolChain
:
2464 if Arch
== "*" or Arch
== self
.Arch
:
2465 if Tool
not in BuildOptions
:
2466 BuildOptions
[Tool
] = {}
2467 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or Options
[Key
].startswith('='):
2468 BuildOptions
[Tool
][Attr
] = Options
[Key
]
2470 # append options for the same tool except PATH
2472 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
2474 BuildOptions
[Tool
][Attr
] = Options
[Key
]
2475 # Build Option Family has been checked, which need't to be checked again for family.
2476 if FamilyMatch
or FamilyIsNull
:
2480 if ModuleStyle
!= None and len (Key
) > 2:
2481 # Check Module style is EDK or EDKII.
2482 # Only append build option for the matched style module.
2483 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
2485 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
2488 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
2489 # if tool chain family doesn't match, skip it
2490 if Tool
not in self
.ToolDefinition
or Family
== "":
2492 # option has been added before
2493 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
2496 # expand any wildcard
2497 if Target
== "*" or Target
== self
.BuildTarget
:
2498 if Tag
== "*" or Tag
== self
.ToolChain
:
2499 if Arch
== "*" or Arch
== self
.Arch
:
2500 if Tool
not in BuildOptions
:
2501 BuildOptions
[Tool
] = {}
2502 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
] or Options
[Key
].startswith('='):
2503 BuildOptions
[Tool
][Attr
] = Options
[Key
]
2505 # append options for the same tool except PATH
2507 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
2509 BuildOptions
[Tool
][Attr
] = Options
[Key
]
2512 ## Append build options in platform to a module
2514 # @param Module The module to which the build options will be appened
2516 # @retval options The options appended with build options in platform
2518 def ApplyBuildOption(self
, Module
):
2519 # Get the different options for the different style module
2520 if Module
.AutoGenVersion
< 0x00010005:
2521 PlatformOptions
= self
.EdkBuildOption
2522 ModuleTypeOptions
= self
.Platform
.GetBuildOptionsByModuleType(EDK_NAME
, Module
.ModuleType
)
2524 PlatformOptions
= self
.EdkIIBuildOption
2525 ModuleTypeOptions
= self
.Platform
.GetBuildOptionsByModuleType(EDKII_NAME
, Module
.ModuleType
)
2526 ModuleTypeOptions
= self
._ExpandBuildOption
(ModuleTypeOptions
)
2527 ModuleOptions
= self
._ExpandBuildOption
(Module
.BuildOptions
)
2528 if Module
in self
.Platform
.Modules
:
2529 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
2530 PlatformModuleOptions
= self
._ExpandBuildOption
(PlatformModule
.BuildOptions
)
2532 PlatformModuleOptions
= {}
2534 BuildRuleOrder
= None
2535 for Options
in [self
.ToolDefinition
, ModuleOptions
, PlatformOptions
, ModuleTypeOptions
, PlatformModuleOptions
]:
2536 for Tool
in Options
:
2537 for Attr
in Options
[Tool
]:
2538 if Attr
== TAB_TOD_DEFINES_BUILDRULEORDER
:
2539 BuildRuleOrder
= Options
[Tool
][Attr
]
2541 AllTools
= set(ModuleOptions
.keys() + PlatformOptions
.keys() +
2542 PlatformModuleOptions
.keys() + ModuleTypeOptions
.keys() +
2543 self
.ToolDefinition
.keys())
2545 for Tool
in AllTools
:
2546 if Tool
not in BuildOptions
:
2547 BuildOptions
[Tool
] = {}
2549 for Options
in [self
.ToolDefinition
, ModuleOptions
, PlatformOptions
, ModuleTypeOptions
, PlatformModuleOptions
]:
2550 if Tool
not in Options
:
2552 for Attr
in Options
[Tool
]:
2553 Value
= Options
[Tool
][Attr
]
2555 # Do not generate it in Makefile
2557 if Attr
== TAB_TOD_DEFINES_BUILDRULEORDER
:
2559 if Attr
not in BuildOptions
[Tool
]:
2560 BuildOptions
[Tool
][Attr
] = ""
2561 # check if override is indicated
2562 if Value
.startswith('='):
2563 ToolPath
= Value
[1:]
2564 ToolPath
= mws
.handleWsMacro(ToolPath
)
2565 BuildOptions
[Tool
][Attr
] = ToolPath
2567 Value
= mws
.handleWsMacro(Value
)
2569 BuildOptions
[Tool
][Attr
] += " " + Value
2571 BuildOptions
[Tool
][Attr
] = Value
2572 if Module
.AutoGenVersion
< 0x00010005 and self
.Workspace
.UniFlag
!= None:
2574 # Override UNI flag only for EDK module.
2576 if 'BUILD' not in BuildOptions
:
2577 BuildOptions
['BUILD'] = {}
2578 BuildOptions
['BUILD']['FLAGS'] = self
.Workspace
.UniFlag
2579 return BuildOptions
, BuildRuleOrder
2581 Platform
= property(_GetPlatform
)
2582 Name
= property(_GetName
)
2583 Guid
= property(_GetGuid
)
2584 Version
= property(_GetVersion
)
2586 OutputDir
= property(_GetOutputDir
)
2587 BuildDir
= property(_GetBuildDir
)
2588 MakeFileDir
= property(_GetMakeFileDir
)
2589 FdfFile
= property(_GetFdfFile
)
2591 PcdTokenNumber
= property(_GetPcdTokenNumbers
) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
2592 DynamicPcdList
= property(_GetDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
2593 NonDynamicPcdList
= property(_GetNonDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
2594 NonDynamicPcdDict
= property(_GetNonDynamicPcdDict
)
2595 PackageList
= property(_GetPackageList
)
2597 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
2598 ToolDefinitionFile
= property(_GetToolDefFile
) # toolcode : lib path
2599 ToolChainFamily
= property(_GetToolChainFamily
)
2600 BuildRuleFamily
= property(_GetBuildRuleFamily
)
2601 BuildOption
= property(_GetBuildOptions
) # toolcode : option
2602 EdkBuildOption
= property(_GetEdkBuildOptions
) # edktoolcode : option
2603 EdkIIBuildOption
= property(_GetEdkIIBuildOptions
) # edkiitoolcode : option
2605 BuildCommand
= property(_GetBuildCommand
)
2606 BuildRule
= property(_GetBuildRule
)
2607 ModuleAutoGenList
= property(_GetModuleAutoGenList
)
2608 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
2609 GenFdsCommand
= property(_GenFdsCommand
)
2611 ## ModuleAutoGen class
2613 # This class encapsules the AutoGen behaviors for the build tools. In addition to
2614 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
2615 # to the [depex] section in module's inf file.
2617 class ModuleAutoGen(AutoGen
):
2618 ## Cache the timestamps of metafiles of every module in a class variable
2622 ## The real constructor of ModuleAutoGen
2624 # This method is not supposed to be called by users of ModuleAutoGen. It's
2625 # only used by factory method __new__() to do real initialization work for an
2626 # object of ModuleAutoGen
2628 # @param Workspace EdkIIWorkspaceBuild object
2629 # @param ModuleFile The path of module file
2630 # @param Target Build target (DEBUG, RELEASE)
2631 # @param Toolchain Name of tool chain
2632 # @param Arch The arch the module supports
2633 # @param PlatformFile Platform meta-file
2635 def _Init(self
, Workspace
, ModuleFile
, Target
, Toolchain
, Arch
, PlatformFile
):
2636 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen module [%s] [%s]" % (ModuleFile
, Arch
))
2637 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (ModuleFile
, Arch
, Toolchain
, Target
)
2639 self
.Workspace
= Workspace
2640 self
.WorkspaceDir
= Workspace
.WorkspaceDir
2642 self
.MetaFile
= ModuleFile
2643 self
.PlatformInfo
= PlatformAutoGen(Workspace
, PlatformFile
, Target
, Toolchain
, Arch
)
2644 # check if this module is employed by active platform
2645 if not self
.PlatformInfo
.ValidModule(self
.MetaFile
):
2646 EdkLogger
.verbose("Module [%s] for [%s] is not employed by active platform\n" \
2647 % (self
.MetaFile
, Arch
))
2650 self
.SourceDir
= self
.MetaFile
.SubDir
2651 self
.SourceDir
= mws
.relpath(self
.SourceDir
, self
.WorkspaceDir
)
2653 self
.SourceOverrideDir
= None
2654 # use overrided path defined in DSC file
2655 if self
.MetaFile
.Key
in GlobalData
.gOverrideDir
:
2656 self
.SourceOverrideDir
= GlobalData
.gOverrideDir
[self
.MetaFile
.Key
]
2658 self
.ToolChain
= Toolchain
2659 self
.BuildTarget
= Target
2661 self
.ToolChainFamily
= self
.PlatformInfo
.ToolChainFamily
2662 self
.BuildRuleFamily
= self
.PlatformInfo
.BuildRuleFamily
2664 self
.IsMakeFileCreated
= False
2665 self
.IsCodeFileCreated
= False
2666 self
.IsAsBuiltInfCreated
= False
2667 self
.DepexGenerated
= False
2669 self
.BuildDatabase
= self
.Workspace
.BuildDatabase
2670 self
.BuildRuleOrder
= None
2675 self
._Version
= None
2676 self
._ModuleType
= None
2677 self
._ComponentType
= None
2678 self
._PcdIsDriver
= None
2679 self
._AutoGenVersion
= None
2680 self
._LibraryFlag
= None
2681 self
._CustomMakefile
= None
2684 self
._BuildDir
= None
2685 self
._OutputDir
= None
2686 self
._DebugDir
= None
2687 self
._MakeFileDir
= None
2689 self
._IncludePathList
= None
2690 self
._IncludePathLength
= 0
2691 self
._AutoGenFileList
= None
2692 self
._UnicodeFileList
= None
2693 self
._VfrFileList
= None
2694 self
._IdfFileList
= None
2695 self
._SourceFileList
= None
2696 self
._ObjectFileList
= None
2697 self
._BinaryFileList
= None
2699 self
._DependentPackageList
= None
2700 self
._DependentLibraryList
= None
2701 self
._LibraryAutoGenList
= None
2702 self
._DerivedPackageList
= None
2703 self
._ModulePcdList
= None
2704 self
._LibraryPcdList
= None
2705 self
._PcdComments
= sdict()
2706 self
._GuidList
= None
2707 self
._GuidsUsedByPcd
= None
2708 self
._GuidComments
= sdict()
2709 self
._ProtocolList
= None
2710 self
._ProtocolComments
= sdict()
2711 self
._PpiList
= None
2712 self
._PpiComments
= sdict()
2713 self
._DepexList
= None
2714 self
._DepexExpressionList
= None
2715 self
._BuildOption
= None
2716 self
._BuildOptionIncPathList
= None
2717 self
._BuildTargets
= None
2718 self
._IntroBuildTargetList
= None
2719 self
._FinalBuildTargetList
= None
2720 self
._FileTypes
= None
2721 self
._BuildRules
= None
2723 self
._TimeStampPath
= None
2725 self
.AutoGenDepSet
= set()
2728 ## The Modules referenced to this Library
2729 # Only Library has this attribute
2730 self
._ReferenceModules
= []
2732 ## Store the FixedAtBuild Pcds
2734 self
._FixedAtBuildPcds
= []
2739 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
2741 # Get FixedAtBuild Pcds of this Module
2742 def _GetFixedAtBuildPcds(self
):
2743 if self
._FixedAtBuildPcds
:
2744 return self
._FixedAtBuildPcds
2745 for Pcd
in self
.ModulePcdList
:
2747 if not (Pcd
.Pending
== False and Pcd
.Type
== "FixedAtBuild"):
2749 elif Pcd
.Type
!= "FixedAtBuild":
2751 if Pcd
not in self
._FixedAtBuildPcds
:
2752 self
._FixedAtBuildPcds
.append(Pcd
)
2754 return self
._FixedAtBuildPcds
2756 def _GetUniqueBaseName(self
):
2757 BaseName
= self
.Name
2758 for Module
in self
.PlatformInfo
.ModuleAutoGenList
:
2759 if Module
.MetaFile
== self
.MetaFile
:
2761 if Module
.Name
== self
.Name
:
2762 if uuid
.UUID(Module
.Guid
) == uuid
.UUID(self
.Guid
):
2763 EdkLogger
.error("build", FILE_DUPLICATED
, 'Modules have same BaseName and FILE_GUID:\n'
2764 ' %s\n %s' % (Module
.MetaFile
, self
.MetaFile
))
2765 BaseName
= '%s_%s' % (self
.Name
, self
.Guid
)
2768 # Macros could be used in build_rule.txt (also Makefile)
2769 def _GetMacros(self
):
2770 if self
._Macro
== None:
2771 self
._Macro
= sdict()
2772 self
._Macro
["WORKSPACE" ] = self
.WorkspaceDir
2773 self
._Macro
["MODULE_NAME" ] = self
.Name
2774 self
._Macro
["MODULE_NAME_GUID" ] = self
._GetUniqueBaseName
()
2775 self
._Macro
["MODULE_GUID" ] = self
.Guid
2776 self
._Macro
["MODULE_VERSION" ] = self
.Version
2777 self
._Macro
["MODULE_TYPE" ] = self
.ModuleType
2778 self
._Macro
["MODULE_FILE" ] = str(self
.MetaFile
)
2779 self
._Macro
["MODULE_FILE_BASE_NAME" ] = self
.MetaFile
.BaseName
2780 self
._Macro
["MODULE_RELATIVE_DIR" ] = self
.SourceDir
2781 self
._Macro
["MODULE_DIR" ] = self
.SourceDir
2783 self
._Macro
["BASE_NAME" ] = self
.Name
2785 self
._Macro
["ARCH" ] = self
.Arch
2786 self
._Macro
["TOOLCHAIN" ] = self
.ToolChain
2787 self
._Macro
["TOOLCHAIN_TAG" ] = self
.ToolChain
2788 self
._Macro
["TOOL_CHAIN_TAG" ] = self
.ToolChain
2789 self
._Macro
["TARGET" ] = self
.BuildTarget
2791 self
._Macro
["BUILD_DIR" ] = self
.PlatformInfo
.BuildDir
2792 self
._Macro
["BIN_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
2793 self
._Macro
["LIB_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
2794 self
._Macro
["MODULE_BUILD_DIR" ] = self
.BuildDir
2795 self
._Macro
["OUTPUT_DIR" ] = self
.OutputDir
2796 self
._Macro
["DEBUG_DIR" ] = self
.DebugDir
2797 self
._Macro
["DEST_DIR_OUTPUT" ] = self
.OutputDir
2798 self
._Macro
["DEST_DIR_DEBUG" ] = self
.DebugDir
2799 self
._Macro
["PLATFORM_NAME" ] = self
.PlatformInfo
.Name
2800 self
._Macro
["PLATFORM_GUID" ] = self
.PlatformInfo
.Guid
2801 self
._Macro
["PLATFORM_VERSION" ] = self
.PlatformInfo
.Version
2802 self
._Macro
["PLATFORM_RELATIVE_DIR" ] = self
.PlatformInfo
.SourceDir
2803 self
._Macro
["PLATFORM_DIR" ] = mws
.join(self
.WorkspaceDir
, self
.PlatformInfo
.SourceDir
)
2804 self
._Macro
["PLATFORM_OUTPUT_DIR" ] = self
.PlatformInfo
.OutputDir
2807 ## Return the module build data object
2808 def _GetModule(self
):
2809 if self
._Module
== None:
2810 self
._Module
= self
.Workspace
.BuildDatabase
[self
.MetaFile
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
2813 ## Return the module name
2814 def _GetBaseName(self
):
2815 return self
.Module
.BaseName
2817 ## Return the module DxsFile if exist
2818 def _GetDxsFile(self
):
2819 return self
.Module
.DxsFile
2821 ## Return the module SourceOverridePath
2822 def _GetSourceOverridePath(self
):
2823 return self
.Module
.SourceOverridePath
2825 ## Return the module meta-file GUID
2828 # To build same module more than once, the module path with FILE_GUID overridden has
2829 # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the realy path
2830 # in DSC. The overridden GUID can be retrieved from file name
2832 if os
.path
.basename(self
.MetaFile
.File
) != os
.path
.basename(self
.MetaFile
.Path
):
2834 # Length of GUID is 36
2836 return os
.path
.basename(self
.MetaFile
.Path
)[:36]
2837 return self
.Module
.Guid
2839 ## Return the module version
2840 def _GetVersion(self
):
2841 return self
.Module
.Version
2843 ## Return the module type
2844 def _GetModuleType(self
):
2845 return self
.Module
.ModuleType
2847 ## Return the component type (for Edk.x style of module)
2848 def _GetComponentType(self
):
2849 return self
.Module
.ComponentType
2851 ## Return the build type
2852 def _GetBuildType(self
):
2853 return self
.Module
.BuildType
2855 ## Return the PCD_IS_DRIVER setting
2856 def _GetPcdIsDriver(self
):
2857 return self
.Module
.PcdIsDriver
2859 ## Return the autogen version, i.e. module meta-file version
2860 def _GetAutoGenVersion(self
):
2861 return self
.Module
.AutoGenVersion
2863 ## Check if the module is library or not
2864 def _IsLibrary(self
):
2865 if self
._LibraryFlag
== None:
2866 if self
.Module
.LibraryClass
!= None and self
.Module
.LibraryClass
!= []:
2867 self
._LibraryFlag
= True
2869 self
._LibraryFlag
= False
2870 return self
._LibraryFlag
2872 ## Check if the module is binary module or not
2873 def _IsBinaryModule(self
):
2874 return self
.Module
.IsBinaryModule
2876 ## Return the directory to store intermediate files of the module
2877 def _GetBuildDir(self
):
2878 if self
._BuildDir
== None:
2879 self
._BuildDir
= path
.join(
2880 self
.PlatformInfo
.BuildDir
,
2883 self
.MetaFile
.BaseName
2885 CreateDirectory(self
._BuildDir
)
2886 return self
._BuildDir
2888 ## Return the directory to store the intermediate object files of the mdoule
2889 def _GetOutputDir(self
):
2890 if self
._OutputDir
== None:
2891 self
._OutputDir
= path
.join(self
.BuildDir
, "OUTPUT")
2892 CreateDirectory(self
._OutputDir
)
2893 return self
._OutputDir
2895 ## Return the directory to store auto-gened source files of the mdoule
2896 def _GetDebugDir(self
):
2897 if self
._DebugDir
== None:
2898 self
._DebugDir
= path
.join(self
.BuildDir
, "DEBUG")
2899 CreateDirectory(self
._DebugDir
)
2900 return self
._DebugDir
2902 ## Return the path of custom file
2903 def _GetCustomMakefile(self
):
2904 if self
._CustomMakefile
== None:
2905 self
._CustomMakefile
= {}
2906 for Type
in self
.Module
.CustomMakefile
:
2907 if Type
in gMakeTypeMap
:
2908 MakeType
= gMakeTypeMap
[Type
]
2911 if self
.SourceOverrideDir
!= None:
2912 File
= os
.path
.join(self
.SourceOverrideDir
, self
.Module
.CustomMakefile
[Type
])
2913 if not os
.path
.exists(File
):
2914 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
2916 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
2917 self
._CustomMakefile
[MakeType
] = File
2918 return self
._CustomMakefile
2920 ## Return the directory of the makefile
2922 # @retval string The directory string of module's makefile
2924 def _GetMakeFileDir(self
):
2925 return self
.BuildDir
2927 ## Return build command string
2929 # @retval string Build command string
2931 def _GetBuildCommand(self
):
2932 return self
.PlatformInfo
.BuildCommand
2934 ## Get object list of all packages the module and its dependent libraries belong to
2936 # @retval list The list of package object
2938 def _GetDerivedPackageList(self
):
2940 for M
in [self
.Module
] + self
.DependentLibraryList
:
2941 for Package
in M
.Packages
:
2942 if Package
in PackageList
:
2944 PackageList
.append(Package
)
2947 ## Get the depex string
2949 # @return : a string contain all depex expresion.
2950 def _GetDepexExpresionString(self
):
2953 ## DPX_SOURCE IN Define section.
2954 if self
.Module
.DxsFile
:
2956 for M
in [self
.Module
] + self
.DependentLibraryList
:
2957 Filename
= M
.MetaFile
.Path
2958 InfObj
= InfSectionParser
.InfSectionParser(Filename
)
2959 DepexExpresionList
= InfObj
.GetDepexExpresionList()
2960 for DepexExpresion
in DepexExpresionList
:
2961 for key
in DepexExpresion
.keys():
2962 Arch
, ModuleType
= key
2963 DepexExpr
= [x
for x
in DepexExpresion
[key
] if not str(x
).startswith('#')]
2964 # the type of build module is USER_DEFINED.
2965 # All different DEPEX section tags would be copied into the As Built INF file
2966 # and there would be separate DEPEX section tags
2967 if self
.ModuleType
.upper() == SUP_MODULE_USER_DEFINED
:
2968 if (Arch
.upper() == self
.Arch
.upper()) and (ModuleType
.upper() != TAB_ARCH_COMMON
):
2969 DepexList
.append({(Arch
, ModuleType
): DepexExpr
})
2971 if Arch
.upper() == TAB_ARCH_COMMON
or \
2972 (Arch
.upper() == self
.Arch
.upper() and \
2973 ModuleType
.upper() in [TAB_ARCH_COMMON
, self
.ModuleType
.upper()]):
2974 DepexList
.append({(Arch
, ModuleType
): DepexExpr
})
2976 #the type of build module is USER_DEFINED.
2977 if self
.ModuleType
.upper() == SUP_MODULE_USER_DEFINED
:
2978 for Depex
in DepexList
:
2979 for key
in Depex
.keys():
2980 DepexStr
+= '[Depex.%s.%s]\n' % key
2981 DepexStr
+= '\n'.join(['# '+ val
for val
in Depex
[key
]])
2984 return '[Depex.%s]\n' % self
.Arch
2987 #the type of build module not is USER_DEFINED.
2989 for Depex
in DepexList
:
2994 for D
in Depex
.values():
2995 DepexStr
+= ' '.join([val
for val
in D
])
2996 Index
= DepexStr
.find('END')
2997 if Index
> -1 and Index
== len(DepexStr
) - 3:
2998 DepexStr
= DepexStr
[:-3]
2999 DepexStr
= DepexStr
.strip()
3002 DepexStr
= DepexStr
.lstrip('(').rstrip(')').strip()
3004 return '[Depex.%s]\n' % self
.Arch
3005 return '[Depex.%s]\n# ' % self
.Arch
+ DepexStr
3007 ## Merge dependency expression
3009 # @retval list The token list of the dependency expression after parsed
3011 def _GetDepexTokenList(self
):
3012 if self
._DepexList
== None:
3013 self
._DepexList
= {}
3014 if self
.DxsFile
or self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
3015 return self
._DepexList
3017 self
._DepexList
[self
.ModuleType
] = []
3019 for ModuleType
in self
._DepexList
:
3020 DepexList
= self
._DepexList
[ModuleType
]
3022 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
3024 for M
in [self
.Module
] + self
.DependentLibraryList
:
3026 for D
in M
.Depex
[self
.Arch
, ModuleType
]:
3028 DepexList
.append('AND')
3029 DepexList
.append('(')
3031 if DepexList
[-1] == 'END': # no need of a END at this time
3033 DepexList
.append(')')
3036 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexList
))
3037 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
3039 if len(DepexList
) > 0:
3040 EdkLogger
.verbose('')
3041 return self
._DepexList
3043 ## Merge dependency expression
3045 # @retval list The token list of the dependency expression after parsed
3047 def _GetDepexExpressionTokenList(self
):
3048 if self
._DepexExpressionList
== None:
3049 self
._DepexExpressionList
= {}
3050 if self
.DxsFile
or self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
3051 return self
._DepexExpressionList
3053 self
._DepexExpressionList
[self
.ModuleType
] = ''
3055 for ModuleType
in self
._DepexExpressionList
:
3056 DepexExpressionList
= self
._DepexExpressionList
[ModuleType
]
3058 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
3060 for M
in [self
.Module
] + self
.DependentLibraryList
:
3062 for D
in M
.DepexExpression
[self
.Arch
, ModuleType
]:
3063 if DepexExpressionList
!= '':
3064 DepexExpressionList
+= ' AND '
3065 DepexExpressionList
+= '('
3066 DepexExpressionList
+= D
3067 DepexExpressionList
= DepexExpressionList
.rstrip('END').strip()
3068 DepexExpressionList
+= ')'
3071 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexExpressionList
))
3072 if 'BEFORE' in DepexExpressionList
or 'AFTER' in DepexExpressionList
:
3074 if len(DepexExpressionList
) > 0:
3075 EdkLogger
.verbose('')
3076 self
._DepexExpressionList
[ModuleType
] = DepexExpressionList
3077 return self
._DepexExpressionList
3079 ## Return the list of specification version required for the module
3081 # @retval list The list of specification defined in module file
3083 def _GetSpecification(self
):
3084 return self
.Module
.Specification
3086 ## Tool option for the module build
3088 # @param PlatformInfo The object of PlatformBuildInfo
3089 # @retval dict The dict containing valid options
3091 def _GetModuleBuildOption(self
):
3092 if self
._BuildOption
== None:
3093 self
._BuildOption
, self
.BuildRuleOrder
= self
.PlatformInfo
.ApplyBuildOption(self
.Module
)
3094 if self
.BuildRuleOrder
:
3095 self
.BuildRuleOrder
= ['.%s' % Ext
for Ext
in self
.BuildRuleOrder
.split()]
3096 return self
._BuildOption
3098 ## Get include path list from tool option for the module build
3100 # @retval list The include path list
3102 def _GetBuildOptionIncPathList(self
):
3103 if self
._BuildOptionIncPathList
== None:
3105 # Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT
3106 # is the former use /I , the Latter used -I to specify include directories
3108 if self
.PlatformInfo
.ToolChainFamily
in ('MSFT'):
3109 gBuildOptIncludePattern
= re
.compile(r
"(?:.*?)/I[ \t]*([^ ]*)", re
.MULTILINE | re
.DOTALL
)
3110 elif self
.PlatformInfo
.ToolChainFamily
in ('INTEL', 'GCC', 'RVCT'):
3111 gBuildOptIncludePattern
= re
.compile(r
"(?:.*?)-I[ \t]*([^ ]*)", re
.MULTILINE | re
.DOTALL
)
3114 # New ToolChainFamily, don't known whether there is option to specify include directories
3116 self
._BuildOptionIncPathList
= []
3117 return self
._BuildOptionIncPathList
3119 BuildOptionIncPathList
= []
3120 for Tool
in ('CC', 'PP', 'VFRPP', 'ASLPP', 'ASLCC', 'APP', 'ASM'):
3123 FlagOption
= self
.BuildOption
[Tool
][Attr
]
3127 if self
.PlatformInfo
.ToolChainFamily
!= 'RVCT':
3128 IncPathList
= [NormPath(Path
, self
.Macros
) for Path
in gBuildOptIncludePattern
.findall(FlagOption
)]
3131 # RVCT may specify a list of directory seperated by commas
3134 for Path
in gBuildOptIncludePattern
.findall(FlagOption
):
3135 PathList
= GetSplitList(Path
, TAB_COMMA_SPLIT
)
3136 IncPathList
+= [NormPath(PathEntry
, self
.Macros
) for PathEntry
in PathList
]
3139 # EDK II modules must not reference header files outside of the packages they depend on or
3140 # within the module's directory tree. Report error if violation.
3142 if self
.AutoGenVersion
>= 0x00010005 and len(IncPathList
) > 0:
3143 for Path
in IncPathList
:
3144 if (Path
not in self
.IncludePathList
) and (CommonPath([Path
, self
.MetaFile
.Dir
]) != self
.MetaFile
.Dir
):
3145 ErrMsg
= "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path
, Tool
, FlagOption
)
3146 EdkLogger
.error("build",
3149 File
=str(self
.MetaFile
))
3152 BuildOptionIncPathList
+= IncPathList
3154 self
._BuildOptionIncPathList
= BuildOptionIncPathList
3156 return self
._BuildOptionIncPathList
3158 ## Return a list of files which can be built from source
3160 # What kind of files can be built is determined by build rules in
3161 # $(CONF_DIRECTORY)/build_rule.txt and toolchain family.
3163 def _GetSourceFileList(self
):
3164 if self
._SourceFileList
== None:
3165 self
._SourceFileList
= []
3166 for F
in self
.Module
.Sources
:
3168 if F
.TagName
not in ("", "*", self
.ToolChain
):
3169 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "The toolchain [%s] for processing file [%s] is found, "
3170 "but [%s] is needed" % (F
.TagName
, str(F
), self
.ToolChain
))
3172 # match tool chain family
3173 if F
.ToolChainFamily
not in ("", "*", self
.ToolChainFamily
):
3176 "The file [%s] must be built by tools of [%s], " \
3177 "but current toolchain family is [%s]" \
3178 % (str(F
), F
.ToolChainFamily
, self
.ToolChainFamily
))
3181 # add the file path into search path list for file including
3182 if F
.Dir
not in self
.IncludePathList
and self
.AutoGenVersion
>= 0x00010005:
3183 self
.IncludePathList
.insert(0, F
.Dir
)
3184 self
._SourceFileList
.append(F
)
3186 self
._MatchBuildRuleOrder
(self
._SourceFileList
)
3188 for F
in self
._SourceFileList
:
3189 self
._ApplyBuildRule
(F
, TAB_UNKNOWN_FILE
)
3190 return self
._SourceFileList
3192 def _MatchBuildRuleOrder(self
, FileList
):
3194 self
._GetModuleBuildOption
()
3195 for SingleFile
in FileList
:
3196 if self
.BuildRuleOrder
and SingleFile
.Ext
in self
.BuildRuleOrder
and SingleFile
.Ext
in self
.BuildRules
:
3197 key
= SingleFile
.Path
.split(SingleFile
.Ext
)[0]
3198 if key
in Order_Dict
:
3199 Order_Dict
[key
].append(SingleFile
.Ext
)
3201 Order_Dict
[key
] = [SingleFile
.Ext
]
3204 for F
in Order_Dict
:
3205 if len(Order_Dict
[F
]) > 1:
3206 Order_Dict
[F
].sort(key
=lambda i
: self
.BuildRuleOrder
.index(i
))
3207 for Ext
in Order_Dict
[F
][1:]:
3208 RemoveList
.append(F
+ Ext
)
3210 for item
in RemoveList
:
3211 FileList
.remove(item
)
3215 ## Return the list of unicode files
3216 def _GetUnicodeFileList(self
):
3217 if self
._UnicodeFileList
== None:
3218 if TAB_UNICODE_FILE
in self
.FileTypes
:
3219 self
._UnicodeFileList
= self
.FileTypes
[TAB_UNICODE_FILE
]
3221 self
._UnicodeFileList
= []
3222 return self
._UnicodeFileList
3224 ## Return the list of vfr files
3225 def _GetVfrFileList(self
):
3226 if self
._VfrFileList
== None:
3227 if TAB_VFR_FILE
in self
.FileTypes
:
3228 self
._VfrFileList
= self
.FileTypes
[TAB_VFR_FILE
]
3230 self
._VfrFileList
= []
3231 return self
._VfrFileList
3233 ## Return the list of Image Definition files
3234 def _GetIdfFileList(self
):
3235 if self
._IdfFileList
== None:
3236 if TAB_IMAGE_FILE
in self
.FileTypes
:
3237 self
._IdfFileList
= self
.FileTypes
[TAB_IMAGE_FILE
]
3239 self
._IdfFileList
= []
3240 return self
._IdfFileList
3242 ## Return a list of files which can be built from binary
3244 # "Build" binary files are just to copy them to build directory.
3246 # @retval list The list of files which can be built later
3248 def _GetBinaryFiles(self
):
3249 if self
._BinaryFileList
== None:
3250 self
._BinaryFileList
= []
3251 for F
in self
.Module
.Binaries
:
3252 if F
.Target
not in ['COMMON', '*'] and F
.Target
!= self
.BuildTarget
:
3254 self
._BinaryFileList
.append(F
)
3255 self
._ApplyBuildRule
(F
, F
.Type
)
3256 return self
._BinaryFileList
3258 def _GetBuildRules(self
):
3259 if self
._BuildRules
== None:
3261 BuildRuleDatabase
= self
.PlatformInfo
.BuildRule
3262 for Type
in BuildRuleDatabase
.FileTypeList
:
3263 #first try getting build rule by BuildRuleFamily
3264 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.BuildRuleFamily
]
3266 # build type is always module type, but ...
3267 if self
.ModuleType
!= self
.BuildType
:
3268 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.BuildRuleFamily
]
3269 #second try getting build rule by ToolChainFamily
3271 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.ToolChainFamily
]
3273 # build type is always module type, but ...
3274 if self
.ModuleType
!= self
.BuildType
:
3275 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.ToolChainFamily
]
3278 RuleObject
= RuleObject
.Instantiate(self
.Macros
)
3279 BuildRules
[Type
] = RuleObject
3280 for Ext
in RuleObject
.SourceFileExtList
:
3281 BuildRules
[Ext
] = RuleObject
3282 self
._BuildRules
= BuildRules
3283 return self
._BuildRules
3285 def _ApplyBuildRule(self
, File
, FileType
):
3286 if self
._BuildTargets
== None:
3287 self
._IntroBuildTargetList
= set()
3288 self
._FinalBuildTargetList
= set()
3289 self
._BuildTargets
= {}
3290 self
._FileTypes
= {}
3292 SubDirectory
= os
.path
.join(self
.OutputDir
, File
.SubDir
)
3293 if not os
.path
.exists(SubDirectory
):
3294 CreateDirectory(SubDirectory
)
3300 # Make sure to get build rule order value
3302 self
._GetModuleBuildOption
()
3304 while Index
< len(SourceList
):
3305 Source
= SourceList
[Index
]
3309 CreateDirectory(Source
.Dir
)
3311 if File
.IsBinary
and File
== Source
and self
._BinaryFileList
!= None and File
in self
._BinaryFileList
:
3312 # Skip all files that are not binary libraries
3313 if not self
.IsLibrary
:
3315 RuleObject
= self
.BuildRules
[TAB_DEFAULT_BINARY_FILE
]
3316 elif FileType
in self
.BuildRules
:
3317 RuleObject
= self
.BuildRules
[FileType
]
3318 elif Source
.Ext
in self
.BuildRules
:
3319 RuleObject
= self
.BuildRules
[Source
.Ext
]
3321 # stop at no more rules
3323 self
._FinalBuildTargetList
.add(LastTarget
)
3326 FileType
= RuleObject
.SourceFileType
3327 if FileType
not in self
._FileTypes
:
3328 self
._FileTypes
[FileType
] = set()
3329 self
._FileTypes
[FileType
].add(Source
)
3331 # stop at STATIC_LIBRARY for library
3332 if self
.IsLibrary
and FileType
== TAB_STATIC_LIBRARY
:
3334 self
._FinalBuildTargetList
.add(LastTarget
)
3337 Target
= RuleObject
.Apply(Source
, self
.BuildRuleOrder
)
3340 self
._FinalBuildTargetList
.add(LastTarget
)
3342 elif not Target
.Outputs
:
3343 # Only do build for target with outputs
3344 self
._FinalBuildTargetList
.add(Target
)
3346 if FileType
not in self
._BuildTargets
:
3347 self
._BuildTargets
[FileType
] = set()
3348 self
._BuildTargets
[FileType
].add(Target
)
3350 if not Source
.IsBinary
and Source
== File
:
3351 self
._IntroBuildTargetList
.add(Target
)
3353 # to avoid cyclic rule
3354 if FileType
in RuleChain
:
3357 RuleChain
.append(FileType
)
3358 SourceList
.extend(Target
.Outputs
)
3360 FileType
= TAB_UNKNOWN_FILE
3362 def _GetTargets(self
):
3363 if self
._BuildTargets
== None:
3364 self
._IntroBuildTargetList
= set()
3365 self
._FinalBuildTargetList
= set()
3366 self
._BuildTargets
= {}
3367 self
._FileTypes
= {}
3369 #TRICK: call _GetSourceFileList to apply build rule for source files
3370 if self
.SourceFileList
:
3373 #TRICK: call _GetBinaryFileList to apply build rule for binary files
3374 if self
.BinaryFileList
:
3377 return self
._BuildTargets
3379 def _GetIntroTargetList(self
):
3381 return self
._IntroBuildTargetList
3383 def _GetFinalTargetList(self
):
3385 return self
._FinalBuildTargetList
3387 def _GetFileTypes(self
):
3389 return self
._FileTypes
3391 ## Get the list of package object the module depends on
3393 # @retval list The package object list
3395 def _GetDependentPackageList(self
):
3396 return self
.Module
.Packages
3398 ## Return the list of auto-generated code file
3400 # @retval list The list of auto-generated file
3402 def _GetAutoGenFileList(self
):
3403 UniStringAutoGenC
= True
3404 IdfStringAutoGenC
= True
3405 UniStringBinBuffer
= StringIO()
3406 IdfGenBinBuffer
= StringIO()
3407 if self
.BuildType
== 'UEFI_HII':
3408 UniStringAutoGenC
= False
3409 IdfStringAutoGenC
= False
3410 if self
._AutoGenFileList
== None:
3411 self
._AutoGenFileList
= {}
3412 AutoGenC
= TemplateString()
3413 AutoGenH
= TemplateString()
3414 StringH
= TemplateString()
3415 StringIdf
= TemplateString()
3416 GenC
.CreateCode(self
, AutoGenC
, AutoGenH
, StringH
, UniStringAutoGenC
, UniStringBinBuffer
, StringIdf
, IdfStringAutoGenC
, IdfGenBinBuffer
)
3418 # AutoGen.c is generated if there are library classes in inf, or there are object files
3420 if str(AutoGenC
) != "" and (len(self
.Module
.LibraryClasses
) > 0
3421 or TAB_OBJECT_FILE
in self
.FileTypes
):
3422 AutoFile
= PathClass(gAutoGenCodeFileName
, self
.DebugDir
)
3423 self
._AutoGenFileList
[AutoFile
] = str(AutoGenC
)
3424 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3425 if str(AutoGenH
) != "":
3426 AutoFile
= PathClass(gAutoGenHeaderFileName
, self
.DebugDir
)
3427 self
._AutoGenFileList
[AutoFile
] = str(AutoGenH
)
3428 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3429 if str(StringH
) != "":
3430 AutoFile
= PathClass(gAutoGenStringFileName
% {"module_name":self
.Name
}, self
.DebugDir
)
3431 self
._AutoGenFileList
[AutoFile
] = str(StringH
)
3432 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3433 if UniStringBinBuffer
!= None and UniStringBinBuffer
.getvalue() != "":
3434 AutoFile
= PathClass(gAutoGenStringFormFileName
% {"module_name":self
.Name
}, self
.OutputDir
)
3435 self
._AutoGenFileList
[AutoFile
] = UniStringBinBuffer
.getvalue()
3436 AutoFile
.IsBinary
= True
3437 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3438 if UniStringBinBuffer
!= None:
3439 UniStringBinBuffer
.close()
3440 if str(StringIdf
) != "":
3441 AutoFile
= PathClass(gAutoGenImageDefFileName
% {"module_name":self
.Name
}, self
.DebugDir
)
3442 self
._AutoGenFileList
[AutoFile
] = str(StringIdf
)
3443 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3444 if IdfGenBinBuffer
!= None and IdfGenBinBuffer
.getvalue() != "":
3445 AutoFile
= PathClass(gAutoGenIdfFileName
% {"module_name":self
.Name
}, self
.OutputDir
)
3446 self
._AutoGenFileList
[AutoFile
] = IdfGenBinBuffer
.getvalue()
3447 AutoFile
.IsBinary
= True
3448 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
3449 if IdfGenBinBuffer
!= None:
3450 IdfGenBinBuffer
.close()
3451 return self
._AutoGenFileList
3453 ## Return the list of library modules explicitly or implicityly used by this module
3454 def _GetLibraryList(self
):
3455 if self
._DependentLibraryList
== None:
3456 # only merge library classes and PCD for non-library module
3458 self
._DependentLibraryList
= []
3460 if self
.AutoGenVersion
< 0x00010005:
3461 self
._DependentLibraryList
= self
.PlatformInfo
.ResolveLibraryReference(self
.Module
)
3463 self
._DependentLibraryList
= self
.PlatformInfo
.ApplyLibraryInstance(self
.Module
)
3464 return self
._DependentLibraryList
3467 def UpdateComments(Recver
, Src
):
3469 if Key
not in Recver
:
3471 Recver
[Key
].extend(Src
[Key
])
3472 ## Get the list of PCDs from current module
3474 # @retval list The list of PCD
3476 def _GetModulePcdList(self
):
3477 if self
._ModulePcdList
== None:
3478 # apply PCD settings from platform
3479 self
._ModulePcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, self
.Module
.Pcds
)
3480 self
.UpdateComments(self
._PcdComments
, self
.Module
.PcdComments
)
3481 return self
._ModulePcdList
3483 ## Get the list of PCDs from dependent libraries
3485 # @retval list The list of PCD
3487 def _GetLibraryPcdList(self
):
3488 if self
._LibraryPcdList
== None:
3490 if not self
.IsLibrary
:
3491 # get PCDs from dependent libraries
3492 for Library
in self
.DependentLibraryList
:
3493 self
.UpdateComments(self
._PcdComments
, Library
.PcdComments
)
3494 for Key
in Library
.Pcds
:
3495 # skip duplicated PCDs
3496 if Key
in self
.Module
.Pcds
or Key
in Pcds
:
3498 Pcds
[Key
] = copy
.copy(Library
.Pcds
[Key
])
3499 # apply PCD settings from platform
3500 self
._LibraryPcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, Pcds
)
3502 self
._LibraryPcdList
= []
3503 return self
._LibraryPcdList
3505 ## Get the GUID value mapping
3507 # @retval dict The mapping between GUID cname and its value
3509 def _GetGuidList(self
):
3510 if self
._GuidList
== None:
3511 self
._GuidList
= sdict()
3512 self
._GuidList
.update(self
.Module
.Guids
)
3513 for Library
in self
.DependentLibraryList
:
3514 self
._GuidList
.update(Library
.Guids
)
3515 self
.UpdateComments(self
._GuidComments
, Library
.GuidComments
)
3516 self
.UpdateComments(self
._GuidComments
, self
.Module
.GuidComments
)
3517 return self
._GuidList
3519 def GetGuidsUsedByPcd(self
):
3520 if self
._GuidsUsedByPcd
== None:
3521 self
._GuidsUsedByPcd
= sdict()
3522 self
._GuidsUsedByPcd
.update(self
.Module
.GetGuidsUsedByPcd())
3523 for Library
in self
.DependentLibraryList
:
3524 self
._GuidsUsedByPcd
.update(Library
.GetGuidsUsedByPcd())
3525 return self
._GuidsUsedByPcd
3526 ## Get the protocol value mapping
3528 # @retval dict The mapping between protocol cname and its value
3530 def _GetProtocolList(self
):
3531 if self
._ProtocolList
== None:
3532 self
._ProtocolList
= sdict()
3533 self
._ProtocolList
.update(self
.Module
.Protocols
)
3534 for Library
in self
.DependentLibraryList
:
3535 self
._ProtocolList
.update(Library
.Protocols
)
3536 self
.UpdateComments(self
._ProtocolComments
, Library
.ProtocolComments
)
3537 self
.UpdateComments(self
._ProtocolComments
, self
.Module
.ProtocolComments
)
3538 return self
._ProtocolList
3540 ## Get the PPI value mapping
3542 # @retval dict The mapping between PPI cname and its value
3544 def _GetPpiList(self
):
3545 if self
._PpiList
== None:
3546 self
._PpiList
= sdict()
3547 self
._PpiList
.update(self
.Module
.Ppis
)
3548 for Library
in self
.DependentLibraryList
:
3549 self
._PpiList
.update(Library
.Ppis
)
3550 self
.UpdateComments(self
._PpiComments
, Library
.PpiComments
)
3551 self
.UpdateComments(self
._PpiComments
, self
.Module
.PpiComments
)
3552 return self
._PpiList
3554 ## Get the list of include search path
3556 # @retval list The list path
3558 def _GetIncludePathList(self
):
3559 if self
._IncludePathList
== None:
3560 self
._IncludePathList
= []
3561 if self
.AutoGenVersion
< 0x00010005:
3562 for Inc
in self
.Module
.Includes
:
3563 if Inc
not in self
._IncludePathList
:
3564 self
._IncludePathList
.append(Inc
)
3566 Inc
= path
.join(Inc
, self
.Arch
.capitalize())
3567 if os
.path
.exists(Inc
) and Inc
not in self
._IncludePathList
:
3568 self
._IncludePathList
.append(Inc
)
3569 # Edk module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
3570 self
._IncludePathList
.append(self
.DebugDir
)
3572 self
._IncludePathList
.append(self
.MetaFile
.Dir
)
3573 self
._IncludePathList
.append(self
.DebugDir
)
3575 for Package
in self
.Module
.Packages
:
3576 PackageDir
= mws
.join(self
.WorkspaceDir
, Package
.MetaFile
.Dir
)
3577 if PackageDir
not in self
._IncludePathList
:
3578 self
._IncludePathList
.append(PackageDir
)
3579 IncludesList
= Package
.Includes
3580 if Package
._PrivateIncludes
:
3581 if not self
.MetaFile
.Path
.startswith(PackageDir
):
3582 IncludesList
= list(set(Package
.Includes
).difference(set(Package
._PrivateIncludes
)))
3583 for Inc
in IncludesList
:
3584 if Inc
not in self
._IncludePathList
:
3585 self
._IncludePathList
.append(str(Inc
))
3586 return self
._IncludePathList
3588 def _GetIncludePathLength(self
):
3589 self
._IncludePathLength
= 0
3590 if self
._IncludePathList
:
3591 for inc
in self
._IncludePathList
:
3592 self
._IncludePathLength
+= len(' ' + inc
)
3593 return self
._IncludePathLength
3595 ## Get HII EX PCDs which maybe used by VFR
3597 # efivarstore used by VFR may relate with HII EX PCDs
3598 # Get the variable name and GUID from efivarstore and HII EX PCD
3599 # List the HII EX PCDs in As Built INF if both name and GUID match.
3601 # @retval list HII EX PCDs
3603 def _GetPcdsMaybeUsedByVfr(self
):
3604 if not self
.SourceFileList
:
3608 for SrcFile
in self
.SourceFileList
:
3609 if SrcFile
.Ext
.lower() != '.vfr':
3611 Vfri
= os
.path
.join(self
.OutputDir
, SrcFile
.BaseName
+ '.i')
3612 if not os
.path
.exists(Vfri
):
3614 VfriFile
= open(Vfri
, 'r')
3615 Content
= VfriFile
.read()
3617 Pos
= Content
.find('efivarstore')
3620 # Make sure 'efivarstore' is the start of efivarstore statement
3621 # In case of the value of 'name' (name = efivarstore) is equal to 'efivarstore'
3624 while Index
>= 0 and Content
[Index
] in ' \t\r\n':
3626 if Index
>= 0 and Content
[Index
] != ';':
3627 Pos
= Content
.find('efivarstore', Pos
+ len('efivarstore'))
3630 # 'efivarstore' must be followed by name and guid
3632 Name
= gEfiVarStoreNamePattern
.search(Content
, Pos
)
3635 Guid
= gEfiVarStoreGuidPattern
.search(Content
, Pos
)
3638 NameArray
= ConvertStringToByteArray('L"' + Name
.group(1) + '"')
3639 NameGuids
.append((NameArray
, GuidStructureStringToGuidString(Guid
.group(1))))
3640 Pos
= Content
.find('efivarstore', Name
.end())
3644 for Pcd
in self
.PlatformInfo
.Platform
.Pcds
.values():
3645 if Pcd
.Type
!= TAB_PCDS_DYNAMIC_EX_HII
:
3647 for SkuName
in Pcd
.SkuInfoList
:
3648 SkuInfo
= Pcd
.SkuInfoList
[SkuName
]
3649 Name
= ConvertStringToByteArray(SkuInfo
.VariableName
)
3650 Value
= GuidValue(SkuInfo
.VariableGuid
, self
.PlatformInfo
.PackageList
, self
.MetaFile
.Path
)
3653 Guid
= GuidStructureStringToGuidString(Value
)
3654 if (Name
, Guid
) in NameGuids
and Pcd
not in HiiExPcds
:
3655 HiiExPcds
.append(Pcd
)
3660 def _GenOffsetBin(self
):
3662 for SourceFile
in self
.Module
.Sources
:
3663 if SourceFile
.Type
.upper() == ".VFR" :
3665 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
3667 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
3668 if SourceFile
.Type
.upper() == ".UNI" :
3670 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
3672 VfrUniBaseName
["UniOffsetName"] = (self
.Name
+ "Strings")
3674 if len(VfrUniBaseName
) == 0:
3676 MapFileName
= os
.path
.join(self
.OutputDir
, self
.Name
+ ".map")
3677 EfiFileName
= os
.path
.join(self
.OutputDir
, self
.Name
+ ".efi")
3678 VfrUniOffsetList
= GetVariableOffset(MapFileName
, EfiFileName
, VfrUniBaseName
.values())
3679 if not VfrUniOffsetList
:
3682 OutputName
= '%sOffset.bin' % self
.Name
3683 UniVfrOffsetFileName
= os
.path
.join( self
.OutputDir
, OutputName
)
3686 fInputfile
= open(UniVfrOffsetFileName
, "wb+", 0)
3688 EdkLogger
.error("build", FILE_OPEN_FAILURE
, "File open failed for %s" % UniVfrOffsetFileName
,None)
3690 # Use a instance of StringIO to cache data
3691 fStringIO
= StringIO('')
3693 for Item
in VfrUniOffsetList
:
3694 if (Item
[0].find("Strings") != -1):
3696 # UNI offset in image.
3698 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
3700 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
3701 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
3702 fStringIO
.write(''.join(UniGuid
))
3703 UniValue
= pack ('Q', int (Item
[1], 16))
3704 fStringIO
.write (UniValue
)
3707 # VFR binary offset in image.
3709 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
3711 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
3712 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
3713 fStringIO
.write(''.join(VfrGuid
))
3715 VfrValue
= pack ('Q', int (Item
[1], 16))
3716 fStringIO
.write (VfrValue
)
3718 # write data into file.
3721 fInputfile
.write (fStringIO
.getvalue())
3723 EdkLogger
.error("build", FILE_WRITE_FAILURE
, "Write data to file %s failed, please check whether the "
3724 "file been locked or using by other applications." %UniVfrOffsetFileName
,None)
3730 ## Create AsBuilt INF file the module
3732 def CreateAsBuiltInf(self
):
3733 if self
.IsAsBuiltInfCreated
:
3736 # Skip the following code for EDK I inf
3737 if self
.AutoGenVersion
< 0x00010005:
3740 # Skip the following code for libraries
3744 # Skip the following code for modules with no source files
3745 if self
.SourceFileList
== None or self
.SourceFileList
== []:
3748 # Skip the following code for modules without any binary files
3749 if self
.BinaryFileList
<> None and self
.BinaryFileList
<> []:
3752 ### TODO: How to handles mixed source and binary modules
3754 # Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries
3755 # Also find all packages that the DynamicEx PCDs depend on
3760 PcdTokenSpaceList
= []
3761 for Pcd
in self
.ModulePcdList
+ self
.LibraryPcdList
:
3762 if Pcd
.Type
== TAB_PCDS_PATCHABLE_IN_MODULE
:
3763 PatchablePcds
+= [Pcd
]
3764 PcdCheckList
.append((Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, 'PatchableInModule'))
3765 elif Pcd
.Type
in GenC
.gDynamicExPcd
:
3768 PcdCheckList
.append((Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, 'DynamicEx'))
3769 PcdCheckList
.append((Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, 'Dynamic'))
3770 PcdTokenSpaceList
.append(Pcd
.TokenSpaceGuidCName
)
3772 GuidList
.update(self
.GuidList
)
3773 for TokenSpace
in self
.GetGuidsUsedByPcd():
3774 # If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list
3775 # The GUIDs in GUIDs section should really be the GUIDs in source INF or referred by Ex an patch PCDs
3776 if TokenSpace
not in PcdTokenSpaceList
and TokenSpace
in GuidList
:
3777 GuidList
.pop(TokenSpace
)
3778 CheckList
= (GuidList
, self
.PpiList
, self
.ProtocolList
, PcdCheckList
)
3779 for Package
in self
.DerivedPackageList
:
3780 if Package
in Packages
:
3782 BeChecked
= (Package
.Guids
, Package
.Ppis
, Package
.Protocols
, Package
.Pcds
)
3784 for Index
in range(len(BeChecked
)):
3785 for Item
in CheckList
[Index
]:
3786 if Item
in BeChecked
[Index
]:
3787 Packages
+= [Package
]
3792 VfrPcds
= self
._GetPcdsMaybeUsedByVfr
()
3793 for Pkg
in self
.PlatformInfo
.PackageList
:
3796 for VfrPcd
in VfrPcds
:
3797 if ((VfrPcd
.TokenCName
, VfrPcd
.TokenSpaceGuidCName
, 'DynamicEx') in Pkg
.Pcds
or
3798 (VfrPcd
.TokenCName
, VfrPcd
.TokenSpaceGuidCName
, 'Dynamic') in Pkg
.Pcds
):
3802 ModuleType
= self
.ModuleType
3803 if ModuleType
== 'UEFI_DRIVER' and self
.DepexGenerated
:
3804 ModuleType
= 'DXE_DRIVER'
3807 if self
.PcdIsDriver
!= '':
3808 DriverType
= self
.PcdIsDriver
3811 MDefs
= self
.Module
.Defines
3814 'module_name' : self
.Name
,
3815 'module_guid' : Guid
,
3816 'module_module_type' : ModuleType
,
3817 'module_version_string' : [MDefs
['VERSION_STRING']] if 'VERSION_STRING' in MDefs
else [],
3818 'pcd_is_driver_string' : [],
3819 'module_uefi_specification_version' : [],
3820 'module_pi_specification_version' : [],
3821 'module_entry_point' : self
.Module
.ModuleEntryPointList
,
3822 'module_unload_image' : self
.Module
.ModuleUnloadImageList
,
3823 'module_constructor' : self
.Module
.ConstructorList
,
3824 'module_destructor' : self
.Module
.DestructorList
,
3825 'module_shadow' : [MDefs
['SHADOW']] if 'SHADOW' in MDefs
else [],
3826 'module_pci_vendor_id' : [MDefs
['PCI_VENDOR_ID']] if 'PCI_VENDOR_ID' in MDefs
else [],
3827 'module_pci_device_id' : [MDefs
['PCI_DEVICE_ID']] if 'PCI_DEVICE_ID' in MDefs
else [],
3828 'module_pci_class_code' : [MDefs
['PCI_CLASS_CODE']] if 'PCI_CLASS_CODE' in MDefs
else [],
3829 'module_pci_revision' : [MDefs
['PCI_REVISION']] if 'PCI_REVISION' in MDefs
else [],
3830 'module_build_number' : [MDefs
['BUILD_NUMBER']] if 'BUILD_NUMBER' in MDefs
else [],
3831 'module_spec' : [MDefs
['SPEC']] if 'SPEC' in MDefs
else [],
3832 'module_uefi_hii_resource_section' : [MDefs
['UEFI_HII_RESOURCE_SECTION']] if 'UEFI_HII_RESOURCE_SECTION' in MDefs
else [],
3833 'module_uni_file' : [MDefs
['MODULE_UNI_FILE']] if 'MODULE_UNI_FILE' in MDefs
else [],
3834 'module_arch' : self
.Arch
,
3835 'package_item' : ['%s' % (Package
.MetaFile
.File
.replace('\\', '/')) for Package
in Packages
],
3837 'patchablepcd_item' : [],
3839 'protocol_item' : [],
3843 'libraryclasses_item' : []
3846 if self
.AutoGenVersion
> int(gInfSpecVersion
, 0):
3847 AsBuiltInfDict
['module_inf_version'] = '0x%08x' % self
.AutoGenVersion
3849 AsBuiltInfDict
['module_inf_version'] = gInfSpecVersion
3852 AsBuiltInfDict
['pcd_is_driver_string'] += [DriverType
]
3854 if 'UEFI_SPECIFICATION_VERSION' in self
.Specification
:
3855 AsBuiltInfDict
['module_uefi_specification_version'] += [self
.Specification
['UEFI_SPECIFICATION_VERSION']]
3856 if 'PI_SPECIFICATION_VERSION' in self
.Specification
:
3857 AsBuiltInfDict
['module_pi_specification_version'] += [self
.Specification
['PI_SPECIFICATION_VERSION']]
3859 OutputDir
= self
.OutputDir
.replace('\\', '/').strip('/')
3861 for Item
in self
.CodaTargetList
:
3862 File
= Item
.Target
.Path
.replace('\\', '/').strip('/').replace(OutputDir
, '').strip('/')
3863 if Item
.Target
.Ext
.lower() == '.aml':
3864 AsBuiltInfDict
['binary_item'] += ['ASL|' + File
]
3865 elif Item
.Target
.Ext
.lower() == '.acpi':
3866 AsBuiltInfDict
['binary_item'] += ['ACPI|' + File
]
3867 elif Item
.Target
.Ext
.lower() == '.efi':
3868 AsBuiltInfDict
['binary_item'] += ['PE32|' + self
.Name
+ '.efi']
3870 AsBuiltInfDict
['binary_item'] += ['BIN|' + File
]
3871 if self
.DepexGenerated
:
3872 if self
.ModuleType
in ['PEIM']:
3873 AsBuiltInfDict
['binary_item'] += ['PEI_DEPEX|' + self
.Name
+ '.depex']
3874 if self
.ModuleType
in ['DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'UEFI_DRIVER']:
3875 AsBuiltInfDict
['binary_item'] += ['DXE_DEPEX|' + self
.Name
+ '.depex']
3876 if self
.ModuleType
in ['DXE_SMM_DRIVER']:
3877 AsBuiltInfDict
['binary_item'] += ['SMM_DEPEX|' + self
.Name
+ '.depex']
3879 Bin
= self
._GenOffsetBin
()
3881 AsBuiltInfDict
['binary_item'] += ['BIN|%s' % Bin
]
3883 for Root
, Dirs
, Files
in os
.walk(OutputDir
):
3885 if File
.lower().endswith('.pdb'):
3886 AsBuiltInfDict
['binary_item'] += ['DISPOSABLE|' + File
]
3887 HeaderComments
= self
.Module
.HeaderComments
3889 for Index
in range(len(HeaderComments
)):
3890 if HeaderComments
[Index
].find('@BinaryHeader') != -1:
3891 HeaderComments
[Index
] = HeaderComments
[Index
].replace('@BinaryHeader', '@file')
3894 AsBuiltInfDict
['header_comments'] = '\n'.join(HeaderComments
[StartPos
:]).replace(':#', '://')
3895 AsBuiltInfDict
['tail_comments'] = '\n'.join(self
.Module
.TailComments
)
3898 (self
.ProtocolList
, self
._ProtocolComments
, 'protocol_item'),
3899 (self
.PpiList
, self
._PpiComments
, 'ppi_item'),
3900 (GuidList
, self
._GuidComments
, 'guid_item')
3902 for Item
in GenList
:
3903 for CName
in Item
[0]:
3905 if CName
in Item
[1]:
3906 Comments
= '\n '.join(Item
[1][CName
])
3909 Entry
= Comments
+ '\n ' + CName
3910 AsBuiltInfDict
[Item
[2]].append(Entry
)
3911 PatchList
= parsePcdInfoFromMapFile(
3912 os
.path
.join(self
.OutputDir
, self
.Name
+ '.map'),
3913 os
.path
.join(self
.OutputDir
, self
.Name
+ '.efi')
3916 for Pcd
in PatchablePcds
:
3917 TokenCName
= Pcd
.TokenCName
3918 for PcdItem
in GlobalData
.MixedPcd
:
3919 if (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
) in GlobalData
.MixedPcd
[PcdItem
]:
3920 TokenCName
= PcdItem
[0]
3922 for PatchPcd
in PatchList
:
3923 if TokenCName
== PatchPcd
[0]:
3928 if Pcd
.DatumType
!= 'VOID*':
3929 HexFormat
= '0x%02x'
3930 if Pcd
.DatumType
== 'UINT16':
3931 HexFormat
= '0x%04x'
3932 elif Pcd
.DatumType
== 'UINT32':
3933 HexFormat
= '0x%08x'
3934 elif Pcd
.DatumType
== 'UINT64':
3935 HexFormat
= '0x%016x'
3936 PcdValue
= HexFormat
% int(Pcd
.DefaultValue
, 0)
3938 if Pcd
.MaxDatumSize
== None or Pcd
.MaxDatumSize
== '':
3939 EdkLogger
.error("build", AUTOGEN_ERROR
,
3940 "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd
.TokenSpaceGuidCName
, TokenCName
)
3942 ArraySize
= int(Pcd
.MaxDatumSize
, 0)
3943 PcdValue
= Pcd
.DefaultValue
3944 if PcdValue
[0] != '{':
3946 if PcdValue
[0] == 'L':
3948 PcdValue
= PcdValue
.lstrip('L')
3949 PcdValue
= eval(PcdValue
)
3951 for Index
in range(0, len(PcdValue
)):
3953 CharVal
= ord(PcdValue
[Index
])
3954 NewValue
= NewValue
+ '0x%02x' % (CharVal
& 0x00FF) + ', ' \
3955 + '0x%02x' % (CharVal
>> 8) + ', '
3957 NewValue
= NewValue
+ '0x%02x' % (ord(PcdValue
[Index
]) % 0x100) + ', '
3960 Padding
= Padding
* 2
3961 ArraySize
= ArraySize
/ 2
3962 if ArraySize
< (len(PcdValue
) + 1):
3963 EdkLogger
.error("build", AUTOGEN_ERROR
,
3964 "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd
.TokenSpaceGuidCName
, TokenCName
)
3966 if ArraySize
> len(PcdValue
) + 1:
3967 NewValue
= NewValue
+ Padding
* (ArraySize
- len(PcdValue
) - 1)
3968 PcdValue
= NewValue
+ Padding
.strip().rstrip(',') + '}'
3969 elif len(PcdValue
.split(',')) <= ArraySize
:
3970 PcdValue
= PcdValue
.rstrip('}') + ', 0x00' * (ArraySize
- len(PcdValue
.split(',')))
3973 EdkLogger
.error("build", AUTOGEN_ERROR
,
3974 "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd
.TokenSpaceGuidCName
, TokenCName
)
3976 PcdItem
= '%s.%s|%s|0x%X' % \
3977 (Pcd
.TokenSpaceGuidCName
, TokenCName
, PcdValue
, PatchPcd
[1])
3979 if (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
) in self
._PcdComments
:
3980 PcdComments
= '\n '.join(self
._PcdComments
[Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
])
3982 PcdItem
= PcdComments
+ '\n ' + PcdItem
3983 AsBuiltInfDict
['patchablepcd_item'].append(PcdItem
)
3986 for Pcd
in Pcds
+ VfrPcds
:
3991 TokenCName
= Pcd
.TokenCName
3992 for PcdItem
in GlobalData
.MixedPcd
:
3993 if (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
) in GlobalData
.MixedPcd
[PcdItem
]:
3994 TokenCName
= PcdItem
[0]
3996 if Pcd
.Type
== TAB_PCDS_DYNAMIC_EX_HII
:
3997 for SkuName
in Pcd
.SkuInfoList
:
3998 SkuInfo
= Pcd
.SkuInfoList
[SkuName
]
3999 SkuId
= SkuInfo
.SkuId
4000 HiiInfo
= '## %s|%s|%s' % (SkuInfo
.VariableName
, SkuInfo
.VariableGuid
, SkuInfo
.VariableOffset
)
4004 # Don't generate duplicated HII PCD
4006 if (SkuId
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
) in HiiPcds
:
4009 HiiPcds
.append((SkuId
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
4010 if (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
) in self
._PcdComments
:
4011 PcdCommentList
= self
._PcdComments
[Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
][:]
4015 for Index
, Comment
in enumerate(PcdCommentList
):
4016 for Usage
in UsageList
:
4017 if Comment
.find(Usage
) != -1:
4021 if UsageIndex
!= -1:
4022 PcdCommentList
[UsageIndex
] = '## %s %s %s' % (UsageStr
, HiiInfo
, PcdCommentList
[UsageIndex
].replace(UsageStr
, ''))
4024 PcdCommentList
.append('## UNDEFINED ' + HiiInfo
)
4025 PcdComments
= '\n '.join(PcdCommentList
)
4026 PcdEntry
= Pcd
.TokenSpaceGuidCName
+ '.' + TokenCName
4028 PcdEntry
= PcdComments
+ '\n ' + PcdEntry
4029 AsBuiltInfDict
['pcd_item'] += [PcdEntry
]
4030 for Item
in self
.BuildOption
:
4031 if 'FLAGS' in self
.BuildOption
[Item
]:
4032 AsBuiltInfDict
['flags_item'] += ['%s:%s_%s_%s_%s_FLAGS = %s' % (self
.ToolChainFamily
, self
.BuildTarget
, self
.ToolChain
, self
.Arch
, Item
, self
.BuildOption
[Item
]['FLAGS'].strip())]
4034 # Generated LibraryClasses section in comments.
4035 for Library
in self
.LibraryAutoGenList
:
4036 AsBuiltInfDict
['libraryclasses_item'] += [Library
.MetaFile
.File
.replace('\\', '/')]
4038 # Generated depex expression section in comments.
4039 AsBuiltInfDict
['depexsection_item'] = ''
4040 DepexExpresion
= self
._GetDepexExpresionString
()
4042 AsBuiltInfDict
['depexsection_item'] = DepexExpresion
4044 AsBuiltInf
= TemplateString()
4045 AsBuiltInf
.Append(gAsBuiltInfHeaderString
.Replace(AsBuiltInfDict
))
4047 SaveFileOnChange(os
.path
.join(self
.OutputDir
, self
.Name
+ '.inf'), str(AsBuiltInf
), False)
4049 self
.IsAsBuiltInfCreated
= True
4051 ## Create makefile for the module and its dependent libraries
4053 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of
4054 # dependent libraries will be created
4056 def CreateMakeFile(self
, CreateLibraryMakeFile
=True):
4057 # Ignore generating makefile when it is a binary module
4058 if self
.IsBinaryModule
:
4061 if self
.IsMakeFileCreated
:
4066 if not self
.IsLibrary
and CreateLibraryMakeFile
:
4067 for LibraryAutoGen
in self
.LibraryAutoGenList
:
4068 LibraryAutoGen
.CreateMakeFile()
4070 if len(self
.CustomMakefile
) == 0:
4071 Makefile
= GenMake
.ModuleMakefile(self
)
4073 Makefile
= GenMake
.CustomMakefile(self
)
4074 if Makefile
.Generate():
4075 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for module %s [%s]" %
4076 (self
.Name
, self
.Arch
))
4078 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for module %s [%s]" %
4079 (self
.Name
, self
.Arch
))
4081 self
.CreateTimeStamp(Makefile
)
4082 self
.IsMakeFileCreated
= True
4084 def CopyBinaryFiles(self
):
4085 for File
in self
.Module
.Binaries
:
4087 DstPath
= os
.path
.join(self
.OutputDir
, os
.path
.basename(SrcPath
))
4088 CopyLongFilePath(SrcPath
, DstPath
)
4089 ## Create autogen code for the module and its dependent libraries
4091 # @param CreateLibraryCodeFile Flag indicating if or not the code of
4092 # dependent libraries will be created
4094 def CreateCodeFile(self
, CreateLibraryCodeFile
=True):
4095 if self
.IsCodeFileCreated
:
4100 # Need to generate PcdDatabase even PcdDriver is binarymodule
4101 if self
.IsBinaryModule
and self
.PcdIsDriver
!= '':
4102 CreatePcdDatabaseCode(self
, TemplateString(), TemplateString())
4104 if self
.IsBinaryModule
:
4106 self
.CopyBinaryFiles()
4109 if not self
.IsLibrary
and CreateLibraryCodeFile
:
4110 for LibraryAutoGen
in self
.LibraryAutoGenList
:
4111 LibraryAutoGen
.CreateCodeFile()
4114 IgoredAutoGenList
= []
4116 for File
in self
.AutoGenFileList
:
4117 if GenC
.Generate(File
.Path
, self
.AutoGenFileList
[File
], File
.IsBinary
):
4118 #Ignore Edk AutoGen.c
4119 if self
.AutoGenVersion
< 0x00010005 and File
.Name
== 'AutoGen.c':
4122 AutoGenList
.append(str(File
))
4124 IgoredAutoGenList
.append(str(File
))
4126 # Skip the following code for EDK I inf
4127 if self
.AutoGenVersion
< 0x00010005:
4130 for ModuleType
in self
.DepexList
:
4131 # Ignore empty [depex] section or [depex] section for "USER_DEFINED" module
4132 if len(self
.DepexList
[ModuleType
]) == 0 or ModuleType
== "USER_DEFINED":
4135 Dpx
= GenDepex
.DependencyExpression(self
.DepexList
[ModuleType
], ModuleType
, True)
4136 DpxFile
= gAutoGenDepexFileName
% {"module_name" : self
.Name
}
4138 if len(Dpx
.PostfixNotation
) <> 0:
4139 self
.DepexGenerated
= True
4141 if Dpx
.Generate(path
.join(self
.OutputDir
, DpxFile
)):
4142 AutoGenList
.append(str(DpxFile
))
4144 IgoredAutoGenList
.append(str(DpxFile
))
4146 if IgoredAutoGenList
== []:
4147 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] files for module %s [%s]" %
4148 (" ".join(AutoGenList
), self
.Name
, self
.Arch
))
4149 elif AutoGenList
== []:
4150 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of [%s] files for module %s [%s]" %
4151 (" ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
4153 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] (skipped %s) files for module %s [%s]" %
4154 (" ".join(AutoGenList
), " ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
4156 self
.IsCodeFileCreated
= True
4159 ## Summarize the ModuleAutoGen objects of all libraries used by this module
4160 def _GetLibraryAutoGenList(self
):
4161 if self
._LibraryAutoGenList
== None:
4162 self
._LibraryAutoGenList
= []
4163 for Library
in self
.DependentLibraryList
:
4170 self
.PlatformInfo
.MetaFile
4172 if La
not in self
._LibraryAutoGenList
:
4173 self
._LibraryAutoGenList
.append(La
)
4174 for Lib
in La
.CodaTargetList
:
4175 self
._ApplyBuildRule
(Lib
.Target
, TAB_UNKNOWN_FILE
)
4176 return self
._LibraryAutoGenList
4178 ## Decide whether we can skip the ModuleAutoGen process
4179 # If any source file is newer than the modeule than we cannot skip
4182 if not os
.path
.exists(self
.GetTimeStampPath()):
4184 #last creation time of the module
4185 DstTimeStamp
= os
.stat(self
.GetTimeStampPath())[8]
4187 SrcTimeStamp
= self
.Workspace
._SrcTimeStamp
4188 if SrcTimeStamp
> DstTimeStamp
:
4191 with
open(self
.GetTimeStampPath(),'r') as f
:
4193 source
= source
.rstrip('\n')
4194 if source
not in ModuleAutoGen
.TimeDict
:
4195 ModuleAutoGen
.TimeDict
[source
] = os
.stat(source
)[8]
4196 if ModuleAutoGen
.TimeDict
[source
] > DstTimeStamp
:
4200 def GetTimeStampPath(self
):
4201 if self
._TimeStampPath
== None:
4202 self
._TimeStampPath
= os
.path
.join(self
.MakeFileDir
, 'AutoGenTimeStamp')
4203 return self
._TimeStampPath
4204 def CreateTimeStamp(self
, Makefile
):
4208 FileSet
.add (self
.MetaFile
.Path
)
4210 for SourceFile
in self
.Module
.Sources
:
4211 FileSet
.add (SourceFile
.Path
)
4213 for Lib
in self
.DependentLibraryList
:
4214 FileSet
.add (Lib
.MetaFile
.Path
)
4216 for f
in self
.AutoGenDepSet
:
4217 FileSet
.add (f
.Path
)
4219 if os
.path
.exists (self
.GetTimeStampPath()):
4220 os
.remove (self
.GetTimeStampPath())
4221 with
open(self
.GetTimeStampPath(), 'w+') as file:
4225 Module
= property(_GetModule
)
4226 Name
= property(_GetBaseName
)
4227 Guid
= property(_GetGuid
)
4228 Version
= property(_GetVersion
)
4229 ModuleType
= property(_GetModuleType
)
4230 ComponentType
= property(_GetComponentType
)
4231 BuildType
= property(_GetBuildType
)
4232 PcdIsDriver
= property(_GetPcdIsDriver
)
4233 AutoGenVersion
= property(_GetAutoGenVersion
)
4234 Macros
= property(_GetMacros
)
4235 Specification
= property(_GetSpecification
)
4237 IsLibrary
= property(_IsLibrary
)
4238 IsBinaryModule
= property(_IsBinaryModule
)
4239 BuildDir
= property(_GetBuildDir
)
4240 OutputDir
= property(_GetOutputDir
)
4241 DebugDir
= property(_GetDebugDir
)
4242 MakeFileDir
= property(_GetMakeFileDir
)
4243 CustomMakefile
= property(_GetCustomMakefile
)
4245 IncludePathList
= property(_GetIncludePathList
)
4246 IncludePathLength
= property(_GetIncludePathLength
)
4247 AutoGenFileList
= property(_GetAutoGenFileList
)
4248 UnicodeFileList
= property(_GetUnicodeFileList
)
4249 VfrFileList
= property(_GetVfrFileList
)
4250 SourceFileList
= property(_GetSourceFileList
)
4251 BinaryFileList
= property(_GetBinaryFiles
) # FileType : [File List]
4252 Targets
= property(_GetTargets
)
4253 IntroTargetList
= property(_GetIntroTargetList
)
4254 CodaTargetList
= property(_GetFinalTargetList
)
4255 FileTypes
= property(_GetFileTypes
)
4256 BuildRules
= property(_GetBuildRules
)
4257 IdfFileList
= property(_GetIdfFileList
)
4259 DependentPackageList
= property(_GetDependentPackageList
)
4260 DependentLibraryList
= property(_GetLibraryList
)
4261 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
4262 DerivedPackageList
= property(_GetDerivedPackageList
)
4264 ModulePcdList
= property(_GetModulePcdList
)
4265 LibraryPcdList
= property(_GetLibraryPcdList
)
4266 GuidList
= property(_GetGuidList
)
4267 ProtocolList
= property(_GetProtocolList
)
4268 PpiList
= property(_GetPpiList
)
4269 DepexList
= property(_GetDepexTokenList
)
4270 DxsFile
= property(_GetDxsFile
)
4271 DepexExpressionList
= property(_GetDepexExpressionTokenList
)
4272 BuildOption
= property(_GetModuleBuildOption
)
4273 BuildOptionIncPathList
= property(_GetBuildOptionIncPathList
)
4274 BuildCommand
= property(_GetBuildCommand
)
4276 FixedAtBuildPcds
= property(_GetFixedAtBuildPcds
)
4278 # This acts like the main() function for the script, unless it is 'import'ed into another script.
4279 if __name__
== '__main__':