2 # Generate AutoGen.h, AutoGen.c and *.depex files
4 # Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 import os
.path
as path
24 from StringIO
import StringIO
26 from StrGather
import *
27 from BuildEngine
import BuildRule
29 from Common
.BuildToolError
import *
30 from Common
.DataType
import *
31 from Common
.Misc
import *
32 from Common
.String
import *
33 import Common
.GlobalData
as GlobalData
34 from GenFds
.FdfParser
import *
35 from CommonDataClass
.CommonClass
import SkuInfoClass
36 from Workspace
.BuildClassObject
import *
37 import Common
.VpdInfoFile
as VpdInfoFile
39 ## Regular expression for splitting Dependency Expression stirng into tokens
40 gDepexTokenPattern
= re
.compile("(\(|\)|\w+| \S+\.inf)")
42 ## Mapping Makefile type
43 gMakeTypeMap
= {"MSFT":"nmake", "GCC":"gmake"}
46 ## Build rule configuration file
47 gBuildRuleFile
= 'Conf/build_rule.txt'
49 ## Build rule default version
50 AutoGenReqBuildRuleVerNum
= "0.1"
52 ## default file name for AutoGen
53 gAutoGenCodeFileName
= "AutoGen.c"
54 gAutoGenHeaderFileName
= "AutoGen.h"
55 gAutoGenStringFileName
= "%(module_name)sStrDefs.h"
56 gAutoGenStringFormFileName
= "%(module_name)sStrDefs.hpk"
57 gAutoGenDepexFileName
= "%(module_name)s.depex"
60 # Template string to generic AsBuilt INF
62 gAsBuiltInfHeaderString
= TemplateString("""## @file
66 # FILE auto-generated Binary INF
71 INF_VERSION = 0x00010016
72 BASE_NAME = ${module_name}
73 FILE_GUID = ${module_guid}
74 MODULE_TYPE = ${module_module_type}
75 VERSION_STRING = ${module_version_string}${BEGIN}
76 UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN}
77 PI_SPECIFICATION_VERSION = ${module_pi_specification_version}${END}
82 [Binaries.${module_arch}]${BEGIN}
89 ## ${flags_item}${END}
92 ## Base class for AutoGen
94 # This class just implements the cache mechanism of AutoGen objects.
96 class AutoGen(object):
97 # database to maintain the objects of xxxAutoGen
98 _CACHE_
= {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}
102 # @param Class class object of real AutoGen class
103 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
104 # @param Workspace Workspace directory or WorkspaceAutoGen object
105 # @param MetaFile The path of meta file
106 # @param Target Build target
107 # @param Toolchain Tool chain name
108 # @param Arch Target arch
109 # @param *args The specific class related parameters
110 # @param **kwargs The specific class related dict parameters
112 def __new__(Class
, Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
113 # check if the object has been created
114 Key
= (Target
, Toolchain
)
115 if Key
not in Class
._CACHE
_ or Arch
not in Class
._CACHE
_[Key
] \
116 or MetaFile
not in Class
._CACHE
_[Key
][Arch
]:
117 AutoGenObject
= super(AutoGen
, Class
).__new
__(Class
)
118 # call real constructor
119 if not AutoGenObject
._Init
(Workspace
, MetaFile
, Target
, Toolchain
, Arch
, *args
, **kwargs
):
121 if Key
not in Class
._CACHE
_:
122 Class
._CACHE
_[Key
] = {}
123 if Arch
not in Class
._CACHE
_[Key
]:
124 Class
._CACHE
_[Key
][Arch
] = {}
125 Class
._CACHE
_[Key
][Arch
][MetaFile
] = AutoGenObject
127 AutoGenObject
= Class
._CACHE
_[Key
][Arch
][MetaFile
]
133 # The file path of platform file will be used to represent hash value of this object
135 # @retval int Hash value of the file path of platform file
138 return hash(self
.MetaFile
)
142 # The file path of platform file will be used to represent this object
144 # @retval string String of platform file path
147 return str(self
.MetaFile
)
150 def __eq__(self
, Other
):
151 return Other
and self
.MetaFile
== Other
153 ## Workspace AutoGen class
155 # This class is used mainly to control the whole platform build for different
156 # architecture. This class will generate top level makefile.
158 class WorkspaceAutoGen(AutoGen
):
159 ## Real constructor of WorkspaceAutoGen
161 # This method behaves the same as __init__ except that it needs explicit invoke
162 # (in super class's __new__ method)
164 # @param WorkspaceDir Root directory of workspace
165 # @param ActivePlatform Meta-file of active platform
166 # @param Target Build target
167 # @param Toolchain Tool chain name
168 # @param ArchList List of architecture of current build
169 # @param MetaFileDb Database containing meta-files
170 # @param BuildConfig Configuration of build
171 # @param ToolDefinition Tool chain definitions
172 # @param FlashDefinitionFile File of flash definition
173 # @param Fds FD list to be generated
174 # @param Fvs FV list to be generated
175 # @param Caps Capsule list to be generated
176 # @param SkuId SKU id from command line
178 def _Init(self
, WorkspaceDir
, ActivePlatform
, Target
, Toolchain
, ArchList
, MetaFileDb
,
179 BuildConfig
, ToolDefinition
, FlashDefinitionFile
='', Fds
=None, Fvs
=None, Caps
=None, SkuId
='', UniFlag
=None,
180 Progress
=None, BuildModule
=None):
187 self
.BuildDatabase
= MetaFileDb
188 self
.MetaFile
= ActivePlatform
189 self
.WorkspaceDir
= WorkspaceDir
190 self
.Platform
= self
.BuildDatabase
[self
.MetaFile
, 'COMMON', Target
, Toolchain
]
191 GlobalData
.gActivePlatform
= self
.Platform
192 self
.BuildTarget
= Target
193 self
.ToolChain
= Toolchain
194 self
.ArchList
= ArchList
196 self
.UniFlag
= UniFlag
198 self
.TargetTxt
= BuildConfig
199 self
.ToolDef
= ToolDefinition
200 self
.FdfFile
= FlashDefinitionFile
201 self
.FdTargetList
= Fds
202 self
.FvTargetList
= Fvs
203 self
.CapTargetList
= Caps
204 self
.AutoGenObjectList
= []
206 # there's many relative directory operations, so ...
207 os
.chdir(self
.WorkspaceDir
)
212 if not self
.ArchList
:
213 ArchList
= set(self
.Platform
.SupArchList
)
215 ArchList
= set(self
.ArchList
) & set(self
.Platform
.SupArchList
)
217 EdkLogger
.error("build", PARAMETER_INVALID
,
218 ExtraData
= "Invalid ARCH specified. [Valid ARCH: %s]" % (" ".join(self
.Platform
.SupArchList
)))
219 elif self
.ArchList
and len(ArchList
) != len(self
.ArchList
):
220 SkippedArchList
= set(self
.ArchList
).symmetric_difference(set(self
.Platform
.SupArchList
))
221 EdkLogger
.verbose("\nArch [%s] is ignored because the platform supports [%s] only!"
222 % (" ".join(SkippedArchList
), " ".join(self
.Platform
.SupArchList
)))
223 self
.ArchList
= tuple(ArchList
)
225 # Validate build target
226 if self
.BuildTarget
not in self
.Platform
.BuildTargets
:
227 EdkLogger
.error("build", PARAMETER_INVALID
,
228 ExtraData
="Build target [%s] is not supported by the platform. [Valid target: %s]"
229 % (self
.BuildTarget
, " ".join(self
.Platform
.BuildTargets
)))
233 self
.SkuId
= 'DEFAULT'
235 if self
.SkuId
not in self
.Platform
.SkuIds
:
236 EdkLogger
.error("build", PARAMETER_INVALID
,
237 ExtraData
="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"
238 % (self
.SkuId
, " ".join(self
.Platform
.SkuIds
.keys())))
240 # parse FDF file to get PCDs in it, if any
242 self
.FdfFile
= self
.Platform
.FlashDefinition
246 EdkLogger
.info('%-16s = %s' % ("Architecture(s)", ' '.join(self
.ArchList
)))
247 EdkLogger
.info('%-16s = %s' % ("Build target", self
.BuildTarget
))
248 EdkLogger
.info('%-16s = %s' % ("Toolchain",self
.ToolChain
))
250 EdkLogger
.info('\n%-24s = %s' % ("Active Platform", self
.Platform
))
252 EdkLogger
.info('%-24s = %s' % ("Active Module", BuildModule
))
255 EdkLogger
.info('%-24s = %s' % ("Flash Image Definition", self
.FdfFile
))
257 EdkLogger
.verbose("\nFLASH_DEFINITION = %s" % self
.FdfFile
)
260 Progress
.Start("\nProcessing meta-data")
264 # Mark now build in AutoGen Phase
266 GlobalData
.gAutoGenPhase
= True
267 Fdf
= FdfParser(self
.FdfFile
.Path
)
269 GlobalData
.gAutoGenPhase
= False
270 PcdSet
= Fdf
.Profile
.PcdDict
271 ModuleList
= Fdf
.Profile
.InfList
272 self
.FdfProfile
= Fdf
.Profile
273 for fvname
in self
.FvTargetList
:
274 if fvname
.upper() not in self
.FdfProfile
.FvDict
:
275 EdkLogger
.error("build", OPTION_VALUE_INVALID
,
276 "No such an FV in FDF file: %s" % fvname
)
280 self
.FdfProfile
= None
281 if self
.FdTargetList
:
282 EdkLogger
.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self
.FdTargetList
))
283 self
.FdTargetList
= []
284 if self
.FvTargetList
:
285 EdkLogger
.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self
.FvTargetList
))
286 self
.FvTargetList
= []
287 if self
.CapTargetList
:
288 EdkLogger
.info("No flash definition file found. Capsule [%s] will be ignored." % " ".join(self
.CapTargetList
))
289 self
.CapTargetList
= []
291 # apply SKU and inject PCDs from Flash Definition file
292 for Arch
in self
.ArchList
:
293 Platform
= self
.BuildDatabase
[self
.MetaFile
, Arch
, Target
, Toolchain
]
296 PGen
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
297 Pkgs
= PGen
.PackageList
299 for Pcd
in Pkg
.Pcds
.keys():
300 DecPcds
.add((Pcd
[0], Pcd
[1]))
301 Platform
.IsPlatformPcdDeclared(DecPcds
)
303 Platform
.SkuName
= self
.SkuId
304 for Name
, Guid
in PcdSet
:
305 if (Name
, Guid
) not in DecPcds
:
309 "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid
, Name
),
310 File
= self
.FdfProfile
.PcdFileLineDict
[Name
, Guid
][0],
311 Line
= self
.FdfProfile
.PcdFileLineDict
[Name
, Guid
][1]
313 Platform
.AddPcd(Name
, Guid
, PcdSet
[Name
, Guid
])
315 Pa
= PlatformAutoGen(self
, self
.MetaFile
, Target
, Toolchain
, Arch
)
317 # Explicitly collect platform's dynamic PCDs
319 Pa
.CollectPlatformDynamicPcds()
320 self
.AutoGenObjectList
.append(Pa
)
323 # Check PCDs token value conflict in each DEC file.
325 self
._CheckAllPcdsTokenValueConflict
()
328 # Check PCD type and definition between DSC and DEC
330 self
._CheckPcdDefineAndType
()
333 self
._CheckDuplicateInFV
(Fdf
)
335 self
._BuildDir
= None
337 self
._MakeFileDir
= None
338 self
._BuildCommand
= None
342 ## _CheckDuplicateInFV() method
344 # Check whether there is duplicate modules/files exist in FV section.
345 # The check base on the file GUID;
347 def _CheckDuplicateInFV(self
, Fdf
):
348 for Fv
in Fdf
.Profile
.FvDict
:
350 for FfsFile
in Fdf
.Profile
.FvDict
[Fv
].FfsList
:
351 if FfsFile
.InfFileName
and FfsFile
.NameGuid
== None:
356 for Pa
in self
.AutoGenObjectList
:
359 for Module
in Pa
.ModuleAutoGenList
:
360 if path
.normpath(Module
.MetaFile
.File
) == path
.normpath(FfsFile
.InfFileName
):
362 if not Module
.Guid
.upper() in _GuidDict
.keys():
363 _GuidDict
[Module
.Guid
.upper()] = FfsFile
366 EdkLogger
.error("build",
368 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s"%(FfsFile
.CurrentLineNum
,
369 FfsFile
.CurrentLineContent
,
370 _GuidDict
[Module
.Guid
.upper()].CurrentLineNum
,
371 _GuidDict
[Module
.Guid
.upper()].CurrentLineContent
,
372 Module
.Guid
.upper()),
373 ExtraData
=self
.FdfFile
)
375 # Some INF files not have entity in DSC file.
378 if FfsFile
.InfFileName
.find('$') == -1:
379 InfPath
= NormPath(FfsFile
.InfFileName
)
380 if not os
.path
.exists(InfPath
):
381 EdkLogger
.error('build', GENFDS_ERROR
, "Non-existant Module %s !" % (FfsFile
.InfFileName
))
383 PathClassObj
= PathClass(FfsFile
.InfFileName
, self
.WorkspaceDir
)
385 # Here we just need to get FILE_GUID from INF file, use 'COMMON' as ARCH attribute. and use
386 # BuildObject from one of AutoGenObjectList is enough.
388 InfObj
= self
.AutoGenObjectList
[0].BuildDatabase
.WorkspaceDb
.BuildObject
[PathClassObj
, 'COMMON', self
.BuildTarget
, self
.ToolChain
]
389 if not InfObj
.Guid
.upper() in _GuidDict
.keys():
390 _GuidDict
[InfObj
.Guid
.upper()] = FfsFile
392 EdkLogger
.error("build",
394 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s"%(FfsFile
.CurrentLineNum
,
395 FfsFile
.CurrentLineContent
,
396 _GuidDict
[InfObj
.Guid
.upper()].CurrentLineNum
,
397 _GuidDict
[InfObj
.Guid
.upper()].CurrentLineContent
,
398 InfObj
.Guid
.upper()),
399 ExtraData
=self
.FdfFile
)
402 if FfsFile
.NameGuid
!= None:
403 _CheckPCDAsGuidPattern
= re
.compile("^PCD\(.+\..+\)$")
406 # If the NameGuid reference a PCD name.
407 # The style must match: PCD(xxxx.yyy)
409 if _CheckPCDAsGuidPattern
.match(FfsFile
.NameGuid
):
411 # Replace the PCD value.
413 _PcdName
= FfsFile
.NameGuid
.lstrip("PCD(").rstrip(")")
415 for Pa
in self
.AutoGenObjectList
:
417 for PcdItem
in Pa
.AllPcdList
:
418 if (PcdItem
.TokenSpaceGuidCName
+ "." + PcdItem
.TokenCName
) == _PcdName
:
420 # First convert from CFormatGuid to GUID string
422 _PcdGuidString
= GuidStructureStringToGuidString(PcdItem
.DefaultValue
)
424 if not _PcdGuidString
:
426 # Then try Byte array.
428 _PcdGuidString
= GuidStructureByteArrayToGuidString(PcdItem
.DefaultValue
)
430 if not _PcdGuidString
:
432 # Not Byte array or CFormat GUID, raise error.
434 EdkLogger
.error("build",
436 "The format of PCD value is incorrect. PCD: %s , Value: %s\n"%(_PcdName
, PcdItem
.DefaultValue
),
437 ExtraData
=self
.FdfFile
)
439 if not _PcdGuidString
.upper() in _GuidDict
.keys():
440 _GuidDict
[_PcdGuidString
.upper()] = FfsFile
444 EdkLogger
.error("build",
446 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s"%(FfsFile
.CurrentLineNum
,
447 FfsFile
.CurrentLineContent
,
448 _GuidDict
[_PcdGuidString
.upper()].CurrentLineNum
,
449 _GuidDict
[_PcdGuidString
.upper()].CurrentLineContent
,
450 FfsFile
.NameGuid
.upper()),
451 ExtraData
=self
.FdfFile
)
453 if not FfsFile
.NameGuid
.upper() in _GuidDict
.keys():
454 _GuidDict
[FfsFile
.NameGuid
.upper()] = FfsFile
457 # Two raw file GUID conflict.
459 EdkLogger
.error("build",
461 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s"%(FfsFile
.CurrentLineNum
,
462 FfsFile
.CurrentLineContent
,
463 _GuidDict
[FfsFile
.NameGuid
.upper()].CurrentLineNum
,
464 _GuidDict
[FfsFile
.NameGuid
.upper()].CurrentLineContent
,
465 FfsFile
.NameGuid
.upper()),
466 ExtraData
=self
.FdfFile
)
469 def _CheckPcdDefineAndType(self
):
471 "FixedAtBuild", "PatchableInModule", "FeatureFlag",
472 "Dynamic", #"DynamicHii", "DynamicVpd",
473 "DynamicEx", # "DynamicExHii", "DynamicExVpd"
476 # This dict store PCDs which are not used by any modules with specified arches
478 for Pa
in self
.AutoGenObjectList
:
479 # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid
480 for Pcd
in Pa
.Platform
.Pcds
:
481 PcdType
= Pa
.Platform
.Pcds
[Pcd
].Type
483 # If no PCD type, this PCD comes from FDF
487 # Try to remove Hii and Vpd suffix
488 if PcdType
.startswith("DynamicEx"):
489 PcdType
= "DynamicEx"
490 elif PcdType
.startswith("Dynamic"):
493 for Package
in Pa
.PackageList
:
494 # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType
495 if (Pcd
[0], Pcd
[1], PcdType
) in Package
.Pcds
:
497 for Type
in PcdTypeList
:
498 if (Pcd
[0], Pcd
[1], Type
) in Package
.Pcds
:
502 "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \
503 % (Pa
.Platform
.Pcds
[Pcd
].Type
, Pcd
[1], Pcd
[0], Type
),
508 UnusedPcd
.setdefault(Pcd
, []).append(Pa
.Arch
)
510 for Pcd
in UnusedPcd
:
513 "The PCD was not specified by any INF module in the platform for the given architecture.\n"
514 "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"
515 % (Pcd
[1], Pcd
[0], os
.path
.basename(str(self
.MetaFile
)), str(UnusedPcd
[Pcd
])),
520 return "%s [%s]" % (self
.MetaFile
, ", ".join(self
.ArchList
))
522 ## Return the directory to store FV files
524 if self
._FvDir
== None:
525 self
._FvDir
= path
.join(self
.BuildDir
, 'FV')
528 ## Return the directory to store all intermediate and final files built
529 def _GetBuildDir(self
):
530 return self
.AutoGenObjectList
[0].BuildDir
532 ## Return the build output directory platform specifies
533 def _GetOutputDir(self
):
534 return self
.Platform
.OutputDirectory
536 ## Return platform name
538 return self
.Platform
.PlatformName
540 ## Return meta-file GUID
542 return self
.Platform
.Guid
544 ## Return platform version
545 def _GetVersion(self
):
546 return self
.Platform
.Version
548 ## Return paths of tools
549 def _GetToolDefinition(self
):
550 return self
.AutoGenObjectList
[0].ToolDefinition
552 ## Return directory of platform makefile
554 # @retval string Makefile directory
556 def _GetMakeFileDir(self
):
557 if self
._MakeFileDir
== None:
558 self
._MakeFileDir
= self
.BuildDir
559 return self
._MakeFileDir
561 ## Return build command string
563 # @retval string Build command string
565 def _GetBuildCommand(self
):
566 if self
._BuildCommand
== None:
567 # BuildCommand should be all the same. So just get one from platform AutoGen
568 self
._BuildCommand
= self
.AutoGenObjectList
[0].BuildCommand
569 return self
._BuildCommand
571 ## Check the PCDs token value conflict in each DEC file.
573 # Will cause build break and raise error message while two PCDs conflict.
577 def _CheckAllPcdsTokenValueConflict(self
):
578 for Pa
in self
.AutoGenObjectList
:
579 for Package
in Pa
.PackageList
:
580 PcdList
= Package
.Pcds
.values()
581 PcdList
.sort(lambda x
, y
: cmp(x
.TokenValue
, y
.TokenValue
))
583 while (Count
< len(PcdList
) - 1) :
584 Item
= PcdList
[Count
]
585 ItemNext
= PcdList
[Count
+ 1]
587 # Make sure in the same token space the TokenValue should be unique
589 if (Item
.TokenValue
== ItemNext
.TokenValue
):
590 SameTokenValuePcdList
= []
591 SameTokenValuePcdList
.append(Item
)
592 SameTokenValuePcdList
.append(ItemNext
)
593 RemainPcdListLength
= len(PcdList
) - Count
- 2
594 for ValueSameCount
in range(RemainPcdListLength
):
595 if PcdList
[len(PcdList
) - RemainPcdListLength
+ ValueSameCount
].TokenValue
== Item
.TokenValue
:
596 SameTokenValuePcdList
.append(PcdList
[len(PcdList
) - RemainPcdListLength
+ ValueSameCount
])
600 # Sort same token value PCD list with TokenGuid and TokenCName
602 SameTokenValuePcdList
.sort(lambda x
, y
: cmp("%s.%s"%(x
.TokenSpaceGuidCName
, x
.TokenCName
), "%s.%s"%(y
.TokenSpaceGuidCName
, y
.TokenCName
)))
603 SameTokenValuePcdListCount
= 0
604 while (SameTokenValuePcdListCount
< len(SameTokenValuePcdList
) - 1):
605 TemListItem
= SameTokenValuePcdList
[SameTokenValuePcdListCount
]
606 TemListItemNext
= SameTokenValuePcdList
[SameTokenValuePcdListCount
+ 1]
608 if (TemListItem
.TokenSpaceGuidCName
== TemListItemNext
.TokenSpaceGuidCName
) and (TemListItem
.TokenCName
!= TemListItemNext
.TokenCName
):
612 "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\
613 % (TemListItem
.TokenValue
, TemListItem
.TokenSpaceGuidCName
, TemListItem
.TokenCName
, TemListItemNext
.TokenSpaceGuidCName
, TemListItemNext
.TokenCName
, Package
),
616 SameTokenValuePcdListCount
+= 1
617 Count
+= SameTokenValuePcdListCount
620 PcdList
= Package
.Pcds
.values()
621 PcdList
.sort(lambda x
, y
: cmp("%s.%s"%(x
.TokenSpaceGuidCName
, x
.TokenCName
), "%s.%s"%(y
.TokenSpaceGuidCName
, y
.TokenCName
)))
623 while (Count
< len(PcdList
) - 1) :
624 Item
= PcdList
[Count
]
625 ItemNext
= PcdList
[Count
+ 1]
627 # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.
629 if (Item
.TokenSpaceGuidCName
== ItemNext
.TokenSpaceGuidCName
) and (Item
.TokenCName
== ItemNext
.TokenCName
) and (Item
.TokenValue
!= ItemNext
.TokenValue
):
633 "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\
634 % (Item
.TokenValue
, Item
.TokenSpaceGuidCName
, Item
.TokenCName
, Package
),
640 ## Create makefile for the platform and modules in it
642 # @param CreateDepsMakeFile Flag indicating if the makefile for
643 # modules will be created as well
645 def CreateMakeFile(self
, CreateDepsMakeFile
=False):
646 # create makefile for platform
647 Makefile
= GenMake
.TopLevelMakefile(self
)
648 if Makefile
.Generate():
649 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for platform [%s] %s\n" %
650 (self
.MetaFile
, self
.ArchList
))
652 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for platform [%s] %s\n" %
653 (self
.MetaFile
, self
.ArchList
))
655 if CreateDepsMakeFile
:
656 for Pa
in self
.AutoGenObjectList
:
657 Pa
.CreateMakeFile(CreateDepsMakeFile
)
659 ## Create autogen code for platform and modules
661 # Since there's no autogen code for platform, this method will do nothing
662 # if CreateModuleCodeFile is set to False.
664 # @param CreateDepsCodeFile Flag indicating if creating module's
665 # autogen code file or not
667 def CreateCodeFile(self
, CreateDepsCodeFile
=False):
668 if not CreateDepsCodeFile
:
670 for Pa
in self
.AutoGenObjectList
:
671 Pa
.CreateCodeFile(CreateDepsCodeFile
)
673 ## Create AsBuilt INF file the platform
675 def CreateAsBuiltInf(self
):
678 Name
= property(_GetName
)
679 Guid
= property(_GetGuid
)
680 Version
= property(_GetVersion
)
681 OutputDir
= property(_GetOutputDir
)
683 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
685 BuildDir
= property(_GetBuildDir
)
686 FvDir
= property(_GetFvDir
)
687 MakeFileDir
= property(_GetMakeFileDir
)
688 BuildCommand
= property(_GetBuildCommand
)
690 ## AutoGen class for platform
692 # PlatformAutoGen class will process the original information in platform
693 # file in order to generate makefile for platform.
695 class PlatformAutoGen(AutoGen
):
697 # Used to store all PCDs for both PEI and DXE phase, in order to generate
698 # correct PCD database
701 _NonDynaPcdList_
= []
704 # The priority list while override build option
706 PrioList
= {"0x11111" : 16, # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)
707 "0x01111" : 15, # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
708 "0x10111" : 14, # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE
709 "0x00111" : 13, # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE
710 "0x11011" : 12, # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
711 "0x01011" : 11, # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE
712 "0x10011" : 10, # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE
713 "0x00011" : 9, # ******_*********_****_COMMANDTYPE_ATTRIBUTE
714 "0x11101" : 8, # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE
715 "0x01101" : 7, # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE
716 "0x10101" : 6, # TARGET_*********_ARCH_***********_ATTRIBUTE
717 "0x00101" : 5, # ******_*********_ARCH_***********_ATTRIBUTE
718 "0x11001" : 4, # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE
719 "0x01001" : 3, # ******_TOOLCHAIN_****_***********_ATTRIBUTE
720 "0x10001" : 2, # TARGET_*********_****_***********_ATTRIBUTE
721 "0x00001" : 1} # ******_*********_****_***********_ATTRIBUTE (Lowest)
723 ## The real constructor of PlatformAutoGen
725 # This method is not supposed to be called by users of PlatformAutoGen. It's
726 # only used by factory method __new__() to do real initialization work for an
727 # object of PlatformAutoGen
729 # @param Workspace WorkspaceAutoGen object
730 # @param PlatformFile Platform file (DSC file)
731 # @param Target Build target (DEBUG, RELEASE)
732 # @param Toolchain Name of tool chain
733 # @param Arch arch of the platform supports
735 def _Init(self
, Workspace
, PlatformFile
, Target
, Toolchain
, Arch
):
736 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen platform [%s] [%s]" % (PlatformFile
, Arch
))
737 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (PlatformFile
, Arch
, Toolchain
, Target
)
739 self
.MetaFile
= PlatformFile
740 self
.Workspace
= Workspace
741 self
.WorkspaceDir
= Workspace
.WorkspaceDir
742 self
.ToolChain
= Toolchain
743 self
.BuildTarget
= Target
745 self
.SourceDir
= PlatformFile
.SubDir
746 self
.SourceOverrideDir
= None
747 self
.FdTargetList
= self
.Workspace
.FdTargetList
748 self
.FvTargetList
= self
.Workspace
.FvTargetList
751 # flag indicating if the makefile/C-code file has been created or not
752 self
.IsMakeFileCreated
= False
753 self
.IsCodeFileCreated
= False
755 self
._Platform
= None
760 self
._BuildRule
= None
761 self
._SourceDir
= None
762 self
._BuildDir
= None
763 self
._OutputDir
= None
765 self
._MakeFileDir
= None
768 self
._PcdTokenNumber
= None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
769 self
._DynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
770 self
._NonDynamicPcdList
= None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
772 self
._ToolDefinitions
= None
773 self
._ToolDefFile
= None # toolcode : tool path
774 self
._ToolChainFamily
= None
775 self
._BuildRuleFamily
= None
776 self
._BuildOption
= None # toolcode : option
777 self
._EdkBuildOption
= None # edktoolcode : option
778 self
._EdkIIBuildOption
= None # edkiitoolcode : option
779 self
._PackageList
= None
780 self
._ModuleAutoGenList
= None
781 self
._LibraryAutoGenList
= None
782 self
._BuildCommand
= None
784 # get the original module/package/platform objects
785 self
.BuildDatabase
= Workspace
.BuildDatabase
789 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
791 ## Create autogen code for platform and modules
793 # Since there's no autogen code for platform, this method will do nothing
794 # if CreateModuleCodeFile is set to False.
796 # @param CreateModuleCodeFile Flag indicating if creating module's
797 # autogen code file or not
799 def CreateCodeFile(self
, CreateModuleCodeFile
=False):
800 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
801 if self
.IsCodeFileCreated
or not CreateModuleCodeFile
:
804 for Ma
in self
.ModuleAutoGenList
:
805 Ma
.CreateCodeFile(True)
807 # don't do this twice
808 self
.IsCodeFileCreated
= True
810 ## Create makefile for the platform and mdoules in it
812 # @param CreateModuleMakeFile Flag indicating if the makefile for
813 # modules will be created as well
815 def CreateMakeFile(self
, CreateModuleMakeFile
=False):
816 if CreateModuleMakeFile
:
817 for ModuleFile
in self
.Platform
.Modules
:
818 Ma
= ModuleAutoGen(self
.Workspace
, ModuleFile
, self
.BuildTarget
,
819 self
.ToolChain
, self
.Arch
, self
.MetaFile
)
820 Ma
.CreateMakeFile(True)
821 Ma
.CreateAsBuiltInf()
823 # no need to create makefile for the platform more than once
824 if self
.IsMakeFileCreated
:
827 # create makefile for platform
828 Makefile
= GenMake
.PlatformMakefile(self
)
829 if Makefile
.Generate():
830 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for platform [%s] [%s]\n" %
831 (self
.MetaFile
, self
.Arch
))
833 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for platform [%s] [%s]\n" %
834 (self
.MetaFile
, self
.Arch
))
835 self
.IsMakeFileCreated
= True
837 ## Collect dynamic PCDs
839 # Gather dynamic PCDs list from each module and their settings from platform
840 # This interface should be invoked explicitly when platform action is created.
842 def CollectPlatformDynamicPcds(self
):
843 # for gathering error information
844 NoDatumTypePcdList
= set()
847 for F
in self
.Platform
.Modules
.keys():
848 M
= ModuleAutoGen(self
.Workspace
, F
, self
.BuildTarget
, self
.ToolChain
, self
.Arch
, self
.MetaFile
)
849 #GuidValue.update(M.Guids)
851 self
.Platform
.Modules
[F
].M
= M
853 for PcdFromModule
in M
.ModulePcdList
+M
.LibraryPcdList
:
854 # make sure that the "VOID*" kind of datum has MaxDatumSize set
855 if PcdFromModule
.DatumType
== "VOID*" and PcdFromModule
.MaxDatumSize
== None:
856 NoDatumTypePcdList
.add("%s.%s [%s]" % (PcdFromModule
.TokenSpaceGuidCName
, PcdFromModule
.TokenCName
, F
))
858 if PcdFromModule
.Type
in GenC
.gDynamicPcd
or PcdFromModule
.Type
in GenC
.gDynamicExPcd
:
860 # If a dynamic PCD used by a PEM module/PEI module & DXE module,
861 # it should be stored in Pcd PEI database, If a dynamic only
862 # used by DXE module, it should be stored in DXE PCD database.
863 # The default Phase is DXE
865 if M
.ModuleType
in ["PEIM", "PEI_CORE"]:
866 PcdFromModule
.Phase
= "PEI"
867 if PcdFromModule
not in self
._DynaPcdList
_:
868 self
._DynaPcdList
_.append(PcdFromModule
)
869 elif PcdFromModule
.Phase
== 'PEI':
870 # overwrite any the same PCD existing, if Phase is PEI
871 Index
= self
._DynaPcdList
_.index(PcdFromModule
)
872 self
._DynaPcdList
_[Index
] = PcdFromModule
873 elif PcdFromModule
not in self
._NonDynaPcdList
_:
874 self
._NonDynaPcdList
_.append(PcdFromModule
)
876 # print out error information and break the build, if error found
877 if len(NoDatumTypePcdList
) > 0:
878 NoDatumTypePcdListString
= "\n\t\t".join(NoDatumTypePcdList
)
879 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
881 ExtraData
="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
882 % NoDatumTypePcdListString
)
883 self
._NonDynamicPcdList
= self
._NonDynaPcdList
_
884 self
._DynamicPcdList
= self
._DynaPcdList
_
885 self
.AllPcdList
= self
._NonDynamicPcdList
+ self
._DynamicPcdList
888 # Sort dynamic PCD list to:
889 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should
890 # try to be put header of dynamicd List
891 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD
893 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
899 VpdFile
= VpdInfoFile
.VpdInfoFile()
900 NeedProcessVpdMapFile
= False
902 if (self
.Workspace
.ArchList
[-1] == self
.Arch
):
903 for Pcd
in self
._DynamicPcdList
:
904 # just pick the a value to determine whether is unicode string type
905 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
906 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
908 PcdValue
= Sku
.DefaultValue
909 if Pcd
.DatumType
== 'VOID*' and PcdValue
.startswith("L"):
910 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
911 UnicodePcdArray
.append(Pcd
)
912 elif len(Sku
.VariableName
) > 0:
913 # if found HII type PCD then insert to right of UnicodeIndex
914 HiiPcdArray
.append(Pcd
)
916 OtherPcdArray
.append(Pcd
)
917 if Pcd
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
]:
918 VpdPcdDict
[(Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
)] = Pcd
920 PlatformPcds
= self
.Platform
.Pcds
.keys()
923 # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.
925 for PcdKey
in PlatformPcds
:
926 Pcd
= self
.Platform
.Pcds
[PcdKey
]
927 if Pcd
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
]:
928 Pcd
= VpdPcdDict
[PcdKey
]
929 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
930 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
932 # Fix the optional data of VPD PCD.
934 if (Pcd
.DatumType
.strip() != "VOID*"):
935 if Sku
.DefaultValue
== '':
936 Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]].DefaultValue
= Pcd
.MaxDatumSize
937 Pcd
.MaxDatumSize
= None
939 EdkLogger
.error("build", AUTOGEN_ERROR
, "PCD setting error",
941 ExtraData
="\n\tPCD: %s.%s format incorrect in DSC: %s\n\t\t\n"
942 % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, self
.Platform
.MetaFile
.Path
))
944 VpdFile
.Add(Pcd
, Sku
.VpdOffset
)
945 # if the offset of a VPD is *, then it need to be fixed up by third party tool.
946 if not NeedProcessVpdMapFile
and Sku
.VpdOffset
== "*":
947 NeedProcessVpdMapFile
= True
948 if self
.Platform
.VpdToolGuid
== None or self
.Platform
.VpdToolGuid
== '':
949 EdkLogger
.error("Build", FILE_NOT_FOUND
, \
950 "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.")
954 # Fix the PCDs define in VPD PCD section that never referenced by module.
955 # An example is PCD for signature usage.
957 for DscPcd
in PlatformPcds
:
958 DscPcdEntry
= self
.Platform
.Pcds
[DscPcd
]
959 if DscPcdEntry
.Type
in [TAB_PCDS_DYNAMIC_VPD
, TAB_PCDS_DYNAMIC_EX_VPD
]:
960 if not (self
.Platform
.VpdToolGuid
== None or self
.Platform
.VpdToolGuid
== ''):
962 for VpdPcd
in VpdFile
._VpdArray
.keys():
963 # This PCD has been referenced by module
964 if (VpdPcd
.TokenSpaceGuidCName
== DscPcdEntry
.TokenSpaceGuidCName
) and \
965 (VpdPcd
.TokenCName
== DscPcdEntry
.TokenCName
):
968 # Not found, it should be signature
970 # just pick the a value to determine whether is unicode string type
971 Sku
= DscPcdEntry
.SkuInfoList
[DscPcdEntry
.SkuInfoList
.keys()[0]]
972 Sku
.VpdOffset
= Sku
.VpdOffset
.strip()
974 # Need to iterate DEC pcd information to get the value & datumtype
975 for eachDec
in self
.PackageList
:
976 for DecPcd
in eachDec
.Pcds
:
977 DecPcdEntry
= eachDec
.Pcds
[DecPcd
]
978 if (DecPcdEntry
.TokenSpaceGuidCName
== DscPcdEntry
.TokenSpaceGuidCName
) and \
979 (DecPcdEntry
.TokenCName
== DscPcdEntry
.TokenCName
):
980 # Print warning message to let the developer make a determine.
981 EdkLogger
.warn("build", "Unreferenced vpd pcd used!",
982 File
=self
.MetaFile
, \
983 ExtraData
= "PCD: %s.%s used in the DSC file %s is unreferenced." \
984 %(DscPcdEntry
.TokenSpaceGuidCName
, DscPcdEntry
.TokenCName
, self
.Platform
.MetaFile
.Path
))
986 DscPcdEntry
.DatumType
= DecPcdEntry
.DatumType
987 DscPcdEntry
.DefaultValue
= DecPcdEntry
.DefaultValue
988 # Only fix the value while no value provided in DSC file.
989 if (Sku
.DefaultValue
== "" or Sku
.DefaultValue
==None):
990 DscPcdEntry
.SkuInfoList
[DscPcdEntry
.SkuInfoList
.keys()[0]].DefaultValue
= DecPcdEntry
.DefaultValue
993 VpdFile
.Add(DscPcdEntry
, Sku
.VpdOffset
)
994 # if the offset of a VPD is *, then it need to be fixed up by third party tool.
995 if not NeedProcessVpdMapFile
and Sku
.VpdOffset
== "*":
996 NeedProcessVpdMapFile
= True
999 if (self
.Platform
.FlashDefinition
== None or self
.Platform
.FlashDefinition
== '') and \
1000 VpdFile
.GetCount() != 0:
1001 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
,
1002 "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self
.Platform
.MetaFile
))
1004 if VpdFile
.GetCount() != 0:
1005 DscTimeStamp
= self
.Platform
.MetaFile
.TimeStamp
1006 FvPath
= os
.path
.join(self
.BuildDir
, "FV")
1007 if not os
.path
.exists(FvPath
):
1011 EdkLogger
.error("build", FILE_WRITE_FAILURE
, "Fail to create FV folder under %s" % self
.BuildDir
)
1014 VpdFilePath
= os
.path
.join(FvPath
, "%s.txt" % self
.Platform
.VpdToolGuid
)
1017 if not os
.path
.exists(VpdFilePath
) or os
.path
.getmtime(VpdFilePath
) < DscTimeStamp
:
1018 VpdFile
.Write(VpdFilePath
)
1020 # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.
1022 for ToolDef
in self
.ToolDefinition
.values():
1023 if ToolDef
.has_key("GUID") and ToolDef
["GUID"] == self
.Platform
.VpdToolGuid
:
1024 if not ToolDef
.has_key("PATH"):
1025 EdkLogger
.error("build", ATTRIBUTE_NOT_AVAILABLE
, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self
.Platform
.VpdToolGuid
)
1026 BPDGToolName
= ToolDef
["PATH"]
1028 # Call third party GUID BPDG tool.
1029 if BPDGToolName
!= None:
1030 VpdInfoFile
.CallExtenalBPDGTool(BPDGToolName
, VpdFilePath
)
1032 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.")
1034 # Process VPD map file generated by third party BPDG tool
1035 if NeedProcessVpdMapFile
:
1036 VpdMapFilePath
= os
.path
.join(self
.BuildDir
, "FV", "%s.map" % self
.Platform
.VpdToolGuid
)
1037 if os
.path
.exists(VpdMapFilePath
):
1038 VpdFile
.Read(VpdMapFilePath
)
1041 for Pcd
in self
._DynamicPcdList
:
1042 # just pick the a value to determine whether is unicode string type
1043 Sku
= Pcd
.SkuInfoList
[Pcd
.SkuInfoList
.keys()[0]]
1044 if Sku
.VpdOffset
== "*":
1045 Sku
.VpdOffset
= VpdFile
.GetOffset(Pcd
)[0].strip()
1047 EdkLogger
.error("build", FILE_READ_FAILURE
, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath
)
1049 # Delete the DynamicPcdList At the last time enter into this function
1050 del self
._DynamicPcdList
[:]
1051 self
._DynamicPcdList
.extend(UnicodePcdArray
)
1052 self
._DynamicPcdList
.extend(HiiPcdArray
)
1053 self
._DynamicPcdList
.extend(OtherPcdArray
)
1056 ## Return the platform build data object
1057 def _GetPlatform(self
):
1058 if self
._Platform
== None:
1059 self
._Platform
= self
.BuildDatabase
[self
.MetaFile
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
1060 return self
._Platform
1062 ## Return platform name
1064 return self
.Platform
.PlatformName
1066 ## Return the meta file GUID
1068 return self
.Platform
.Guid
1070 ## Return the platform version
1071 def _GetVersion(self
):
1072 return self
.Platform
.Version
1074 ## Return the FDF file name
1075 def _GetFdfFile(self
):
1076 if self
._FdfFile
== None:
1077 if self
.Workspace
.FdfFile
!= "":
1078 self
._FdfFile
= path
.join(self
.WorkspaceDir
, self
.Workspace
.FdfFile
)
1081 return self
._FdfFile
1083 ## Return the build output directory platform specifies
1084 def _GetOutputDir(self
):
1085 return self
.Platform
.OutputDirectory
1087 ## Return the directory to store all intermediate and final files built
1088 def _GetBuildDir(self
):
1089 if self
._BuildDir
== None:
1090 if os
.path
.isabs(self
.OutputDir
):
1091 self
._BuildDir
= path
.join(
1092 path
.abspath(self
.OutputDir
),
1093 self
.BuildTarget
+ "_" + self
.ToolChain
,
1096 self
._BuildDir
= path
.join(
1099 self
.BuildTarget
+ "_" + self
.ToolChain
,
1101 return self
._BuildDir
1103 ## Return directory of platform makefile
1105 # @retval string Makefile directory
1107 def _GetMakeFileDir(self
):
1108 if self
._MakeFileDir
== None:
1109 self
._MakeFileDir
= path
.join(self
.BuildDir
, self
.Arch
)
1110 return self
._MakeFileDir
1112 ## Return build command string
1114 # @retval string Build command string
1116 def _GetBuildCommand(self
):
1117 if self
._BuildCommand
== None:
1118 self
._BuildCommand
= []
1119 if "MAKE" in self
.ToolDefinition
and "PATH" in self
.ToolDefinition
["MAKE"]:
1120 self
._BuildCommand
+= SplitOption(self
.ToolDefinition
["MAKE"]["PATH"])
1121 if "FLAGS" in self
.ToolDefinition
["MAKE"]:
1122 NewOption
= self
.ToolDefinition
["MAKE"]["FLAGS"].strip()
1124 self
._BuildCommand
+= SplitOption(NewOption
)
1125 return self
._BuildCommand
1127 ## Get tool chain definition
1129 # Get each tool defition for given tool chain from tools_def.txt and platform
1131 def _GetToolDefinition(self
):
1132 if self
._ToolDefinitions
== None:
1133 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDictionary
1134 if TAB_TOD_DEFINES_COMMAND_TYPE
not in self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
:
1135 EdkLogger
.error('build', RESOURCE_NOT_AVAILABLE
, "No tools found in configuration",
1136 ExtraData
="[%s]" % self
.MetaFile
)
1137 self
._ToolDefinitions
= {}
1139 for Def
in ToolDefinition
:
1140 Target
, Tag
, Arch
, Tool
, Attr
= Def
.split("_")
1141 if Target
!= self
.BuildTarget
or Tag
!= self
.ToolChain
or Arch
!= self
.Arch
:
1144 Value
= ToolDefinition
[Def
]
1145 # don't record the DLL
1147 DllPathList
.add(Value
)
1150 if Tool
not in self
._ToolDefinitions
:
1151 self
._ToolDefinitions
[Tool
] = {}
1152 self
._ToolDefinitions
[Tool
][Attr
] = Value
1156 if GlobalData
.gOptions
.SilentMode
and "MAKE" in self
._ToolDefinitions
:
1157 if "FLAGS" not in self
._ToolDefinitions
["MAKE"]:
1158 self
._ToolDefinitions
["MAKE"]["FLAGS"] = ""
1159 self
._ToolDefinitions
["MAKE"]["FLAGS"] += " -s"
1161 for Tool
in self
._ToolDefinitions
:
1162 for Attr
in self
._ToolDefinitions
[Tool
]:
1163 Value
= self
._ToolDefinitions
[Tool
][Attr
]
1164 if Tool
in self
.BuildOption
and Attr
in self
.BuildOption
[Tool
]:
1165 # check if override is indicated
1166 if self
.BuildOption
[Tool
][Attr
].startswith('='):
1167 Value
= self
.BuildOption
[Tool
][Attr
][1:]
1169 Value
+= " " + self
.BuildOption
[Tool
][Attr
]
1172 # Don't put MAKE definition in the file
1176 ToolsDef
+= "%s = %s\n" % (Tool
, Value
)
1178 # Don't put MAKE definition in the file
1183 ToolsDef
+= "%s_%s = %s\n" % (Tool
, Attr
, Value
)
1186 SaveFileOnChange(self
.ToolDefinitionFile
, ToolsDef
)
1187 for DllPath
in DllPathList
:
1188 os
.environ
["PATH"] = DllPath
+ os
.pathsep
+ os
.environ
["PATH"]
1189 os
.environ
["MAKE_FLAGS"] = MakeFlags
1191 return self
._ToolDefinitions
1193 ## Return the paths of tools
1194 def _GetToolDefFile(self
):
1195 if self
._ToolDefFile
== None:
1196 self
._ToolDefFile
= os
.path
.join(self
.MakeFileDir
, "TOOLS_DEF." + self
.Arch
)
1197 return self
._ToolDefFile
1199 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
1200 def _GetToolChainFamily(self
):
1201 if self
._ToolChainFamily
== None:
1202 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
1203 if TAB_TOD_DEFINES_FAMILY
not in ToolDefinition \
1204 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_FAMILY
] \
1205 or not ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]:
1206 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
1208 self
._ToolChainFamily
= "MSFT"
1210 self
._ToolChainFamily
= ToolDefinition
[TAB_TOD_DEFINES_FAMILY
][self
.ToolChain
]
1211 return self
._ToolChainFamily
1213 def _GetBuildRuleFamily(self
):
1214 if self
._BuildRuleFamily
== None:
1215 ToolDefinition
= self
.Workspace
.ToolDef
.ToolsDefTxtDatabase
1216 if TAB_TOD_DEFINES_BUILDRULEFAMILY
not in ToolDefinition \
1217 or self
.ToolChain
not in ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
] \
1218 or not ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]:
1219 EdkLogger
.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
1221 self
._BuildRuleFamily
= "MSFT"
1223 self
._BuildRuleFamily
= ToolDefinition
[TAB_TOD_DEFINES_BUILDRULEFAMILY
][self
.ToolChain
]
1224 return self
._BuildRuleFamily
1226 ## Return the build options specific for all modules in this platform
1227 def _GetBuildOptions(self
):
1228 if self
._BuildOption
== None:
1229 self
._BuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
)
1230 return self
._BuildOption
1232 ## Return the build options specific for EDK modules in this platform
1233 def _GetEdkBuildOptions(self
):
1234 if self
._EdkBuildOption
== None:
1235 self
._EdkBuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
, EDK_NAME
)
1236 return self
._EdkBuildOption
1238 ## Return the build options specific for EDKII modules in this platform
1239 def _GetEdkIIBuildOptions(self
):
1240 if self
._EdkIIBuildOption
== None:
1241 self
._EdkIIBuildOption
= self
._ExpandBuildOption
(self
.Platform
.BuildOptions
, EDKII_NAME
)
1242 return self
._EdkIIBuildOption
1244 ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt
1246 # @retval BuildRule object
1248 def _GetBuildRule(self
):
1249 if self
._BuildRule
== None:
1250 BuildRuleFile
= None
1251 if TAB_TAT_DEFINES_BUILD_RULE_CONF
in self
.Workspace
.TargetTxt
.TargetTxtDictionary
:
1252 BuildRuleFile
= self
.Workspace
.TargetTxt
.TargetTxtDictionary
[TAB_TAT_DEFINES_BUILD_RULE_CONF
]
1253 if BuildRuleFile
in [None, '']:
1254 BuildRuleFile
= gBuildRuleFile
1255 self
._BuildRule
= BuildRule(BuildRuleFile
)
1256 if self
._BuildRule
._FileVersion
== "":
1257 self
._BuildRule
._FileVersion
= AutoGenReqBuildRuleVerNum
1259 if self
._BuildRule
._FileVersion
< AutoGenReqBuildRuleVerNum
:
1260 # If Build Rule's version is less than the version number required by the tools, halting the build.
1261 EdkLogger
.error("build", AUTOGEN_ERROR
,
1262 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])"\
1263 % (self
._BuildRule
._FileVersion
, AutoGenReqBuildRuleVerNum
))
1265 return self
._BuildRule
1267 ## Summarize the packages used by modules in this platform
1268 def _GetPackageList(self
):
1269 if self
._PackageList
== None:
1270 self
._PackageList
= set()
1271 for La
in self
.LibraryAutoGenList
:
1272 self
._PackageList
.update(La
.DependentPackageList
)
1273 for Ma
in self
.ModuleAutoGenList
:
1274 self
._PackageList
.update(Ma
.DependentPackageList
)
1275 self
._PackageList
= list(self
._PackageList
)
1276 return self
._PackageList
1278 ## Get list of non-dynamic PCDs
1279 def _GetNonDynamicPcdList(self
):
1280 if self
._NonDynamicPcdList
== None:
1281 self
.CollectPlatformDynamicPcds()
1282 return self
._NonDynamicPcdList
1284 ## Get list of dynamic PCDs
1285 def _GetDynamicPcdList(self
):
1286 if self
._DynamicPcdList
== None:
1287 self
.CollectPlatformDynamicPcds()
1288 return self
._DynamicPcdList
1290 ## Generate Token Number for all PCD
1291 def _GetPcdTokenNumbers(self
):
1292 if self
._PcdTokenNumber
== None:
1293 self
._PcdTokenNumber
= sdict()
1296 # Make the Dynamic and DynamicEx PCD use within different TokenNumber area.
1300 # TokenNumber 0 ~ 10
1302 # TokeNumber 11 ~ 20
1304 for Pcd
in self
.DynamicPcdList
:
1305 if Pcd
.Phase
== "PEI":
1306 if Pcd
.Type
in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
1307 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
1308 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1311 for Pcd
in self
.DynamicPcdList
:
1312 if Pcd
.Phase
== "PEI":
1313 if Pcd
.Type
in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
1314 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
1315 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1318 for Pcd
in self
.DynamicPcdList
:
1319 if Pcd
.Phase
== "DXE":
1320 if Pcd
.Type
in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
1321 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
1322 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1325 for Pcd
in self
.DynamicPcdList
:
1326 if Pcd
.Phase
== "DXE":
1327 if Pcd
.Type
in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
1328 EdkLogger
.debug(EdkLogger
.DEBUG_5
, "%s %s (%s) -> %d" % (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, Pcd
.Phase
, TokenNumber
))
1329 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1332 for Pcd
in self
.NonDynamicPcdList
:
1333 self
._PcdTokenNumber
[Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
] = TokenNumber
1335 return self
._PcdTokenNumber
1337 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
1338 def _GetAutoGenObjectList(self
):
1339 self
._ModuleAutoGenList
= []
1340 self
._LibraryAutoGenList
= []
1341 for ModuleFile
in self
.Platform
.Modules
:
1350 if Ma
not in self
._ModuleAutoGenList
:
1351 self
._ModuleAutoGenList
.append(Ma
)
1352 for La
in Ma
.LibraryAutoGenList
:
1353 if La
not in self
._LibraryAutoGenList
:
1354 self
._LibraryAutoGenList
.append(La
)
1356 ## Summarize ModuleAutoGen objects of all modules to be built for this platform
1357 def _GetModuleAutoGenList(self
):
1358 if self
._ModuleAutoGenList
== None:
1359 self
._GetAutoGenObjectList
()
1360 return self
._ModuleAutoGenList
1362 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
1363 def _GetLibraryAutoGenList(self
):
1364 if self
._LibraryAutoGenList
== None:
1365 self
._GetAutoGenObjectList
()
1366 return self
._LibraryAutoGenList
1368 ## Test if a module is supported by the platform
1370 # An error will be raised directly if the module or its arch is not supported
1371 # by the platform or current configuration
1373 def ValidModule(self
, Module
):
1374 return Module
in self
.Platform
.Modules
or Module
in self
.Platform
.LibraryInstances
1376 ## Resolve the library classes in a module to library instances
1378 # This method will not only resolve library classes but also sort the library
1379 # instances according to the dependency-ship.
1381 # @param Module The module from which the library classes will be resolved
1383 # @retval library_list List of library instances sorted
1385 def ApplyLibraryInstance(self
, Module
):
1386 ModuleType
= Module
.ModuleType
1388 # for overridding library instances with module specific setting
1389 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1391 # add forced library instances (specified under LibraryClasses sections)
1393 # If a module has a MODULE_TYPE of USER_DEFINED,
1394 # do not link in NULL library class instances from the global [LibraryClasses.*] sections.
1396 if Module
.ModuleType
!= SUP_MODULE_USER_DEFINED
:
1397 for LibraryClass
in self
.Platform
.LibraryClasses
.GetKeys():
1398 if LibraryClass
.startswith("NULL") and self
.Platform
.LibraryClasses
[LibraryClass
, Module
.ModuleType
]:
1399 Module
.LibraryClasses
[LibraryClass
] = self
.Platform
.LibraryClasses
[LibraryClass
, Module
.ModuleType
]
1401 # add forced library instances (specified in module overrides)
1402 for LibraryClass
in PlatformModule
.LibraryClasses
:
1403 if LibraryClass
.startswith("NULL"):
1404 Module
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
1407 LibraryConsumerList
= [Module
]
1409 ConsumedByList
= sdict()
1410 LibraryInstance
= sdict()
1412 EdkLogger
.verbose("")
1413 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
1414 while len(LibraryConsumerList
) > 0:
1415 M
= LibraryConsumerList
.pop()
1416 for LibraryClassName
in M
.LibraryClasses
:
1417 if LibraryClassName
not in LibraryInstance
:
1418 # override library instance for this module
1419 if LibraryClassName
in PlatformModule
.LibraryClasses
:
1420 LibraryPath
= PlatformModule
.LibraryClasses
[LibraryClassName
]
1422 LibraryPath
= self
.Platform
.LibraryClasses
[LibraryClassName
, ModuleType
]
1423 if LibraryPath
== None or LibraryPath
== "":
1424 LibraryPath
= M
.LibraryClasses
[LibraryClassName
]
1425 if LibraryPath
== None or LibraryPath
== "":
1426 EdkLogger
.error("build", RESOURCE_NOT_AVAILABLE
,
1427 "Instance of library class [%s] is not found" % LibraryClassName
,
1429 ExtraData
="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M
), self
.Arch
, str(Module
)))
1431 LibraryModule
= self
.BuildDatabase
[LibraryPath
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
1432 # for those forced library instance (NULL library), add a fake library class
1433 if LibraryClassName
.startswith("NULL"):
1434 LibraryModule
.LibraryClass
.append(LibraryClassObject(LibraryClassName
, [ModuleType
]))
1435 elif LibraryModule
.LibraryClass
== None \
1436 or len(LibraryModule
.LibraryClass
) == 0 \
1437 or (ModuleType
!= 'USER_DEFINED'
1438 and ModuleType
not in LibraryModule
.LibraryClass
[0].SupModList
):
1439 # only USER_DEFINED can link against any library instance despite of its SupModList
1440 EdkLogger
.error("build", OPTION_MISSING
,
1441 "Module type [%s] is not supported by library instance [%s]" \
1442 % (ModuleType
, LibraryPath
), File
=self
.MetaFile
,
1443 ExtraData
="consumed by [%s]" % str(Module
))
1445 LibraryInstance
[LibraryClassName
] = LibraryModule
1446 LibraryConsumerList
.append(LibraryModule
)
1447 EdkLogger
.verbose("\t" + str(LibraryClassName
) + " : " + str(LibraryModule
))
1449 LibraryModule
= LibraryInstance
[LibraryClassName
]
1451 if LibraryModule
== None:
1454 if LibraryModule
.ConstructorList
!= [] and LibraryModule
not in Constructor
:
1455 Constructor
.append(LibraryModule
)
1457 if LibraryModule
not in ConsumedByList
:
1458 ConsumedByList
[LibraryModule
] = []
1459 # don't add current module itself to consumer list
1461 if M
in ConsumedByList
[LibraryModule
]:
1463 ConsumedByList
[LibraryModule
].append(M
)
1465 # Initialize the sorted output list to the empty set
1467 SortedLibraryList
= []
1469 # Q <- Set of all nodes with no incoming edges
1471 LibraryList
= [] #LibraryInstance.values()
1473 for LibraryClassName
in LibraryInstance
:
1474 M
= LibraryInstance
[LibraryClassName
]
1475 LibraryList
.append(M
)
1476 if ConsumedByList
[M
] == []:
1480 # start the DAG algorithm
1484 while Q
== [] and EdgeRemoved
:
1486 # for each node Item with a Constructor
1487 for Item
in LibraryList
:
1488 if Item
not in Constructor
:
1490 # for each Node without a constructor with an edge e from Item to Node
1491 for Node
in ConsumedByList
[Item
]:
1492 if Node
in Constructor
:
1494 # remove edge e from the graph if Node has no constructor
1495 ConsumedByList
[Item
].remove(Node
)
1497 if ConsumedByList
[Item
] == []:
1498 # insert Item into Q
1503 # DAG is done if there's no more incoming edge for all nodes
1507 # remove node from Q
1510 SortedLibraryList
.append(Node
)
1512 # for each node Item with an edge e from Node to Item do
1513 for Item
in LibraryList
:
1514 if Node
not in ConsumedByList
[Item
]:
1516 # remove edge e from the graph
1517 ConsumedByList
[Item
].remove(Node
)
1519 if ConsumedByList
[Item
] != []:
1521 # insert Item into Q, if Item has no other incoming edges
1525 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
1527 for Item
in LibraryList
:
1528 if ConsumedByList
[Item
] != [] and Item
in Constructor
and len(Constructor
) > 1:
1529 ErrorMessage
= "\tconsumed by " + "\n\tconsumed by ".join([str(L
) for L
in ConsumedByList
[Item
]])
1530 EdkLogger
.error("build", BUILD_ERROR
, 'Library [%s] with constructors has a cycle' % str(Item
),
1531 ExtraData
=ErrorMessage
, File
=self
.MetaFile
)
1532 if Item
not in SortedLibraryList
:
1533 SortedLibraryList
.append(Item
)
1536 # Build the list of constructor and destructir names
1537 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
1539 SortedLibraryList
.reverse()
1540 return SortedLibraryList
1543 ## Override PCD setting (type, value, ...)
1545 # @param ToPcd The PCD to be overrided
1546 # @param FromPcd The PCD overrideing from
1548 def _OverridePcd(self
, ToPcd
, FromPcd
, Module
=""):
1550 # in case there's PCDs coming from FDF file, which have no type given.
1551 # at this point, ToPcd.Type has the type found from dependent
1555 if ToPcd
.Pending
and FromPcd
.Type
not in [None, '']:
1556 ToPcd
.Type
= FromPcd
.Type
1557 elif (ToPcd
.Type
not in [None, '']) and (FromPcd
.Type
not in [None, ''])\
1558 and (ToPcd
.Type
!= FromPcd
.Type
) and (ToPcd
.Type
in FromPcd
.Type
):
1559 if ToPcd
.Type
.strip() == "DynamicEx":
1560 ToPcd
.Type
= FromPcd
.Type
1561 elif ToPcd
.Type
not in [None, ''] and FromPcd
.Type
not in [None, ''] \
1562 and ToPcd
.Type
!= FromPcd
.Type
:
1563 EdkLogger
.error("build", OPTION_CONFLICT
, "Mismatched PCD type",
1564 ExtraData
="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
1565 % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
,
1566 ToPcd
.Type
, Module
, FromPcd
.Type
),
1569 if FromPcd
.MaxDatumSize
not in [None, '']:
1570 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
1571 if FromPcd
.DefaultValue
not in [None, '']:
1572 ToPcd
.DefaultValue
= FromPcd
.DefaultValue
1573 if FromPcd
.TokenValue
not in [None, '']:
1574 ToPcd
.TokenValue
= FromPcd
.TokenValue
1575 if FromPcd
.MaxDatumSize
not in [None, '']:
1576 ToPcd
.MaxDatumSize
= FromPcd
.MaxDatumSize
1577 if FromPcd
.DatumType
not in [None, '']:
1578 ToPcd
.DatumType
= FromPcd
.DatumType
1579 if FromPcd
.SkuInfoList
not in [None, '', []]:
1580 ToPcd
.SkuInfoList
= FromPcd
.SkuInfoList
1582 # check the validation of datum
1583 IsValid
, Cause
= CheckPcdDatum(ToPcd
.DatumType
, ToPcd
.DefaultValue
)
1585 EdkLogger
.error('build', FORMAT_INVALID
, Cause
, File
=self
.MetaFile
,
1586 ExtraData
="%s.%s" % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
))
1588 if ToPcd
.DatumType
== "VOID*" and ToPcd
.MaxDatumSize
in ['', None]:
1589 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "No MaxDatumSize specified for PCD %s.%s" \
1590 % (ToPcd
.TokenSpaceGuidCName
, ToPcd
.TokenCName
))
1591 Value
= ToPcd
.DefaultValue
1592 if Value
in [None, '']:
1593 ToPcd
.MaxDatumSize
= 1
1594 elif Value
[0] == 'L':
1595 ToPcd
.MaxDatumSize
= str(len(Value
) * 2)
1596 elif Value
[0] == '{':
1597 ToPcd
.MaxDatumSize
= str(len(Value
.split(',')))
1599 ToPcd
.MaxDatumSize
= str(len(Value
))
1601 # apply default SKU for dynamic PCDS if specified one is not available
1602 if (ToPcd
.Type
in PCD_DYNAMIC_TYPE_LIST
or ToPcd
.Type
in PCD_DYNAMIC_EX_TYPE_LIST
) \
1603 and ToPcd
.SkuInfoList
in [None, {}, '']:
1604 if self
.Platform
.SkuName
in self
.Platform
.SkuIds
:
1605 SkuName
= self
.Platform
.SkuName
1608 ToPcd
.SkuInfoList
= {
1609 SkuName
: SkuInfoClass(SkuName
, self
.Platform
.SkuIds
[SkuName
], '', '', '', '', '', ToPcd
.DefaultValue
)
1612 ## Apply PCD setting defined platform to a module
1614 # @param Module The module from which the PCD setting will be overrided
1616 # @retval PCD_list The list PCDs with settings from platform
1618 def ApplyPcdSetting(self
, Module
, Pcds
):
1619 # for each PCD in module
1620 for Name
,Guid
in Pcds
:
1621 PcdInModule
= Pcds
[Name
,Guid
]
1622 # find out the PCD setting in platform
1623 if (Name
,Guid
) in self
.Platform
.Pcds
:
1624 PcdInPlatform
= self
.Platform
.Pcds
[Name
,Guid
]
1626 PcdInPlatform
= None
1627 # then override the settings if any
1628 self
._OverridePcd
(PcdInModule
, PcdInPlatform
, Module
)
1629 # resolve the VariableGuid value
1630 for SkuId
in PcdInModule
.SkuInfoList
:
1631 Sku
= PcdInModule
.SkuInfoList
[SkuId
]
1632 if Sku
.VariableGuid
== '': continue
1633 Sku
.VariableGuidValue
= GuidValue(Sku
.VariableGuid
, self
.PackageList
)
1634 if Sku
.VariableGuidValue
== None:
1635 PackageList
= "\n\t".join([str(P
) for P
in self
.PackageList
])
1638 RESOURCE_NOT_AVAILABLE
,
1639 "Value of GUID [%s] is not found in" % Sku
.VariableGuid
,
1640 ExtraData
=PackageList
+ "\n\t(used with %s.%s from module %s)" \
1641 % (Guid
, Name
, str(Module
)),
1645 # override PCD settings with module specific setting
1646 if Module
in self
.Platform
.Modules
:
1647 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1648 for Key
in PlatformModule
.Pcds
:
1650 self
._OverridePcd
(Pcds
[Key
], PlatformModule
.Pcds
[Key
], Module
)
1651 return Pcds
.values()
1653 ## Resolve library names to library modules
1655 # (for Edk.x modules)
1657 # @param Module The module from which the library names will be resolved
1659 # @retval library_list The list of library modules
1661 def ResolveLibraryReference(self
, Module
):
1662 EdkLogger
.verbose("")
1663 EdkLogger
.verbose("Library instances of module [%s] [%s]:" % (str(Module
), self
.Arch
))
1664 LibraryConsumerList
= [Module
]
1666 # "CompilerStub" is a must for Edk modules
1667 if Module
.Libraries
:
1668 Module
.Libraries
.append("CompilerStub")
1670 while len(LibraryConsumerList
) > 0:
1671 M
= LibraryConsumerList
.pop()
1672 for LibraryName
in M
.Libraries
:
1673 Library
= self
.Platform
.LibraryClasses
[LibraryName
, ':dummy:']
1675 for Key
in self
.Platform
.LibraryClasses
.data
.keys():
1676 if LibraryName
.upper() == Key
.upper():
1677 Library
= self
.Platform
.LibraryClasses
[Key
, ':dummy:']
1680 EdkLogger
.warn("build", "Library [%s] is not found" % LibraryName
, File
=str(M
),
1681 ExtraData
="\t%s [%s]" % (str(Module
), self
.Arch
))
1684 if Library
not in LibraryList
:
1685 LibraryList
.append(Library
)
1686 LibraryConsumerList
.append(Library
)
1687 EdkLogger
.verbose("\t" + LibraryName
+ " : " + str(Library
) + ' ' + str(type(Library
)))
1690 ## Calculate the priority value of the build option
1692 # @param Key Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
1694 # @retval Value Priority value based on the priority list.
1696 def CalculatePriorityValue(self
, Key
):
1697 Target
, ToolChain
, Arch
, CommandType
, Attr
= Key
.split('_')
1698 PriorityValue
= 0x11111
1700 PriorityValue
&= 0x01111
1701 if ToolChain
== "*":
1702 PriorityValue
&= 0x10111
1704 PriorityValue
&= 0x11011
1705 if CommandType
== "*":
1706 PriorityValue
&= 0x11101
1708 PriorityValue
&= 0x11110
1710 return self
.PrioList
["0x%0.5x"%PriorityValue
]
1713 ## Expand * in build option key
1715 # @param Options Options to be expanded
1717 # @retval options Options expanded
1719 def _ExpandBuildOption(self
, Options
, ModuleStyle
=None):
1726 # Construct a list contain the build options which need override.
1730 # Key[0] -- tool family
1731 # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE
1733 if Key
[0] == self
.BuildRuleFamily
:
1734 Target
, ToolChain
, Arch
, CommandType
, Attr
= Key
[1].split('_')
1735 if Target
== self
.BuildTarget
or Target
== "*":
1736 if ToolChain
== self
.ToolChain
or ToolChain
== "*":
1737 if Arch
== self
.Arch
or Arch
== "*":
1738 if Options
[Key
].startswith("="):
1739 if OverrideList
.get(Key
[1]) != None:
1740 OverrideList
.pop(Key
[1])
1741 OverrideList
[Key
[1]] = Options
[Key
]
1744 # Use the highest priority value.
1746 if (len(OverrideList
) >= 2):
1747 KeyList
= OverrideList
.keys()
1748 for Index
in range(len(KeyList
)):
1749 NowKey
= KeyList
[Index
]
1750 Target1
, ToolChain1
, Arch1
, CommandType1
, Attr1
= NowKey
.split("_")
1751 for Index1
in range(len(KeyList
) - Index
- 1):
1752 NextKey
= KeyList
[Index1
+ Index
+ 1]
1754 # Compare two Key, if one is included by another, choose the higher priority one
1756 Target2
, ToolChain2
, Arch2
, CommandType2
, Attr2
= NextKey
.split("_")
1757 if Target1
== Target2
or Target1
== "*" or Target2
== "*":
1758 if ToolChain1
== ToolChain2
or ToolChain1
== "*" or ToolChain2
== "*":
1759 if Arch1
== Arch2
or Arch1
== "*" or Arch2
== "*":
1760 if CommandType1
== CommandType2
or CommandType1
== "*" or CommandType2
== "*":
1761 if Attr1
== Attr2
or Attr1
== "*" or Attr2
== "*":
1762 if self
.CalculatePriorityValue(NowKey
) > self
.CalculatePriorityValue(NextKey
):
1763 if Options
.get((self
.BuildRuleFamily
, NextKey
)) != None:
1764 Options
.pop((self
.BuildRuleFamily
, NextKey
))
1766 if Options
.get((self
.BuildRuleFamily
, NowKey
)) != None:
1767 Options
.pop((self
.BuildRuleFamily
, NowKey
))
1771 if ModuleStyle
!= None and len (Key
) > 2:
1772 # Check Module style is EDK or EDKII.
1773 # Only append build option for the matched style module.
1774 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
1776 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
1779 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
1780 # if tool chain family doesn't match, skip it
1781 if Tool
in self
.ToolDefinition
and Family
!= "":
1782 FamilyIsNull
= False
1783 if self
.ToolDefinition
[Tool
].get(TAB_TOD_DEFINES_BUILDRULEFAMILY
, "") != "":
1784 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_BUILDRULEFAMILY
]:
1786 elif Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
1789 # expand any wildcard
1790 if Target
== "*" or Target
== self
.BuildTarget
:
1791 if Tag
== "*" or Tag
== self
.ToolChain
:
1792 if Arch
== "*" or Arch
== self
.Arch
:
1793 if Tool
not in BuildOptions
:
1794 BuildOptions
[Tool
] = {}
1795 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
]:
1796 BuildOptions
[Tool
][Attr
] = Options
[Key
]
1798 # append options for the same tool
1799 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
1800 # Build Option Family has been checked, which need't to be checked again for family.
1801 if FamilyMatch
or FamilyIsNull
:
1805 if ModuleStyle
!= None and len (Key
) > 2:
1806 # Check Module style is EDK or EDKII.
1807 # Only append build option for the matched style module.
1808 if ModuleStyle
== EDK_NAME
and Key
[2] != EDK_NAME
:
1810 elif ModuleStyle
== EDKII_NAME
and Key
[2] != EDKII_NAME
:
1813 Target
, Tag
, Arch
, Tool
, Attr
= Key
[1].split("_")
1814 # if tool chain family doesn't match, skip it
1815 if Tool
not in self
.ToolDefinition
or Family
=="":
1817 # option has been added before
1818 if Family
!= self
.ToolDefinition
[Tool
][TAB_TOD_DEFINES_FAMILY
]:
1821 # expand any wildcard
1822 if Target
== "*" or Target
== self
.BuildTarget
:
1823 if Tag
== "*" or Tag
== self
.ToolChain
:
1824 if Arch
== "*" or Arch
== self
.Arch
:
1825 if Tool
not in BuildOptions
:
1826 BuildOptions
[Tool
] = {}
1827 if Attr
!= "FLAGS" or Attr
not in BuildOptions
[Tool
]:
1828 BuildOptions
[Tool
][Attr
] = Options
[Key
]
1830 # append options for the same tool
1831 BuildOptions
[Tool
][Attr
] += " " + Options
[Key
]
1834 ## Append build options in platform to a module
1836 # @param Module The module to which the build options will be appened
1838 # @retval options The options appended with build options in platform
1840 def ApplyBuildOption(self
, Module
):
1841 # Get the different options for the different style module
1842 if Module
.AutoGenVersion
< 0x00010005:
1843 PlatformOptions
= self
.EdkBuildOption
1845 PlatformOptions
= self
.EdkIIBuildOption
1846 ModuleOptions
= self
._ExpandBuildOption
(Module
.BuildOptions
)
1847 if Module
in self
.Platform
.Modules
:
1848 PlatformModule
= self
.Platform
.Modules
[str(Module
)]
1849 PlatformModuleOptions
= self
._ExpandBuildOption
(PlatformModule
.BuildOptions
)
1851 PlatformModuleOptions
= {}
1853 AllTools
= set(ModuleOptions
.keys() + PlatformOptions
.keys() + PlatformModuleOptions
.keys() + self
.ToolDefinition
.keys())
1855 for Tool
in AllTools
:
1856 if Tool
not in BuildOptions
:
1857 BuildOptions
[Tool
] = {}
1859 for Options
in [self
.ToolDefinition
, ModuleOptions
, PlatformOptions
, PlatformModuleOptions
]:
1860 if Tool
not in Options
:
1862 for Attr
in Options
[Tool
]:
1863 Value
= Options
[Tool
][Attr
]
1864 if Attr
not in BuildOptions
[Tool
]:
1865 BuildOptions
[Tool
][Attr
] = ""
1866 # check if override is indicated
1867 if Value
.startswith('='):
1868 BuildOptions
[Tool
][Attr
] = Value
[1:]
1870 BuildOptions
[Tool
][Attr
] += " " + Value
1871 if Module
.AutoGenVersion
< 0x00010005 and self
.Workspace
.UniFlag
!= None:
1873 # Override UNI flag only for EDK module.
1875 if 'BUILD' not in BuildOptions
:
1876 BuildOptions
['BUILD'] = {}
1877 BuildOptions
['BUILD']['FLAGS'] = self
.Workspace
.UniFlag
1880 Platform
= property(_GetPlatform
)
1881 Name
= property(_GetName
)
1882 Guid
= property(_GetGuid
)
1883 Version
= property(_GetVersion
)
1885 OutputDir
= property(_GetOutputDir
)
1886 BuildDir
= property(_GetBuildDir
)
1887 MakeFileDir
= property(_GetMakeFileDir
)
1888 FdfFile
= property(_GetFdfFile
)
1890 PcdTokenNumber
= property(_GetPcdTokenNumbers
) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
1891 DynamicPcdList
= property(_GetDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1892 NonDynamicPcdList
= property(_GetNonDynamicPcdList
) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1893 PackageList
= property(_GetPackageList
)
1895 ToolDefinition
= property(_GetToolDefinition
) # toolcode : tool path
1896 ToolDefinitionFile
= property(_GetToolDefFile
) # toolcode : lib path
1897 ToolChainFamily
= property(_GetToolChainFamily
)
1898 BuildRuleFamily
= property(_GetBuildRuleFamily
)
1899 BuildOption
= property(_GetBuildOptions
) # toolcode : option
1900 EdkBuildOption
= property(_GetEdkBuildOptions
) # edktoolcode : option
1901 EdkIIBuildOption
= property(_GetEdkIIBuildOptions
) # edkiitoolcode : option
1903 BuildCommand
= property(_GetBuildCommand
)
1904 BuildRule
= property(_GetBuildRule
)
1905 ModuleAutoGenList
= property(_GetModuleAutoGenList
)
1906 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
1908 ## ModuleAutoGen class
1910 # This class encapsules the AutoGen behaviors for the build tools. In addition to
1911 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
1912 # to the [depex] section in module's inf file.
1914 class ModuleAutoGen(AutoGen
):
1915 ## The real constructor of ModuleAutoGen
1917 # This method is not supposed to be called by users of ModuleAutoGen. It's
1918 # only used by factory method __new__() to do real initialization work for an
1919 # object of ModuleAutoGen
1921 # @param Workspace EdkIIWorkspaceBuild object
1922 # @param ModuleFile The path of module file
1923 # @param Target Build target (DEBUG, RELEASE)
1924 # @param Toolchain Name of tool chain
1925 # @param Arch The arch the module supports
1926 # @param PlatformFile Platform meta-file
1928 def _Init(self
, Workspace
, ModuleFile
, Target
, Toolchain
, Arch
, PlatformFile
):
1929 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "AutoGen module [%s] [%s]" % (ModuleFile
, Arch
))
1930 GlobalData
.gProcessingFile
= "%s [%s, %s, %s]" % (ModuleFile
, Arch
, Toolchain
, Target
)
1932 self
.Workspace
= Workspace
1933 self
.WorkspaceDir
= Workspace
.WorkspaceDir
1935 self
.MetaFile
= ModuleFile
1936 self
.PlatformInfo
= PlatformAutoGen(Workspace
, PlatformFile
, Target
, Toolchain
, Arch
)
1937 # check if this module is employed by active platform
1938 if not self
.PlatformInfo
.ValidModule(self
.MetaFile
):
1939 EdkLogger
.verbose("Module [%s] for [%s] is not employed by active platform\n" \
1940 % (self
.MetaFile
, Arch
))
1943 self
.SourceDir
= self
.MetaFile
.SubDir
1944 self
.SourceOverrideDir
= None
1945 # use overrided path defined in DSC file
1946 if self
.MetaFile
.Key
in GlobalData
.gOverrideDir
:
1947 self
.SourceOverrideDir
= GlobalData
.gOverrideDir
[self
.MetaFile
.Key
]
1949 self
.ToolChain
= Toolchain
1950 self
.BuildTarget
= Target
1952 self
.ToolChainFamily
= self
.PlatformInfo
.ToolChainFamily
1953 self
.BuildRuleFamily
= self
.PlatformInfo
.BuildRuleFamily
1955 self
.IsMakeFileCreated
= False
1956 self
.IsCodeFileCreated
= False
1957 self
.IsAsBuiltInfCreated
= False
1958 self
.DepexGenerated
= False
1960 self
.BuildDatabase
= self
.Workspace
.BuildDatabase
1965 self
._Version
= None
1966 self
._ModuleType
= None
1967 self
._ComponentType
= None
1968 self
._PcdIsDriver
= None
1969 self
._AutoGenVersion
= None
1970 self
._LibraryFlag
= None
1971 self
._CustomMakefile
= None
1974 self
._BuildDir
= None
1975 self
._OutputDir
= None
1976 self
._DebugDir
= None
1977 self
._MakeFileDir
= None
1979 self
._IncludePathList
= None
1980 self
._AutoGenFileList
= None
1981 self
._UnicodeFileList
= None
1982 self
._SourceFileList
= None
1983 self
._ObjectFileList
= None
1984 self
._BinaryFileList
= None
1986 self
._DependentPackageList
= None
1987 self
._DependentLibraryList
= None
1988 self
._LibraryAutoGenList
= None
1989 self
._DerivedPackageList
= None
1990 self
._ModulePcdList
= None
1991 self
._LibraryPcdList
= None
1992 self
._GuidList
= None
1993 self
._ProtocolList
= None
1994 self
._PpiList
= None
1995 self
._DepexList
= None
1996 self
._DepexExpressionList
= None
1997 self
._BuildOption
= None
1998 self
._BuildOptionIncPathList
= None
1999 self
._BuildTargets
= None
2000 self
._IntroBuildTargetList
= None
2001 self
._FinalBuildTargetList
= None
2002 self
._FileTypes
= None
2003 self
._BuildRules
= None
2008 return "%s [%s]" % (self
.MetaFile
, self
.Arch
)
2010 # Macros could be used in build_rule.txt (also Makefile)
2011 def _GetMacros(self
):
2012 if self
._Macro
== None:
2013 self
._Macro
= sdict()
2014 self
._Macro
["WORKSPACE" ] = self
.WorkspaceDir
2015 self
._Macro
["MODULE_NAME" ] = self
.Name
2016 self
._Macro
["MODULE_GUID" ] = self
.Guid
2017 self
._Macro
["MODULE_VERSION" ] = self
.Version
2018 self
._Macro
["MODULE_TYPE" ] = self
.ModuleType
2019 self
._Macro
["MODULE_FILE" ] = str(self
.MetaFile
)
2020 self
._Macro
["MODULE_FILE_BASE_NAME" ] = self
.MetaFile
.BaseName
2021 self
._Macro
["MODULE_RELATIVE_DIR" ] = self
.SourceDir
2022 self
._Macro
["MODULE_DIR" ] = self
.SourceDir
2024 self
._Macro
["BASE_NAME" ] = self
.Name
2026 self
._Macro
["ARCH" ] = self
.Arch
2027 self
._Macro
["TOOLCHAIN" ] = self
.ToolChain
2028 self
._Macro
["TOOLCHAIN_TAG" ] = self
.ToolChain
2029 self
._Macro
["TOOL_CHAIN_TAG" ] = self
.ToolChain
2030 self
._Macro
["TARGET" ] = self
.BuildTarget
2032 self
._Macro
["BUILD_DIR" ] = self
.PlatformInfo
.BuildDir
2033 self
._Macro
["BIN_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
2034 self
._Macro
["LIB_DIR" ] = os
.path
.join(self
.PlatformInfo
.BuildDir
, self
.Arch
)
2035 self
._Macro
["MODULE_BUILD_DIR" ] = self
.BuildDir
2036 self
._Macro
["OUTPUT_DIR" ] = self
.OutputDir
2037 self
._Macro
["DEBUG_DIR" ] = self
.DebugDir
2040 ## Return the module build data object
2041 def _GetModule(self
):
2042 if self
._Module
== None:
2043 self
._Module
= self
.Workspace
.BuildDatabase
[self
.MetaFile
, self
.Arch
, self
.BuildTarget
, self
.ToolChain
]
2046 ## Return the module name
2047 def _GetBaseName(self
):
2048 return self
.Module
.BaseName
2050 ## Return the module DxsFile if exist
2051 def _GetDxsFile(self
):
2052 return self
.Module
.DxsFile
2054 ## Return the module SourceOverridePath
2055 def _GetSourceOverridePath(self
):
2056 return self
.Module
.SourceOverridePath
2058 ## Return the module meta-file GUID
2060 return self
.Module
.Guid
2062 ## Return the module version
2063 def _GetVersion(self
):
2064 return self
.Module
.Version
2066 ## Return the module type
2067 def _GetModuleType(self
):
2068 return self
.Module
.ModuleType
2070 ## Return the component type (for Edk.x style of module)
2071 def _GetComponentType(self
):
2072 return self
.Module
.ComponentType
2074 ## Return the build type
2075 def _GetBuildType(self
):
2076 return self
.Module
.BuildType
2078 ## Return the PCD_IS_DRIVER setting
2079 def _GetPcdIsDriver(self
):
2080 return self
.Module
.PcdIsDriver
2082 ## Return the autogen version, i.e. module meta-file version
2083 def _GetAutoGenVersion(self
):
2084 return self
.Module
.AutoGenVersion
2086 ## Check if the module is library or not
2087 def _IsLibrary(self
):
2088 if self
._LibraryFlag
== None:
2089 if self
.Module
.LibraryClass
!= None and self
.Module
.LibraryClass
!= []:
2090 self
._LibraryFlag
= True
2092 self
._LibraryFlag
= False
2093 return self
._LibraryFlag
2095 ## Return the directory to store intermediate files of the module
2096 def _GetBuildDir(self
):
2097 if self
._BuildDir
== None:
2098 self
._BuildDir
= path
.join(
2099 self
.PlatformInfo
.BuildDir
,
2102 self
.MetaFile
.BaseName
2104 CreateDirectory(self
._BuildDir
)
2105 return self
._BuildDir
2107 ## Return the directory to store the intermediate object files of the mdoule
2108 def _GetOutputDir(self
):
2109 if self
._OutputDir
== None:
2110 self
._OutputDir
= path
.join(self
.BuildDir
, "OUTPUT")
2111 CreateDirectory(self
._OutputDir
)
2112 return self
._OutputDir
2114 ## Return the directory to store auto-gened source files of the mdoule
2115 def _GetDebugDir(self
):
2116 if self
._DebugDir
== None:
2117 self
._DebugDir
= path
.join(self
.BuildDir
, "DEBUG")
2118 CreateDirectory(self
._DebugDir
)
2119 return self
._DebugDir
2121 ## Return the path of custom file
2122 def _GetCustomMakefile(self
):
2123 if self
._CustomMakefile
== None:
2124 self
._CustomMakefile
= {}
2125 for Type
in self
.Module
.CustomMakefile
:
2126 if Type
in gMakeTypeMap
:
2127 MakeType
= gMakeTypeMap
[Type
]
2130 if self
.SourceOverrideDir
!= None:
2131 File
= os
.path
.join(self
.SourceOverrideDir
, self
.Module
.CustomMakefile
[Type
])
2132 if not os
.path
.exists(File
):
2133 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
2135 File
= os
.path
.join(self
.SourceDir
, self
.Module
.CustomMakefile
[Type
])
2136 self
._CustomMakefile
[MakeType
] = File
2137 return self
._CustomMakefile
2139 ## Return the directory of the makefile
2141 # @retval string The directory string of module's makefile
2143 def _GetMakeFileDir(self
):
2144 return self
.BuildDir
2146 ## Return build command string
2148 # @retval string Build command string
2150 def _GetBuildCommand(self
):
2151 return self
.PlatformInfo
.BuildCommand
2153 ## Get object list of all packages the module and its dependent libraries belong to
2155 # @retval list The list of package object
2157 def _GetDerivedPackageList(self
):
2159 for M
in [self
.Module
] + self
.DependentLibraryList
:
2160 for Package
in M
.Packages
:
2161 if Package
in PackageList
:
2163 PackageList
.append(Package
)
2166 ## Merge dependency expression
2168 # @retval list The token list of the dependency expression after parsed
2170 def _GetDepexTokenList(self
):
2171 if self
._DepexList
== None:
2172 self
._DepexList
= {}
2173 if self
.DxsFile
or self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
2174 return self
._DepexList
2176 self
._DepexList
[self
.ModuleType
] = []
2178 for ModuleType
in self
._DepexList
:
2179 DepexList
= self
._DepexList
[ModuleType
]
2181 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
2183 for M
in [self
.Module
] + self
.DependentLibraryList
:
2185 for D
in M
.Depex
[self
.Arch
, ModuleType
]:
2187 DepexList
.append('AND')
2188 DepexList
.append('(')
2190 if DepexList
[-1] == 'END': # no need of a END at this time
2192 DepexList
.append(')')
2195 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexList
))
2196 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
2198 if len(DepexList
) > 0:
2199 EdkLogger
.verbose('')
2200 return self
._DepexList
2202 ## Merge dependency expression
2204 # @retval list The token list of the dependency expression after parsed
2206 def _GetDepexExpressionTokenList(self
):
2207 if self
._DepexExpressionList
== None:
2208 self
._DepexExpressionList
= {}
2209 if self
.DxsFile
or self
.IsLibrary
or TAB_DEPENDENCY_EXPRESSION_FILE
in self
.FileTypes
:
2210 return self
._DepexExpressionList
2212 self
._DepexExpressionList
[self
.ModuleType
] = ''
2214 for ModuleType
in self
._DepexExpressionList
:
2215 DepexExpressionList
= self
._DepexExpressionList
[ModuleType
]
2217 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
2219 for M
in [self
.Module
] + self
.DependentLibraryList
:
2221 for D
in M
.DepexExpression
[self
.Arch
, ModuleType
]:
2222 if DepexExpressionList
!= '':
2223 DepexExpressionList
+= ' AND '
2224 DepexExpressionList
+= '('
2225 DepexExpressionList
+= D
2226 DepexExpressionList
= DepexExpressionList
.rstrip('END').strip()
2227 DepexExpressionList
+= ')'
2230 EdkLogger
.verbose("DEPEX[%s] (+%s) = %s" % (self
.Name
, M
.BaseName
, DepexExpressionList
))
2231 if 'BEFORE' in DepexExpressionList
or 'AFTER' in DepexExpressionList
:
2233 if len(DepexExpressionList
) > 0:
2234 EdkLogger
.verbose('')
2235 self
._DepexExpressionList
[ModuleType
] = DepexExpressionList
2236 return self
._DepexExpressionList
2238 ## Return the list of specification version required for the module
2240 # @retval list The list of specification defined in module file
2242 def _GetSpecification(self
):
2243 return self
.Module
.Specification
2245 ## Tool option for the module build
2247 # @param PlatformInfo The object of PlatformBuildInfo
2248 # @retval dict The dict containing valid options
2250 def _GetModuleBuildOption(self
):
2251 if self
._BuildOption
== None:
2252 self
._BuildOption
= self
.PlatformInfo
.ApplyBuildOption(self
.Module
)
2253 return self
._BuildOption
2255 ## Get include path list from tool option for the module build
2257 # @retval list The include path list
2259 def _GetBuildOptionIncPathList(self
):
2260 if self
._BuildOptionIncPathList
== None:
2262 # Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT
2263 # is the former use /I , the Latter used -I to specify include directories
2265 if self
.PlatformInfo
.ToolChainFamily
in ('MSFT'):
2266 gBuildOptIncludePattern
= re
.compile(r
"(?:.*?)/I[ \t]*([^ ]*)", re
.MULTILINE|re
.DOTALL
)
2267 elif self
.PlatformInfo
.ToolChainFamily
in ('INTEL', 'GCC', 'RVCT'):
2268 gBuildOptIncludePattern
= re
.compile(r
"(?:.*?)-I[ \t]*([^ ]*)", re
.MULTILINE|re
.DOTALL
)
2271 # New ToolChainFamily, don't known whether there is option to specify include directories
2273 self
._BuildOptionIncPathList
= []
2274 return self
._BuildOptionIncPathList
2276 BuildOptionIncPathList
= []
2277 for Tool
in ('CC', 'PP', 'VFRPP', 'ASLPP', 'ASLCC', 'APP', 'ASM'):
2280 FlagOption
= self
.BuildOption
[Tool
][Attr
]
2284 if self
.PlatformInfo
.ToolChainFamily
!= 'RVCT':
2285 IncPathList
= [NormPath(Path
, self
.Macros
) for Path
in gBuildOptIncludePattern
.findall(FlagOption
)]
2288 # RVCT may specify a list of directory seperated by commas
2291 for Path
in gBuildOptIncludePattern
.findall(FlagOption
):
2292 PathList
= GetSplitList(Path
, TAB_COMMA_SPLIT
)
2293 IncPathList
+= [NormPath(PathEntry
, self
.Macros
) for PathEntry
in PathList
]
2296 # EDK II modules must not reference header files outside of the packages they depend on or
2297 # within the module's directory tree. Report error if violation.
2299 if self
.AutoGenVersion
>= 0x00010005 and len(IncPathList
) > 0:
2300 for Path
in IncPathList
:
2301 if (Path
not in self
.IncludePathList
) and (CommonPath([Path
, self
.MetaFile
.Dir
]) != self
.MetaFile
.Dir
):
2302 ErrMsg
= "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path
, Tool
, FlagOption
)
2303 EdkLogger
.error("build",
2306 File
= str(self
.MetaFile
))
2309 BuildOptionIncPathList
+= IncPathList
2311 self
._BuildOptionIncPathList
= BuildOptionIncPathList
2313 return self
._BuildOptionIncPathList
2315 ## Return a list of files which can be built from source
2317 # What kind of files can be built is determined by build rules in
2318 # $(WORKSPACE)/Conf/build_rule.txt and toolchain family.
2320 def _GetSourceFileList(self
):
2321 if self
._SourceFileList
== None:
2322 self
._SourceFileList
= []
2323 for F
in self
.Module
.Sources
:
2325 if F
.TagName
not in ("", "*", self
.ToolChain
):
2326 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "The toolchain [%s] for processing file [%s] is found, "
2327 "but [%s] is needed" % (F
.TagName
, str(F
), self
.ToolChain
))
2329 # match tool chain family
2330 if F
.ToolChainFamily
not in ("", "*", self
.ToolChainFamily
):
2333 "The file [%s] must be built by tools of [%s], " \
2334 "but current toolchain family is [%s]" \
2335 % (str(F
), F
.ToolChainFamily
, self
.ToolChainFamily
))
2338 # add the file path into search path list for file including
2339 if F
.Dir
not in self
.IncludePathList
and self
.AutoGenVersion
>= 0x00010005:
2340 self
.IncludePathList
.insert(0, F
.Dir
)
2341 self
._SourceFileList
.append(F
)
2342 self
._ApplyBuildRule
(F
, TAB_UNKNOWN_FILE
)
2343 return self
._SourceFileList
2345 ## Return the list of unicode files
2346 def _GetUnicodeFileList(self
):
2347 if self
._UnicodeFileList
== None:
2348 if TAB_UNICODE_FILE
in self
.FileTypes
:
2349 self
._UnicodeFileList
= self
.FileTypes
[TAB_UNICODE_FILE
]
2351 self
._UnicodeFileList
= []
2352 return self
._UnicodeFileList
2354 ## Return a list of files which can be built from binary
2356 # "Build" binary files are just to copy them to build directory.
2358 # @retval list The list of files which can be built later
2360 def _GetBinaryFiles(self
):
2361 if self
._BinaryFileList
== None:
2362 self
._BinaryFileList
= []
2363 for F
in self
.Module
.Binaries
:
2364 if F
.Target
not in ['COMMON', '*'] and F
.Target
!= self
.BuildTarget
:
2366 self
._BinaryFileList
.append(F
)
2367 self
._ApplyBuildRule
(F
, F
.Type
)
2368 return self
._BinaryFileList
2370 def _GetBuildRules(self
):
2371 if self
._BuildRules
== None:
2373 BuildRuleDatabase
= self
.PlatformInfo
.BuildRule
2374 for Type
in BuildRuleDatabase
.FileTypeList
:
2375 #first try getting build rule by BuildRuleFamily
2376 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.BuildRuleFamily
]
2378 # build type is always module type, but ...
2379 if self
.ModuleType
!= self
.BuildType
:
2380 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.BuildRuleFamily
]
2381 #second try getting build rule by ToolChainFamily
2383 RuleObject
= BuildRuleDatabase
[Type
, self
.BuildType
, self
.Arch
, self
.ToolChainFamily
]
2385 # build type is always module type, but ...
2386 if self
.ModuleType
!= self
.BuildType
:
2387 RuleObject
= BuildRuleDatabase
[Type
, self
.ModuleType
, self
.Arch
, self
.ToolChainFamily
]
2390 RuleObject
= RuleObject
.Instantiate(self
.Macros
)
2391 BuildRules
[Type
] = RuleObject
2392 for Ext
in RuleObject
.SourceFileExtList
:
2393 BuildRules
[Ext
] = RuleObject
2394 self
._BuildRules
= BuildRules
2395 return self
._BuildRules
2397 def _ApplyBuildRule(self
, File
, FileType
):
2398 if self
._BuildTargets
== None:
2399 self
._IntroBuildTargetList
= set()
2400 self
._FinalBuildTargetList
= set()
2401 self
._BuildTargets
= {}
2402 self
._FileTypes
= {}
2408 while Index
< len(SourceList
):
2409 Source
= SourceList
[Index
]
2413 CreateDirectory(Source
.Dir
)
2415 if File
.IsBinary
and File
== Source
and self
._BinaryFileList
!= None and File
in self
._BinaryFileList
:
2416 # Skip all files that are not binary libraries
2417 if not self
.IsLibrary
:
2419 RuleObject
= self
.BuildRules
[TAB_DEFAULT_BINARY_FILE
]
2420 elif FileType
in self
.BuildRules
:
2421 RuleObject
= self
.BuildRules
[FileType
]
2422 elif Source
.Ext
in self
.BuildRules
:
2423 RuleObject
= self
.BuildRules
[Source
.Ext
]
2425 # stop at no more rules
2427 self
._FinalBuildTargetList
.add(LastTarget
)
2430 FileType
= RuleObject
.SourceFileType
2431 if FileType
not in self
._FileTypes
:
2432 self
._FileTypes
[FileType
] = set()
2433 self
._FileTypes
[FileType
].add(Source
)
2435 # stop at STATIC_LIBRARY for library
2436 if self
.IsLibrary
and FileType
== TAB_STATIC_LIBRARY
:
2438 self
._FinalBuildTargetList
.add(LastTarget
)
2441 Target
= RuleObject
.Apply(Source
)
2444 self
._FinalBuildTargetList
.add(LastTarget
)
2446 elif not Target
.Outputs
:
2447 # Only do build for target with outputs
2448 self
._FinalBuildTargetList
.add(Target
)
2450 if FileType
not in self
._BuildTargets
:
2451 self
._BuildTargets
[FileType
] = set()
2452 self
._BuildTargets
[FileType
].add(Target
)
2454 if not Source
.IsBinary
and Source
== File
:
2455 self
._IntroBuildTargetList
.add(Target
)
2457 # to avoid cyclic rule
2458 if FileType
in RuleChain
:
2461 RuleChain
.append(FileType
)
2462 SourceList
.extend(Target
.Outputs
)
2464 FileType
= TAB_UNKNOWN_FILE
2466 def _GetTargets(self
):
2467 if self
._BuildTargets
== None:
2468 self
._IntroBuildTargetList
= set()
2469 self
._FinalBuildTargetList
= set()
2470 self
._BuildTargets
= {}
2471 self
._FileTypes
= {}
2473 #TRICK: call _GetSourceFileList to apply build rule for source files
2474 if self
.SourceFileList
:
2477 #TRICK: call _GetBinaryFileList to apply build rule for binary files
2478 if self
.BinaryFileList
:
2481 return self
._BuildTargets
2483 def _GetIntroTargetList(self
):
2485 return self
._IntroBuildTargetList
2487 def _GetFinalTargetList(self
):
2489 return self
._FinalBuildTargetList
2491 def _GetFileTypes(self
):
2493 return self
._FileTypes
2495 ## Get the list of package object the module depends on
2497 # @retval list The package object list
2499 def _GetDependentPackageList(self
):
2500 return self
.Module
.Packages
2502 ## Return the list of auto-generated code file
2504 # @retval list The list of auto-generated file
2506 def _GetAutoGenFileList(self
):
2507 UniStringAutoGenC
= True
2508 UniStringBinBuffer
= StringIO()
2509 if self
.BuildType
== 'UEFI_HII':
2510 UniStringAutoGenC
= False
2511 if self
._AutoGenFileList
== None:
2512 self
._AutoGenFileList
= {}
2513 AutoGenC
= TemplateString()
2514 AutoGenH
= TemplateString()
2515 StringH
= TemplateString()
2516 GenC
.CreateCode(self
, AutoGenC
, AutoGenH
, StringH
, UniStringAutoGenC
, UniStringBinBuffer
)
2517 if str(AutoGenC
) != "" and TAB_C_CODE_FILE
in self
.FileTypes
:
2518 AutoFile
= PathClass(gAutoGenCodeFileName
, self
.DebugDir
)
2519 self
._AutoGenFileList
[AutoFile
] = str(AutoGenC
)
2520 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2521 if str(AutoGenH
) != "":
2522 AutoFile
= PathClass(gAutoGenHeaderFileName
, self
.DebugDir
)
2523 self
._AutoGenFileList
[AutoFile
] = str(AutoGenH
)
2524 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2525 if str(StringH
) != "":
2526 AutoFile
= PathClass(gAutoGenStringFileName
% {"module_name":self
.Name
}, self
.DebugDir
)
2527 self
._AutoGenFileList
[AutoFile
] = str(StringH
)
2528 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2529 if UniStringBinBuffer
!= None and UniStringBinBuffer
.getvalue() != "":
2530 AutoFile
= PathClass(gAutoGenStringFormFileName
% {"module_name":self
.Name
}, self
.OutputDir
)
2531 self
._AutoGenFileList
[AutoFile
] = UniStringBinBuffer
.getvalue()
2532 AutoFile
.IsBinary
= True
2533 self
._ApplyBuildRule
(AutoFile
, TAB_UNKNOWN_FILE
)
2534 if UniStringBinBuffer
!= None:
2535 UniStringBinBuffer
.close()
2536 return self
._AutoGenFileList
2538 ## Return the list of library modules explicitly or implicityly used by this module
2539 def _GetLibraryList(self
):
2540 if self
._DependentLibraryList
== None:
2541 # only merge library classes and PCD for non-library module
2543 self
._DependentLibraryList
= []
2545 if self
.AutoGenVersion
< 0x00010005:
2546 self
._DependentLibraryList
= self
.PlatformInfo
.ResolveLibraryReference(self
.Module
)
2548 self
._DependentLibraryList
= self
.PlatformInfo
.ApplyLibraryInstance(self
.Module
)
2549 return self
._DependentLibraryList
2551 ## Get the list of PCDs from current module
2553 # @retval list The list of PCD
2555 def _GetModulePcdList(self
):
2556 if self
._ModulePcdList
== None:
2557 # apply PCD settings from platform
2558 self
._ModulePcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, self
.Module
.Pcds
)
2559 return self
._ModulePcdList
2561 ## Get the list of PCDs from dependent libraries
2563 # @retval list The list of PCD
2565 def _GetLibraryPcdList(self
):
2566 if self
._LibraryPcdList
== None:
2568 if not self
.IsLibrary
:
2569 # get PCDs from dependent libraries
2570 for Library
in self
.DependentLibraryList
:
2571 for Key
in Library
.Pcds
:
2572 # skip duplicated PCDs
2573 if Key
in self
.Module
.Pcds
or Key
in Pcds
:
2575 Pcds
[Key
] = copy
.copy(Library
.Pcds
[Key
])
2576 # apply PCD settings from platform
2577 self
._LibraryPcdList
= self
.PlatformInfo
.ApplyPcdSetting(self
.Module
, Pcds
)
2579 self
._LibraryPcdList
= []
2580 return self
._LibraryPcdList
2582 ## Get the GUID value mapping
2584 # @retval dict The mapping between GUID cname and its value
2586 def _GetGuidList(self
):
2587 if self
._GuidList
== None:
2588 self
._GuidList
= self
.Module
.Guids
2589 for Library
in self
.DependentLibraryList
:
2590 self
._GuidList
.update(Library
.Guids
)
2591 return self
._GuidList
2593 ## Get the protocol value mapping
2595 # @retval dict The mapping between protocol cname and its value
2597 def _GetProtocolList(self
):
2598 if self
._ProtocolList
== None:
2599 self
._ProtocolList
= self
.Module
.Protocols
2600 for Library
in self
.DependentLibraryList
:
2601 self
._ProtocolList
.update(Library
.Protocols
)
2602 return self
._ProtocolList
2604 ## Get the PPI value mapping
2606 # @retval dict The mapping between PPI cname and its value
2608 def _GetPpiList(self
):
2609 if self
._PpiList
== None:
2610 self
._PpiList
= self
.Module
.Ppis
2611 for Library
in self
.DependentLibraryList
:
2612 self
._PpiList
.update(Library
.Ppis
)
2613 return self
._PpiList
2615 ## Get the list of include search path
2617 # @retval list The list path
2619 def _GetIncludePathList(self
):
2620 if self
._IncludePathList
== None:
2621 self
._IncludePathList
= []
2622 if self
.AutoGenVersion
< 0x00010005:
2623 for Inc
in self
.Module
.Includes
:
2624 if Inc
not in self
._IncludePathList
:
2625 self
._IncludePathList
.append(Inc
)
2627 Inc
= path
.join(Inc
, self
.Arch
.capitalize())
2628 if os
.path
.exists(Inc
) and Inc
not in self
._IncludePathList
:
2629 self
._IncludePathList
.append(Inc
)
2630 # Edk module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
2631 self
._IncludePathList
.append(self
.DebugDir
)
2633 self
._IncludePathList
.append(self
.MetaFile
.Dir
)
2634 self
._IncludePathList
.append(self
.DebugDir
)
2636 for Package
in self
.Module
.Packages
:
2637 PackageDir
= path
.join(self
.WorkspaceDir
, Package
.MetaFile
.Dir
)
2638 if PackageDir
not in self
._IncludePathList
:
2639 self
._IncludePathList
.append(PackageDir
)
2640 for Inc
in Package
.Includes
:
2641 if Inc
not in self
._IncludePathList
:
2642 self
._IncludePathList
.append(str(Inc
))
2643 return self
._IncludePathList
2645 ## Create AsBuilt INF file the module
2647 def CreateAsBuiltInf(self
):
2648 if self
.IsAsBuiltInfCreated
:
2651 # Skip the following code for EDK I inf
2652 if self
.AutoGenVersion
< 0x00010005:
2655 # Skip the following code for libraries
2659 # Skip the following code for modules with no source files
2660 if self
.SourceFileList
== None or self
.SourceFileList
== []:
2663 # Skip the following code for modules without any binary files
2664 if self
.BinaryFileList
<> None and self
.BinaryFileList
<> []:
2667 ### TODO: How to handles mixed source and binary modules
2669 # Find all DynamicEx PCDs used by this module and dependent libraries
2670 # Also find all packages that the DynamicEx PCDs depend on
2673 for Pcd
in self
.ModulePcdList
+ self
.LibraryPcdList
:
2674 if Pcd
.Type
in GenC
.gDynamicExPcd
:
2677 for Package
in self
.DerivedPackageList
:
2678 if Package
not in Packages
:
2679 if (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, 'DynamicEx') in Package
.Pcds
:
2680 Packages
+= [Package
]
2681 elif (Pcd
.TokenCName
, Pcd
.TokenSpaceGuidCName
, 'Dynamic') in Package
.Pcds
:
2682 Packages
+= [Package
]
2684 ModuleType
= self
.ModuleType
2685 if ModuleType
== 'UEFI_DRIVER' and self
.DepexGenerated
:
2686 ModuleType
= 'DXE_DRIVER'
2689 'module_name' : self
.Name
,
2690 'module_guid' : self
.Guid
,
2691 'module_module_type' : ModuleType
,
2692 'module_version_string' : self
.Version
,
2693 'module_uefi_specification_version' : [],
2694 'module_pi_specification_version' : [],
2695 'module_arch' : self
.Arch
,
2696 'package_item' : ['%s' % (Package
.MetaFile
.File
.replace('\\','/')) for Package
in Packages
],
2702 if 'UEFI_SPECIFICATION_VERSION' in self
.Specification
:
2703 AsBuiltInfDict
['module_uefi_specification_version'] += [self
.Specification
['UEFI_SPECIFICATION_VERSION']]
2704 if 'PI_SPECIFICATION_VERSION' in self
.Specification
:
2705 AsBuiltInfDict
['module_pi_specification_version'] += [self
.Specification
['PI_SPECIFICATION_VERSION']]
2707 OutputDir
= self
.OutputDir
.replace('\\','/').strip('/')
2708 if self
.ModuleType
in ['BASE', 'USER_DEFINED']:
2709 for Item
in self
.CodaTargetList
:
2710 File
= Item
.Target
.Path
.replace('\\','/').strip('/').replace(OutputDir
,'').strip('/')
2711 if Item
.Target
.Ext
.lower() == '.aml':
2712 AsBuiltInfDict
['binary_item'] += ['ASL|' + File
]
2713 elif Item
.Target
.Ext
.lower() == '.acpi':
2714 AsBuiltInfDict
['binary_item'] += ['ACPI|' + File
]
2716 AsBuiltInfDict
['binary_item'] += ['BIN|' + File
]
2718 for Item
in self
.CodaTargetList
:
2719 File
= Item
.Target
.Path
.replace('\\','/').strip('/').replace(OutputDir
,'').strip('/')
2720 if Item
.Target
.Ext
.lower() == '.efi':
2721 AsBuiltInfDict
['binary_item'] += ['PE32|' + self
.Name
+ '.efi']
2723 AsBuiltInfDict
['binary_item'] += ['BIN|' + File
]
2724 if self
.DepexGenerated
:
2725 if self
.ModuleType
in ['PEIM']:
2726 AsBuiltInfDict
['binary_item'] += ['PEI_DEPEX|' + self
.Name
+ '.depex']
2727 if self
.ModuleType
in ['DXE_DRIVER','DXE_RUNTIME_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER']:
2728 AsBuiltInfDict
['binary_item'] += ['DXE_DEPEX|' + self
.Name
+ '.depex']
2729 if self
.ModuleType
in ['DXE_SMM_DRIVER']:
2730 AsBuiltInfDict
['binary_item'] += ['SMM_DEPEX|' + self
.Name
+ '.depex']
2733 AsBuiltInfDict
['pcd_item'] += [Pcd
.TokenSpaceGuidCName
+ '.' + Pcd
.TokenCName
]
2735 for Item
in self
.BuildOption
:
2736 if 'FLAGS' in self
.BuildOption
[Item
]:
2737 AsBuiltInfDict
['flags_item'] += ['%s:%s_%s_%s_%s_FLAGS = %s' % (self
.ToolChainFamily
, self
.BuildTarget
, self
.ToolChain
, self
.Arch
, Item
, self
.BuildOption
[Item
]['FLAGS'].strip())]
2739 AsBuiltInf
= TemplateString()
2740 AsBuiltInf
.Append(gAsBuiltInfHeaderString
.Replace(AsBuiltInfDict
))
2742 SaveFileOnChange(os
.path
.join(self
.OutputDir
, self
.Name
+ '.inf'), str(AsBuiltInf
), False)
2744 self
.IsAsBuiltInfCreated
= True
2746 ## Create makefile for the module and its dependent libraries
2748 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of
2749 # dependent libraries will be created
2751 def CreateMakeFile(self
, CreateLibraryMakeFile
=True):
2752 if self
.IsMakeFileCreated
:
2755 if not self
.IsLibrary
and CreateLibraryMakeFile
:
2756 for LibraryAutoGen
in self
.LibraryAutoGenList
:
2757 LibraryAutoGen
.CreateMakeFile()
2759 if len(self
.CustomMakefile
) == 0:
2760 Makefile
= GenMake
.ModuleMakefile(self
)
2762 Makefile
= GenMake
.CustomMakefile(self
)
2763 if Makefile
.Generate():
2764 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated makefile for module %s [%s]" %
2765 (self
.Name
, self
.Arch
))
2767 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of makefile for module %s [%s]" %
2768 (self
.Name
, self
.Arch
))
2770 self
.IsMakeFileCreated
= True
2772 ## Create autogen code for the module and its dependent libraries
2774 # @param CreateLibraryCodeFile Flag indicating if or not the code of
2775 # dependent libraries will be created
2777 def CreateCodeFile(self
, CreateLibraryCodeFile
=True):
2778 if self
.IsCodeFileCreated
:
2781 if not self
.IsLibrary
and CreateLibraryCodeFile
:
2782 for LibraryAutoGen
in self
.LibraryAutoGenList
:
2783 LibraryAutoGen
.CreateCodeFile()
2786 IgoredAutoGenList
= []
2788 for File
in self
.AutoGenFileList
:
2789 if GenC
.Generate(File
.Path
, self
.AutoGenFileList
[File
], File
.IsBinary
):
2790 #Ignore Edk AutoGen.c
2791 if self
.AutoGenVersion
< 0x00010005 and File
.Name
== 'AutoGen.c':
2794 AutoGenList
.append(str(File
))
2796 IgoredAutoGenList
.append(str(File
))
2798 # Skip the following code for EDK I inf
2799 if self
.AutoGenVersion
< 0x00010005:
2802 for ModuleType
in self
.DepexList
:
2803 # Ignore empty [depex] section or [depex] section for "USER_DEFINED" module
2804 if len(self
.DepexList
[ModuleType
]) == 0 or ModuleType
== "USER_DEFINED":
2807 Dpx
= GenDepex
.DependencyExpression(self
.DepexList
[ModuleType
], ModuleType
, True)
2808 DpxFile
= gAutoGenDepexFileName
% {"module_name" : self
.Name
}
2810 if len(Dpx
.PostfixNotation
) <> 0:
2811 self
.DepexGenerated
= True
2813 if Dpx
.Generate(path
.join(self
.OutputDir
, DpxFile
)):
2814 AutoGenList
.append(str(DpxFile
))
2816 IgoredAutoGenList
.append(str(DpxFile
))
2818 if IgoredAutoGenList
== []:
2819 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] files for module %s [%s]" %
2820 (" ".join(AutoGenList
), self
.Name
, self
.Arch
))
2821 elif AutoGenList
== []:
2822 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Skipped the generation of [%s] files for module %s [%s]" %
2823 (" ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
2825 EdkLogger
.debug(EdkLogger
.DEBUG_9
, "Generated [%s] (skipped %s) files for module %s [%s]" %
2826 (" ".join(AutoGenList
), " ".join(IgoredAutoGenList
), self
.Name
, self
.Arch
))
2828 self
.IsCodeFileCreated
= True
2831 ## Summarize the ModuleAutoGen objects of all libraries used by this module
2832 def _GetLibraryAutoGenList(self
):
2833 if self
._LibraryAutoGenList
== None:
2834 self
._LibraryAutoGenList
= []
2835 for Library
in self
.DependentLibraryList
:
2842 self
.PlatformInfo
.MetaFile
2844 if La
not in self
._LibraryAutoGenList
:
2845 self
._LibraryAutoGenList
.append(La
)
2846 for Lib
in La
.CodaTargetList
:
2847 self
._ApplyBuildRule
(Lib
.Target
, TAB_UNKNOWN_FILE
)
2848 return self
._LibraryAutoGenList
2850 Module
= property(_GetModule
)
2851 Name
= property(_GetBaseName
)
2852 Guid
= property(_GetGuid
)
2853 Version
= property(_GetVersion
)
2854 ModuleType
= property(_GetModuleType
)
2855 ComponentType
= property(_GetComponentType
)
2856 BuildType
= property(_GetBuildType
)
2857 PcdIsDriver
= property(_GetPcdIsDriver
)
2858 AutoGenVersion
= property(_GetAutoGenVersion
)
2859 Macros
= property(_GetMacros
)
2860 Specification
= property(_GetSpecification
)
2862 IsLibrary
= property(_IsLibrary
)
2864 BuildDir
= property(_GetBuildDir
)
2865 OutputDir
= property(_GetOutputDir
)
2866 DebugDir
= property(_GetDebugDir
)
2867 MakeFileDir
= property(_GetMakeFileDir
)
2868 CustomMakefile
= property(_GetCustomMakefile
)
2870 IncludePathList
= property(_GetIncludePathList
)
2871 AutoGenFileList
= property(_GetAutoGenFileList
)
2872 UnicodeFileList
= property(_GetUnicodeFileList
)
2873 SourceFileList
= property(_GetSourceFileList
)
2874 BinaryFileList
= property(_GetBinaryFiles
) # FileType : [File List]
2875 Targets
= property(_GetTargets
)
2876 IntroTargetList
= property(_GetIntroTargetList
)
2877 CodaTargetList
= property(_GetFinalTargetList
)
2878 FileTypes
= property(_GetFileTypes
)
2879 BuildRules
= property(_GetBuildRules
)
2881 DependentPackageList
= property(_GetDependentPackageList
)
2882 DependentLibraryList
= property(_GetLibraryList
)
2883 LibraryAutoGenList
= property(_GetLibraryAutoGenList
)
2884 DerivedPackageList
= property(_GetDerivedPackageList
)
2886 ModulePcdList
= property(_GetModulePcdList
)
2887 LibraryPcdList
= property(_GetLibraryPcdList
)
2888 GuidList
= property(_GetGuidList
)
2889 ProtocolList
= property(_GetProtocolList
)
2890 PpiList
= property(_GetPpiList
)
2891 DepexList
= property(_GetDepexTokenList
)
2892 DxsFile
= property(_GetDxsFile
)
2893 DepexExpressionList
= property(_GetDepexExpressionTokenList
)
2894 BuildOption
= property(_GetModuleBuildOption
)
2895 BuildOptionIncPathList
= property(_GetBuildOptionIncPathList
)
2896 BuildCommand
= property(_GetBuildCommand
)
2898 # This acts like the main() function for the script, unless it is 'import'ed into another script.
2899 if __name__
== '__main__':